diff --git a/samples/zig-sample/data/orca_jumping.jpg b/samples/zig-sample/data/orca_jumping.jpg new file mode 100644 index 0000000..50e1c35 Binary files /dev/null and b/samples/zig-sample/data/orca_jumping.jpg differ diff --git a/samples/zig-sample/src/main.zig b/samples/zig-sample/src/main.zig index 5c0162e..5a9540e 100644 --- a/samples/zig-sample/src/main.zig +++ b/samples/zig-sample/src/main.zig @@ -2,49 +2,71 @@ const std = @import("std"); const oc = @import("orca"); const Vec2 = oc.Vec2; +const Mat2x3 = oc.Mat2x3; var surface: oc.Surface = undefined; var canvas: oc.Canvas = undefined; +var font: oc.Font = undefined; +var orca_image: oc.Image = undefined; var counter: u32 = 0; -var lastSeconds: f64 = 0; +var last_seconds: f64 = 0; +var frame_size: Vec2 = .{ .x = 0, .y = 0 }; + +var rotation_demo: f32 = 0; export fn oc_on_init() void { - oc.windowSetTitle("zig calc"); + oc.windowSetTitle("zig sample"); oc.windowSetSize(Vec2{ .x = 480, .y = 640 }); - oc.logInfo("current platform: {}", .{oc.getHostPlatform()}, @src()); + oc.log.info("current platform: {}", .{oc.getHostPlatform()}, @src()); surface = oc.Surface.canvas(); canvas = oc.Canvas.create(); oc.assert(oc.Canvas.nil().isNil() == true, "nil canvas should be nil", .{}, @src()); oc.assert(canvas.isNil() == false, "created canvas should not be nil", .{}, @src()); + + var ranges = oc.UnicodeRange.range(&[_]oc.UnicodeRange.Enum{ + .BasicLatin, + .C1ControlsAndLatin1Supplement, + .LatinExtendedA, + .LatinExtendedB, + .Specials, + }); + font = oc.Font.createFromPath("/zig.ttf", &ranges); + oc.assert(font.isNil() == false, "created font should not be nil", .{}, @src()); + + orca_image = oc.Image.createFromPath(surface, oc.Str8.fromSlice("/orca_jumping.jpg"), false); + oc.assert(orca_image.isNil() == false, "created image should not be nil", .{}, @src()); } export fn oc_on_resize(width: u32, height: u32) void { - oc.logInfo("frame resize: {}, {}", .{ width, height }, @src()); + frame_size = Vec2{ .x = @floatFromInt(width), .y = @floatFromInt(height) }; + oc.log.info("frame resize: {d:.2}, {d:.2}", .{ frame_size.x, frame_size.y }, @src()); } export fn oc_on_mouse_down(button: oc.MouseButton) void { - oc.logInfo("mouse down! {}", .{button}, @src()); + oc.log.info("mouse down! {}", .{button}, @src()); } export fn oc_on_mouse_up(button: oc.MouseButton) void { - oc.logInfo("mouse up! {}", .{button}, @src()); + oc.log.info("mouse up! {}", .{button}, @src()); } -export fn oc_on_key_down(key: oc.KeyCode) void { - oc.logInfo("key down: {}", .{key}, @src()); +export fn oc_on_key_down(scan: oc.ScanCode, key: oc.KeyCode) void { + oc.log.info("key down: {} {}", .{ scan, key }, @src()); } -export fn oc_on_key_up(key: oc.KeyCode) void { - oc.logInfo("key up: {}", .{key}, @src()); +export fn oc_on_key_up(scan: oc.ScanCode, key: oc.KeyCode) void { + oc.log.info("key up: {} {}", .{ scan, key }, @src()); switch (key) { oc.KeyCode.Escape => oc.requestQuit(), oc.KeyCode.B => oc.abort("aborting", .{}, @src()), oc.KeyCode.A => oc.assert(false, "test assert failed", .{}, @src()), + oc.KeyCode.W => oc.log.warn("logging a test warning", .{}, @src()), + oc.KeyCode.E => oc.log.err("logging a test error", .{}, @src()), else => {}, } } @@ -54,29 +76,28 @@ export fn oc_on_frame_refresh() void { const secs: f64 = oc.clockTime(oc.ClockKind.Date); - if (lastSeconds != @floor(secs)) { - lastSeconds = @floor(secs); - oc.logInfo("seconds since Jan 1, 1970: {d:.0}", .{secs}, @src()); + if (last_seconds != @floor(secs)) { + last_seconds = @floor(secs); + oc.log.info("seconds since Jan 1, 1970: {d:.0}", .{secs}, @src()); } - _ = canvas.setCurrent(); - surface.select(); + _ = canvas.select(); oc.setColorRgba(0.05, 0.05, 0.05, 1.0); oc.clear(); oc.setColorRgba(1.0, 0.05, 0.05, 1.0); { - const translation: oc.Mat2x3 = .{ .m = [_]f32{ 1, 0, 50, 0, 1, 50 } }; - translation.push(); - defer oc.Mat2x3.pop(); + const translation: Mat2x3 = .{ .m = [_]f32{ 1, 0, 50, 0, 1, 50 } }; + Mat2x3.push(translation); + defer Mat2x3.pop(); - oc.assert(std.meta.eql(oc.matrixTop(), translation), "top of matrix stack should be what we pushed", .{}, @src()); + oc.assert(std.meta.eql(Mat2x3.top(), translation), "top of matrix stack should be what we pushed", .{}, @src()); oc.setWidth(1); - oc.rectangleFill(50, 50, 10, 10); - oc.rectangleStroke(70, 50, 10, 10); - oc.roundedRectangleFill(90, 50, 10, 10, 3); - oc.roundedRectangleStroke(110, 50, 10, 10, 3); + oc.rectangleFill(50, 0, 10, 10); + oc.rectangleStroke(70, 0, 10, 10); + oc.roundedRectangleFill(90, 0, 10, 10, 3); + oc.roundedRectangleStroke(110, 0, 10, 10, 3); const green = oc.Color{ .Flat = .{ .r = 0.05, .g = 1, .b = 0.05, .a = 1 } }; oc.setColor(green); @@ -84,18 +105,69 @@ export fn oc_on_frame_refresh() void { oc.setTolerance(1); oc.setJoint(.Bevel); - oc.ellipseFill(140, 55, 10, 5); - oc.ellipseStroke(170, 55, 10, 5); - oc.circleFill(195, 55, 5); - oc.circleStroke(215, 55, 5); + oc.ellipseFill(140, 5, 10, 5); + oc.ellipseStroke(170, 5, 10, 5); + oc.circleFill(195, 5, 5); + oc.circleStroke(215, 5, 5); - oc.arc(230, 55, 5, 0, std.math.pi); + oc.arc(230, 5, 5, 0, std.math.pi); } - surface.render(canvas); + { + rotation_demo += 0.03; + + const rot = Mat2x3.rotate(rotation_demo); + const trans = Mat2x3.translate(285, 55); + Mat2x3.push(Mat2x3.mul_m(trans, rot)); + defer Mat2x3.pop(); + + oc.rectangleFill(-5, -5, 10, 10); + } + + { + const str = oc.Str8.fromSlice("Hello from Zig!"); + const font_size = 18; + const text_rect = font.textMetrics(font_size, str).ink; + + const center_x = frame_size.x / 2; + const text_begin_x = center_x - text_rect.Flat.w / 2; + + oc.log.info("text rect width: {d}", .{text_rect.Flat.w}, @src()); + oc.log.info("center_x: {d}", .{center_x}, @src()); + oc.log.info("text_begin_x: {d}", .{text_begin_x}, @src()); + + Mat2x3.push(Mat2x3.translate(text_begin_x, 150)); + defer Mat2x3.pop(); + + oc.setColorRgba(1.0, 0.05, 0.05, 1.0); + + oc.setFont(font); + oc.setFontSize(font_size); + oc.moveTo(0, 0); + oc.textOutlines(str); + oc.fill(); + } + + { + const trans = Mat2x3.translate(0, 200); + const scale = Mat2x3.scaleUniform(0.25); + Mat2x3.push(Mat2x3.mul_m(trans, scale)); + defer Mat2x3.pop(); + + const size = orca_image.size(); + + orca_image.draw(oc.Rect.xywh(0, 0, size.x, size.y)); + + var half_size = orca_image.size(); + half_size.x /= 2; + orca_image.drawRegion(oc.Rect.xywh(0, 0, half_size.x, half_size.y), oc.Rect.xywh(size.x + 10, 0, half_size.x, half_size.y)); + } + + surface.select(); + canvas.render(); surface.present(); } export fn oc_on_terminate() void { - oc.logInfo("byebye {}", .{counter}, @src()); + oc.log.info("byebye {}", .{counter}, @src()); } diff --git a/src/app/app.c b/src/app/app.c index a704722..030f02d 100644 --- a/src/app/app.c +++ b/src/app/app.c @@ -188,7 +188,7 @@ oc_key_code oc_scancode_to_keycode(oc_scan_code scanCode) return (oc_appData.keyMap[scanCode]); } -#define OC_DEFAULT_KEYMAP_ENTRY(sc, sv, ...) [(int) sc] = (oc_key_code)sc, +#define OC_DEFAULT_KEYMAP_ENTRY(sc, sv, kc, ...) [(int) sc] = OC_VA_NOPT(sv, ##__VA_ARGS__) __VA_ARGS__, oc_key_code oc_defaultKeyMap[OC_SCANCODE_COUNT] = { OC_KEY_TABLE(OC_DEFAULT_KEYMAP_ENTRY) diff --git a/src/graphics/graphics.h b/src/graphics/graphics.h index 0b0e970..00cd6ab 100644 --- a/src/graphics/graphics.h +++ b/src/graphics/graphics.h @@ -227,9 +227,9 @@ ORCA_API void oc_render(oc_canvas canvas); //DOC: renders all canvas ORCA_API oc_font oc_font_nil(void); ORCA_API bool oc_font_is_nil(oc_font font); -ORCA_API oc_font oc_font_create_from_memory(oc_str8 mem, u32 rangeCount, oc_unicode_range* ranges); -ORCA_API oc_font oc_font_create_from_file(oc_file file, u32 rangeCount, oc_unicode_range* ranges); -ORCA_API oc_font oc_font_create_from_path(oc_str8 path, u32 rangeCount, oc_unicode_range* ranges); +ORCA_API oc_font oc_font_create_from_memory(oc_str8 mem, u32 rangeCount, const oc_unicode_range* ranges); +ORCA_API oc_font oc_font_create_from_file(oc_file file, u32 rangeCount, const oc_unicode_range* ranges); +ORCA_API oc_font oc_font_create_from_path(oc_str8 path, u32 rangeCount, const oc_unicode_range* ranges); ORCA_API void oc_font_destroy(oc_font font); diff --git a/src/graphics/graphics_common.c b/src/graphics/graphics_common.c index 2ce3900..9658ddd 100644 --- a/src/graphics/graphics_common.c +++ b/src/graphics/graphics_common.c @@ -369,7 +369,7 @@ oc_font_data* oc_font_data_from_handle(oc_font handle) return (data); } -oc_font oc_font_create_from_memory(oc_str8 mem, u32 rangeCount, oc_unicode_range* ranges) +oc_font oc_font_create_from_memory(oc_str8 mem, u32 rangeCount, const oc_unicode_range* ranges) { if(!oc_graphicsData.init) { @@ -552,7 +552,7 @@ oc_font oc_font_create_from_memory(oc_str8 mem, u32 rangeCount, oc_unicode_range return (fontHandle); } -oc_font oc_font_create_from_file(oc_file file, u32 rangeCount, oc_unicode_range* ranges) +oc_font oc_font_create_from_file(oc_file file, u32 rangeCount, const oc_unicode_range* ranges) { oc_font font = oc_font_nil(); oc_arena_scope scratch = oc_scratch_begin(); @@ -574,7 +574,7 @@ oc_font oc_font_create_from_file(oc_file file, u32 rangeCount, oc_unicode_range* return (font); } -oc_font oc_font_create_from_path(oc_str8 path, u32 rangeCount, oc_unicode_range* ranges) +oc_font oc_font_create_from_path(oc_str8 path, u32 rangeCount, const oc_unicode_range* ranges) { oc_font font = oc_font_nil(); diff --git a/src/orca.zig b/src/orca.zig index 05f01a6..dbad795 100644 --- a/src/orca.zig +++ b/src/orca.zig @@ -1,16 +1,4 @@ const std = @import("std"); -const orca_c = @cImport({ - @cDefine("__ORCA__", ""); - @cInclude("orca.h"); -}); - -pub const Str8 = orca_c.oc_str8; -pub const Str32 = orca_c.oc_str32; -pub const Utf32 = orca_c.oc_utf32; -pub const Vec2 = extern struct { - x: f32, - y: f32, -}; //------------------------------------------------------------------------------------------ // [PLATFORM] @@ -25,28 +13,52 @@ extern fn oc_get_host_platform() Platform; pub const getHostPlatform = oc_get_host_platform; //------------------------------------------------------------------------------------------ -// [DEBUG] +// [DEBUG] Logging //------------------------------------------------------------------------------------------ -pub fn logInfo(comptime fmt: []const u8, args: anytype, source: std.builtin.SourceLocation) void { - logExt(orca_c.OC_LOG_LEVEL_INFO, fmt, args, source); -} +pub const log = struct { + pub const Level = enum(c_uint) { + Error, + Warning, + Info, + }; -pub fn logWarning(comptime fmt: []const u8, args: anytype, source: std.builtin.SourceLocation) void { - logExt(orca_c.OC_LOG_LEVEL_WARNING, fmt, args, source); -} + pub const Output = opaque {}; -pub fn logError(comptime fmt: []const u8, args: anytype, source: std.builtin.SourceLocation) void { - logExt(orca_c.OC_LOG_LEVEL_ERROR, fmt, args, source); -} + extern var OC_LOG_DEFAULT_OUTPUT: ?*Output; + extern fn oc_log_set_level(level: Level) void; + extern fn oc_log_set_output(output: *Output) void; + extern fn oc_log_ext(level: Level, function: [*]const u8, file: [*]const u8, line: c_int, fmt: [*]const u8, ...) void; -pub fn logExt(comptime level: orca_c.oc_log_level, comptime fmt: []const u8, args: anytype, source: std.builtin.SourceLocation) void { - var format_buf: [512:0]u8 = undefined; - _ = std.fmt.bufPrintZ(&format_buf, fmt, args) catch 0; // just discard NoSpaceLeft error for now - var line: c_int = @intCast(source.line); + const DEFAULT_OUTPUT = OC_LOG_DEFAULT_OUTPUT; - orca_c.oc_log_ext(level, source.fn_name.ptr, source.file.ptr, line, format_buf[0..].ptr); -} + pub fn info(comptime fmt: []const u8, args: anytype, source: std.builtin.SourceLocation) void { + ext(Level.Info, fmt, args, source); + } + + pub fn warn(comptime fmt: []const u8, args: anytype, source: std.builtin.SourceLocation) void { + ext(Level.Warning, fmt, args, source); + } + + pub fn err(comptime fmt: []const u8, args: anytype, source: std.builtin.SourceLocation) void { + ext(Level.Error, fmt, args, source); + } + + pub fn ext(comptime level: Level, comptime fmt: []const u8, args: anytype, source: std.builtin.SourceLocation) void { + var format_buf: [512:0]u8 = undefined; + _ = std.fmt.bufPrintZ(&format_buf, fmt, args) catch 0; // just discard NoSpaceLeft error for now + var line: c_int = @intCast(source.line); + + oc_log_ext(level, source.fn_name.ptr, source.file.ptr, line, format_buf[0..].ptr); + } +}; + +//------------------------------------------------------------------------------------------ +// [DEBUG] Assert/Abort +//------------------------------------------------------------------------------------------ + +extern fn oc_abort_ext(file: [*]const u8, function: [*]const u8, line: c_int, fmt: [*]const u8, ...) void; +extern fn oc_assert_fail(file: [*]const u8, function: [*]const u8, line: c_int, src: [*]const u8, fmt: [*]const u8, ...) void; pub fn assert(condition: bool, comptime fmt: []const u8, args: anytype, source: std.builtin.SourceLocation) void { if (condition == false) { @@ -54,7 +66,7 @@ pub fn assert(condition: bool, comptime fmt: []const u8, args: anytype, source: _ = std.fmt.bufPrintZ(&format_buf, fmt, args) catch 0; var line: c_int = @intCast(source.line); - orca_c.oc_assert_fail(source.file.ptr, source.fn_name.ptr, line, "", format_buf[0..].ptr); + oc_assert_fail(source.file.ptr, source.fn_name.ptr, line, "", format_buf[0..].ptr); } } @@ -63,7 +75,7 @@ pub fn abort(comptime fmt: []const u8, args: anytype, source: std.builtin.Source _ = std.fmt.bufPrintZ(&format_buf, fmt, args) catch 0; var line: c_int = @intCast(source.line); - orca_c.oc_abort_ext(source.file.ptr, source.fn_name.ptr, line, format_buf[0..].ptr); + oc_abort_ext(source.file.ptr, source.fn_name.ptr, line, format_buf[0..].ptr); } //------------------------------------------------------------------------------------------ @@ -181,30 +193,279 @@ pub const ArenaOptions = extern struct { }; //------------------------------------------------------------------------------------------ -// [STRINGS] +// [STRINGS] u8 strings //------------------------------------------------------------------------------------------ +fn stringType(comptime CharType: type) type { + return extern struct { + const Self = @This(); + + ptr: ?[*]CharType, + len: usize, + + extern fn strncmp(a: ?[*]u8, b: ?[*]u8, len: usize) c_int; + + // extern fn oc_str8_push_buffer(arena: *Arena, len: u64, buffer: [*]u8) oc_str8; + // extern fn oc_str8_push_cstring(arena: *Arena, str: [*]const u8) oc_str8; + // extern fn oc_str8_push_copy(arena: *Arena, s: oc_str8) oc_str8; + // extern fn oc_str8_push_slice(arena: *Arena, s: oc_str8, start: u64, end: u64) oc_str8; + // // extern fn oc_str8_pushfv(arena: oc_arena*, char: const* format, args: va_list) oc_str8; + // // extern fn oc_str8_pushf(arena: oc_arena*, char: const* format, ...) oc_str8; + // extern fn oc_str8_cmp(s1: oc_str8, s2: oc_str8) c_int; + + // extern fn oc_str8_list_push(oc_arena* arena, oc_str8_list* list, oc_str8 str) void; + // extern fn oc_str8_list_pushf(oc_arena* arena, oc_str8_list* list, const char* format, ...) void; + + // extern fn oc_str8_list_collate(oc_arena* arena, oc_str8_list list, oc_str8 prefix, oc_str8 separator, oc_str8 postfix) oc_str8; + // extern fn oc_str8_list_join(oc_arena* arena, oc_str8_list list) oc_str8; + // extern fn oc_str8_split(oc_arena* arena, oc_str8 str, oc_str8_list separators) oc_str8_list; + + // extern fn oc_str16_from_buffer(u64 len, u16* buffer) oc_str16; + // extern fn oc_str16_slice(oc_str16 s, u64 start, u64 end) oc_str16; + + // extern fn oc_str16_push_buffer(oc_arena* arena, u64 len, u16* buffer) oc_str16; + // extern fn oc_str16_push_copy(oc_arena* arena, oc_str16 s) oc_str16; + // extern fn oc_str16_push_slice(oc_arena* arena, oc_str16 s, u64 start, u64 end) oc_str16; + // extern fn oc_str16_list_push(oc_arena* arena, oc_str16_list* list, oc_str16 str) void; + // extern fn oc_str16_list_join(oc_arena* arena, oc_str16_list list) oc_str16; + // extern fn oc_str16_split(oc_arena* arena, oc_str16 str, oc_str16_list separators) oc_str16_list; + // extern fn oc_str32_from_buffer(u64 len, u32* buffer) oc_str32; + // extern fn oc_str32_slice(oc_str32 s, u64 start, u64 end) oc_str32; + + // extern fn oc_str32_push_buffer(oc_arena* arena, u64 len, u32* buffer) oc_str32; + // extern fn oc_str32_push_copy(oc_arena* arena, oc_str32 s) oc_str32; + // extern fn oc_str32_push_slice(oc_arena* arena, oc_str32 s, u64 start, u64 end) oc_str32; + // extern fn oc_str32_list_push(oc_arena* arena, oc_str32_list* list, oc_str32 str) void; + // extern fn oc_str32_list_join(oc_arena* arena, oc_str32_list list) oc_str32; + // extern fn oc_str32_split(oc_arena* arena, oc_str32 str, oc_str32_list separators) oc_str32_list; + + pub fn fromSlice(str: []const CharType) Self { + return .{ + .ptr = @constCast(str.ptr), + .len = str.len, + }; + } + + pub fn slice(self: *const Self) []CharType { + if (self.ptr) |p| { + return p[0..self.len]; + } + + return &[_]CharType{}; + } + + pub fn sliceInner(self: *const Self, start: u64, end: u64) []CharType { + if (self.ptr) |p| { + assert(start <= end, "{}.sliceLen: start <= end", .{typename()}, @src()); + assert(end <= self.len, "{}.sliceLen: end <= self.len", .{typename()}, @src()); + return p[start..end]; + } + + return &[_]CharType{}; + } + + pub fn fromBuffer(len: u64, buffer: ?[]CharType) Self { + return .{ + .ptr = buffer, + .len = @intCast(len), + }; + } + + // pub fn cmp(a: *const Self, b: *const Self) std.math.Order { + // if (CharType != u8) { + // @compileError("cmp() is only supported for Str8"); + // } + // const value = strncmp(a.ptr, b.ptr, std.math.min(a.len, b.len)); + + // } + // TODO + + fn typename() []const u8 { + return switch (CharType) { + u8 => "Str8", + u16 => "Str16", + u32 => "Str32", + else => unreachable, + }; + } + }; +} + +fn stringListEltType(comptime StringType: type) type { + return extern struct { + list_elt: ListElt, + string: StringType, + }; +} + +fn stringListType() type { + return extern struct { + list: List, + elt_count: u64, + len: u64, + }; +} + +pub const Str8 = stringType(u8); +pub const Str16 = stringType(u16); +pub const Str32 = stringType(u32); + +pub const Str8ListElt = stringListEltType(Str8); +pub const Str16ListElt = stringListEltType(Str16); +pub const Str32ListElt = stringListEltType(Str32); + +pub const Str8List = stringListType(Str8); +pub const Str16List = stringListType(Str8); +pub const Str32List = stringListType(Str8); + +// pub const Str8 = extern struct { +// ptr: ?[*:0]u8, +// len: usize, + +// pub fn fromSlice(slice: [:0]const u8) Str8 { +// return .{ +// ptr: @constCast(slice.ptr), +// len: slice.len, +// }; +// } +// }; + +// typedef struct oc_str8 +// { +// char* ptr; +// size_t len; +// } oc_str8; + +// #define OC_STR8(s) ((oc_str8){ .ptr = (char*)s, .len = (s) ? strlen(s) : 0 }) + +//NOTE: this only works with string literals, but is sometimes necessary to generate compile-time constants +// #define OC_STR8_LIT(s) \ +// { \ +// (char*)(s), sizeof(s) - 1 \ +// } + +// #define oc_str8_lp(s) ((s).len), ((s).ptr) +// #define oc_str8_ip(s) (int)oc_str8_lp(s) + +// ORCA_API oc_str8 oc_str8_from_buffer(u64 len, char* buffer); +// ORCA_API oc_str8 oc_str8_slice(oc_str8 s, u64 start, u64 end); + +// ORCA_API oc_str8 oc_str8_push_buffer(oc_arena* arena, u64 len, char* buffer); +// ORCA_API oc_str8 oc_str8_push_cstring(oc_arena* arena, const char* str); +// ORCA_API oc_str8 oc_str8_push_copy(oc_arena* arena, oc_str8 s); +// ORCA_API oc_str8 oc_str8_push_slice(oc_arena* arena, oc_str8 s, u64 start, u64 end); + +// ORCA_API oc_str8 oc_str8_pushfv(oc_arena* arena, const char* format, va_list args); +// ORCA_API oc_str8 oc_str8_pushf(oc_arena* arena, const char* format, ...); + +// ORCA_API int oc_str8_cmp(oc_str8 s1, oc_str8 s2); + +// ORCA_API char* oc_str8_to_cstring(oc_arena* arena, oc_str8 string); + +// typedef struct oc_str8_elt +// { +// oc_list_elt listElt; +// oc_str8 string; +// } oc_str8_elt; + +// typedef struct oc_str8_list +// { +// oc_list list; +// u64 eltCount; +// u64 len; +// } oc_str8_list; + +// ORCA_API void oc_str8_list_push(oc_arena* arena, oc_str8_list* list, oc_str8 str); +// ORCA_API void oc_str8_list_pushf(oc_arena* arena, oc_str8_list* list, const char* format, ...); + +// ORCA_API oc_str8 oc_str8_list_collate(oc_arena* arena, oc_str8_list list, oc_str8 prefix, oc_str8 separator, oc_str8 postfix); +// ORCA_API oc_str8 oc_str8_list_join(oc_arena* arena, oc_str8_list list); +// ORCA_API oc_str8_list oc_str8_split(oc_arena* arena, oc_str8 str, oc_str8_list separators); + +// //---------------------------------------------------------------------------------- +// // [STRINGS] u16 strings +// //---------------------------------------------------------------------------------- +// typedef struct oc_str16 +// { +// u16* ptr; +// size_t len; +// } oc_str16; + +// ORCA_API oc_str16 oc_str16_from_buffer(u64 len, u16* buffer); +// ORCA_API oc_str16 oc_str16_slice(oc_str16 s, u64 start, u64 end); + +// ORCA_API oc_str16 oc_str16_push_buffer(oc_arena* arena, u64 len, u16* buffer); +// ORCA_API oc_str16 oc_str16_push_copy(oc_arena* arena, oc_str16 s); +// ORCA_API oc_str16 oc_str16_push_slice(oc_arena* arena, oc_str16 s, u64 start, u64 end); + +// typedef struct oc_str16_elt +// { +// oc_list_elt listElt; +// oc_str16 string; +// } oc_str16_elt; + +// typedef struct oc_str16_list +// { +// oc_list list; +// u64 eltCount; +// u64 len; +// } oc_str16_list; + +// ORCA_API void oc_str16_list_push(oc_arena* arena, oc_str16_list* list, oc_str16 str); +// ORCA_API oc_str16 oc_str16_list_join(oc_arena* arena, oc_str16_list list); +// ORCA_API oc_str16_list oc_str16_split(oc_arena* arena, oc_str16 str, oc_str16_list separators); + +// //---------------------------------------------------------------------------------- +// // [STRINGS] u32 strings +// //---------------------------------------------------------------------------------- +// typedef struct oc_str32 +// { +// u32* ptr; +// size_t len; +// } oc_str32; + +// ORCA_API oc_str32 oc_str32_from_buffer(u64 len, u32* buffer); +// ORCA_API oc_str32 oc_str32_slice(oc_str32 s, u64 start, u64 end); + +// ORCA_API oc_str32 oc_str32_push_buffer(oc_arena* arena, u64 len, u32* buffer); +// ORCA_API oc_str32 oc_str32_push_copy(oc_arena* arena, oc_str32 s); +// ORCA_API oc_str32 oc_str32_push_slice(oc_arena* arena, oc_str32 s, u64 start, u64 end); + +// typedef struct oc_str32_elt +// { +// oc_list_elt listElt; +// oc_str32 string; +// } oc_str32_elt; + +// typedef struct oc_str32_list +// { +// oc_list list; +// u64 eltCount; +// u64 len; +// } oc_str32_list; + +// ORCA_API void oc_str32_list_push(oc_arena* arena, oc_str32_list* list, oc_str32 str); +// ORCA_API oc_str32 oc_str32_list_join(oc_arena* arena, oc_str32_list list); +// ORCA_API oc_str32_list oc_str32_split(oc_arena* arena, oc_str32 str, oc_str32_list separators); + //------------------------------------------------------------------------------------------ // [UTF8] //------------------------------------------------------------------------------------------ -const UnicodeRange = extern struct { - first_code_point: Utf32, - count: u32, -}; +pub const Utf32 = u32; -const Utf8Dec = extern struct { - codepoint: Utf32, // decoded codepoint +pub const Utf8Dec = extern struct { + code_point: Utf32, // decoded codepoint size: u32, // size of corresponding oc_utf8 sequence }; -const Utf8 = struct { +pub const Utf8 = struct { // getting sizes / offsets / indices extern fn oc_utf8_size_from_leading_char(leadingChar: c_char) u32; - extern fn oc_utf8_codepoint_size(codePoint: Utf32) u32; + extern fn oc_utf8_codepoint_size(code_point: Utf32) u32; extern fn oc_utf8_codepoint_count_for_string(string: Str8) u64; - extern fn oc_utf8_byte_count_for_codepoints(codePoints: Str32) u64; + extern fn oc_utf8_byte_count_for_codepoints(code_points: Str32) u64; extern fn oc_utf8_next_offset(string: Str8, byteOffset: u64) u64; extern fn oc_utf8_prev_offset(string: Str8, byteOffset: u64) u64; @@ -218,11 +479,11 @@ const Utf8 = struct { // encoding / decoding extern fn oc_utf8_decode(string: Str8) Utf8Dec; //NOTE: decode a single oc_utf8 sequence at start of string extern fn oc_utf8_decode_at(string: Str8, offset: u64) Utf8Dec; //NOTE: decode a single oc_utf8 sequence starting at byte offset - extern fn oc_utf8_encode(dst: [*]u8, codePoint: Utf32) Str8; //NOTE: encode codepoint into backing buffer dst + extern fn oc_utf8_encode(dst: [*]u8, code_point: Utf32) Str8; //NOTE: encode codepoint into backing buffer dst extern fn oc_utf8_to_codepoints(maxCount: u64, backing: [*]Utf32, string: Str8) Str32; - extern fn oc_utf8_from_codepoints(maxBytes: u64, backing: [*]c_char, codePoints: Str32) Str8; + extern fn oc_utf8_from_codepoints(maxBytes: u64, backing: [*]c_char, code_points: Str32) Str8; extern fn oc_utf8_push_to_codepoints(arena: *Arena, string: Str8) Str32; - extern fn oc_utf8_push_from_codepoints(arena: *Arena, codePoints: Str32) Str8; + extern fn oc_utf8_push_from_codepoints(arena: *Arena, code_points: Str32) Str8; pub const decode = oc_utf8_decode; pub const decodeAt = oc_utf8_decode_at; @@ -233,6 +494,479 @@ const Utf8 = struct { pub const pushFromCodepoints = oc_utf8_push_from_codepoints; }; +//------------------------------------------------------------------------------------------ +// [UTF8] Unicode +//------------------------------------------------------------------------------------------ + +pub const UnicodeRange = extern struct { + first_code_point: Utf32, + count: u32, + + extern const OC_UNICODE_BASIC_LATIN: UnicodeRange; + extern const OC_UNICODE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT: UnicodeRange; + extern const OC_UNICODE_LATIN_EXTENDED_A: UnicodeRange; + extern const OC_UNICODE_LATIN_EXTENDED_B: UnicodeRange; + extern const OC_UNICODE_IPA_EXTENSIONS: UnicodeRange; + extern const OC_UNICODE_SPACING_MODIFIER_LETTERS: UnicodeRange; + extern const OC_UNICODE_COMBINING_DIACRITICAL_MARKS: UnicodeRange; + extern const OC_UNICODE_GREEK_COPTIC: UnicodeRange; + extern const OC_UNICODE_CYRILLIC: UnicodeRange; + extern const OC_UNICODE_CYRILLIC_SUPPLEMENT: UnicodeRange; + extern const OC_UNICODE_ARMENIAN: UnicodeRange; + extern const OC_UNICODE_HEBREW: UnicodeRange; + extern const OC_UNICODE_ARABIC: UnicodeRange; + extern const OC_UNICODE_SYRIAC: UnicodeRange; + extern const OC_UNICODE_THAANA: UnicodeRange; + extern const OC_UNICODE_DEVANAGARI: UnicodeRange; + extern const OC_UNICODE_BENGALI_ASSAMESE: UnicodeRange; + extern const OC_UNICODE_GURMUKHI: UnicodeRange; + extern const OC_UNICODE_GUJARATI: UnicodeRange; + extern const OC_UNICODE_ORIYA: UnicodeRange; + extern const OC_UNICODE_TAMIL: UnicodeRange; + extern const OC_UNICODE_TELUGU: UnicodeRange; + extern const OC_UNICODE_KANNADA: UnicodeRange; + extern const OC_UNICODE_MALAYALAM: UnicodeRange; + extern const OC_UNICODE_SINHALA: UnicodeRange; + extern const OC_UNICODE_THAI: UnicodeRange; + extern const OC_UNICODE_LAO: UnicodeRange; + extern const OC_UNICODE_TIBETAN: UnicodeRange; + extern const OC_UNICODE_MYANMAR: UnicodeRange; + extern const OC_UNICODE_GEORGIAN: UnicodeRange; + extern const OC_UNICODE_HANGUL_JAMO: UnicodeRange; + extern const OC_UNICODE_ETHIOPIC: UnicodeRange; + extern const OC_UNICODE_CHEROKEE: UnicodeRange; + extern const OC_UNICODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS: UnicodeRange; + extern const OC_UNICODE_OGHAM: UnicodeRange; + extern const OC_UNICODE_RUNIC: UnicodeRange; + extern const OC_UNICODE_TAGALOG: UnicodeRange; + extern const OC_UNICODE_HANUNOO: UnicodeRange; + extern const OC_UNICODE_BUHID: UnicodeRange; + extern const OC_UNICODE_TAGBANWA: UnicodeRange; + extern const OC_UNICODE_KHMER: UnicodeRange; + extern const OC_UNICODE_MONGOLIAN: UnicodeRange; + extern const OC_UNICODE_LIMBU: UnicodeRange; + extern const OC_UNICODE_TAI_LE: UnicodeRange; + extern const OC_UNICODE_KHMER_SYMBOLS: UnicodeRange; + extern const OC_UNICODE_PHONETIC_EXTENSIONS: UnicodeRange; + extern const OC_UNICODE_LATIN_EXTENDED_ADDITIONAL: UnicodeRange; + extern const OC_UNICODE_GREEK_EXTENDED: UnicodeRange; + extern const OC_UNICODE_GENERAL_PUNCTUATION: UnicodeRange; + extern const OC_UNICODE_SUPERSCRIPTS_AND_SUBSCRIPTS: UnicodeRange; + extern const OC_UNICODE_CURRENCY_SYMBOLS: UnicodeRange; + extern const OC_UNICODE_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS: UnicodeRange; + extern const OC_UNICODE_LETTERLIKE_SYMBOLS: UnicodeRange; + extern const OC_UNICODE_NUMBER_FORMS: UnicodeRange; + extern const OC_UNICODE_ARROWS: UnicodeRange; + extern const OC_UNICODE_MATHEMATICAL_OPERATORS: UnicodeRange; + extern const OC_UNICODE_MISCELLANEOUS_TECHNICAL: UnicodeRange; + extern const OC_UNICODE_CONTROL_PICTURES: UnicodeRange; + extern const OC_UNICODE_OPTICAL_CHARACTER_RECOGNITION: UnicodeRange; + extern const OC_UNICODE_ENCLOSED_ALPHANUMERICS: UnicodeRange; + extern const OC_UNICODE_BOX_DRAWING: UnicodeRange; + extern const OC_UNICODE_BLOCK_ELEMENTS: UnicodeRange; + extern const OC_UNICODE_GEOMETRIC_SHAPES: UnicodeRange; + extern const OC_UNICODE_MISCELLANEOUS_SYMBOLS: UnicodeRange; + extern const OC_UNICODE_DINGBATS: UnicodeRange; + extern const OC_UNICODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A: UnicodeRange; + extern const OC_UNICODE_SUPPLEMENTAL_ARROWS_A: UnicodeRange; + extern const OC_UNICODE_BRAILLE_PATTERNS: UnicodeRange; + extern const OC_UNICODE_SUPPLEMENTAL_ARROWS_B: UnicodeRange; + extern const OC_UNICODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B: UnicodeRange; + extern const OC_UNICODE_SUPPLEMENTAL_MATHEMATICAL_OPERATORS: UnicodeRange; + extern const OC_UNICODE_MISCELLANEOUS_SYMBOLS_AND_ARROWS: UnicodeRange; + extern const OC_UNICODE_CJK_RADICALS_SUPPLEMENT: UnicodeRange; + extern const OC_UNICODE_KANGXI_RADICALS: UnicodeRange; + extern const OC_UNICODE_IDEOGRAPHIC_DESCRIPTION_CHARACTERS: UnicodeRange; + extern const OC_UNICODE_CJK_SYMBOLS_AND_PUNCTUATION: UnicodeRange; + extern const OC_UNICODE_HIRAGANA: UnicodeRange; + extern const OC_UNICODE_KATAKANA: UnicodeRange; + extern const OC_UNICODE_BOPOMOFO: UnicodeRange; + extern const OC_UNICODE_HANGUL_COMPATIBILITY_JAMO: UnicodeRange; + extern const OC_UNICODE_KANBUN_KUNTEN: UnicodeRange; + extern const OC_UNICODE_BOPOMOFO_EXTENDED: UnicodeRange; + extern const OC_UNICODE_KATAKANA_PHONETIC_EXTENSIONS: UnicodeRange; + extern const OC_UNICODE_ENCLOSED_CJK_LETTERS_AND_MONTHS: UnicodeRange; + extern const OC_UNICODE_CJK_COMPATIBILITY: UnicodeRange; + extern const OC_UNICODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A: UnicodeRange; + extern const OC_UNICODE_YIJING_HEXAGRAM_SYMBOLS: UnicodeRange; + extern const OC_UNICODE_CJK_UNIFIED_IDEOGRAPHS: UnicodeRange; + extern const OC_UNICODE_YI_SYLLABLES: UnicodeRange; + extern const OC_UNICODE_YI_RADICALS: UnicodeRange; + extern const OC_UNICODE_HANGUL_SYLLABLES: UnicodeRange; + extern const OC_UNICODE_HIGH_SURROGATE_AREA: UnicodeRange; + extern const OC_UNICODE_LOW_SURROGATE_AREA: UnicodeRange; + extern const OC_UNICODE_PRIVATE_USE_AREA: UnicodeRange; + extern const OC_UNICODE_CJK_COMPATIBILITY_IDEOGRAPHS: UnicodeRange; + extern const OC_UNICODE_ALPHABETIC_PRESENTATION_FORMS: UnicodeRange; + extern const OC_UNICODE_ARABIC_PRESENTATION_FORMS_A: UnicodeRange; + extern const OC_UNICODE_VARIATION_SELECTORS: UnicodeRange; + extern const OC_UNICODE_COMBINING_HALF_MARKS: UnicodeRange; + extern const OC_UNICODE_CJK_COMPATIBILITY_FORMS: UnicodeRange; + extern const OC_UNICODE_SMALL_FORM_VARIANTS: UnicodeRange; + extern const OC_UNICODE_ARABIC_PRESENTATION_FORMS_B: UnicodeRange; + extern const OC_UNICODE_HALFWIDTH_AND_FULLWIDTH_FORMS: UnicodeRange; + extern const OC_UNICODE_SPECIALS: UnicodeRange; + extern const OC_UNICODE_LINEAR_B_SYLLABARY: UnicodeRange; + extern const OC_UNICODE_LINEAR_B_IDEOGRAMS: UnicodeRange; + extern const OC_UNICODE_AEGEAN_NUMBERS: UnicodeRange; + extern const OC_UNICODE_OLD_ITALIC: UnicodeRange; + extern const OC_UNICODE_GOTHIC: UnicodeRange; + extern const OC_UNICODE_UGARITIC: UnicodeRange; + extern const OC_UNICODE_DESERET: UnicodeRange; + extern const OC_UNICODE_SHAVIAN: UnicodeRange; + extern const OC_UNICODE_OSMANYA: UnicodeRange; + extern const OC_UNICODE_CYPRIOT_SYLLABARY: UnicodeRange; + extern const OC_UNICODE_BYZANTINE_MUSICAL_SYMBOLS: UnicodeRange; + extern const OC_UNICODE_MUSICAL_SYMBOLS: UnicodeRange; + extern const OC_UNICODE_TAI_XUAN_JING_SYMBOLS: UnicodeRange; + extern const OC_UNICODE_MATHEMATICAL_ALPHANUMERIC_SYMBOLS: UnicodeRange; + extern const OC_UNICODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B: UnicodeRange; + extern const OC_UNICODE_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT: UnicodeRange; + extern const OC_UNICODE_TAGS: UnicodeRange; + extern const OC_UNICODE_VARIATION_SELECTORS_SUPPLEMENT: UnicodeRange; + extern const OC_UNICODE_SUPPLEMENTARY_PRIVATE_USE_AREA_A: UnicodeRange; + extern const OC_UNICODE_SUPPLEMENTARY_PRIVATE_USE_AREA_B: UnicodeRange; + + pub const Enum = enum { + BasicLatin, + C1ControlsAndLatin1Supplement, + LatinExtendedA, + LatinExtendedB, + IpaExtensions, + SpacingModifierLetters, + CombiningDiacriticalMarks, + GreekCoptic, + Cyrillic, + CyrillicSupplement, + Armenian, + Hebrew, + Arabic, + Syriac, + Thaana, + Devanagari, + BengaliAssamese, + Gurmukhi, + Gujarati, + Oriya, + Tamil, + Telugu, + Kannada, + Malayalam, + Sinhala, + Thai, + Lao, + Tibetan, + Myanmar, + Georgian, + HangulJamo, + Ethiopic, + Cherokee, + UnifiedCanadianAboriginalSyllabics, + Ogham, + Runic, + Tagalog, + Hanunoo, + Buhid, + Tagbanwa, + Khmer, + Mongolian, + Limbu, + TaiLe, + KhmerSymbols, + PhoneticExtensions, + LatinExtendedAdditional, + GreekExtended, + GeneralPunctuation, + SuperscriptsAndSubscripts, + CurrencySymbols, + CombiningDiacriticalMarksForSymbols, + LetterlikeSymbols, + NumberForms, + Arrows, + MathematicalOperators, + MiscellaneousTechnical, + ControlPictures, + OpticalCharacterRecognition, + EnclosedAlphanumerics, + BoxDrawing, + BlockElements, + GeometricShapes, + MiscellaneousSymbols, + Dingbats, + MiscellaneousMathematicalSymbolsA, + SupplementalArrowsA, + BraillePatterns, + SupplementalArrowsB, + MiscellaneousMathematicalSymbolsB, + SupplementalMathematicalOperators, + MiscellaneousSymbolsAndArrows, + CjkRadicalsSupplement, + KangxiRadicals, + IdeographicDescriptionCharacters, + CjkSymbolsAndPunctuation, + Hiragana, + Katakana, + Bopomofo, + HangulCompatibilityJamo, + KanbunKunten, + BopomofoExtended, + KatakanaPhoneticExtensions, + EnclosedCjkLettersAndMonths, + CjkCompatibility, + CjkUnifiedIdeographsExtensionA, + YijingHexagramSymbols, + CjkUnifiedIdeographs, + YiSyllables, + YiRadicals, + HangulSyllables, + HighSurrogateArea, + LowSurrogateArea, + PrivateUseArea, + CjkCompatibilityIdeographs, + AlphabeticPresentationForms, + ArabicPresentationFormsA, + VariationSelectors, + CombiningHalfMarks, + CjkCompatibilityForms, + SmallFormVariants, + ArabicPresentationFormsB, + HalfwidthAndFullwidthForms, + Specials, + LinearBSyllabary, + LinearBIdeograms, + AegeanNumbers, + OldItalic, + Gothic, + Ugaritic, + Deseret, + Shavian, + Osmanya, + CypriotSyllabary, + ByzantineMusicalSymbols, + MusicalSymbols, + TaiXuanJingSymbols, + MathematicalAlphanumericSymbols, + CjkUnifiedIdeographsExtensionB, + CjkCompatibilityIdeographsSupplement, + Tags, + VariationSelectorsSupplement, + SupplementaryPrivateUseAreaA, + SupplementaryPrivateUseAreaB, + }; + + pub fn range(comptime enums: []const Enum) [enums.len]UnicodeRange { + var r: [enums.len]UnicodeRange = undefined; + for (enums, 0..r.len) |e, i| { + r[i] = switch (e) { + .BasicLatin => OC_UNICODE_BASIC_LATIN, + .C1ControlsAndLatin1Supplement => OC_UNICODE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT, + .LatinExtendedA => OC_UNICODE_LATIN_EXTENDED_A, + .LatinExtendedB => OC_UNICODE_LATIN_EXTENDED_B, + .IpaExtensions => OC_UNICODE_IPA_EXTENSIONS, + .SpacingModifierLetters => OC_UNICODE_SPACING_MODIFIER_LETTERS, + .CombiningDiacriticalMarks => OC_UNICODE_COMBINING_DIACRITICAL_MARKS, + .GreekCoptic => OC_UNICODE_GREEK_COPTIC, + .Cyrillic => OC_UNICODE_CYRILLIC, + .CyrillicSupplement => OC_UNICODE_CYRILLIC_SUPPLEMENT, + .Armenian => OC_UNICODE_ARMENIAN, + .Hebrew => OC_UNICODE_HEBREW, + .Arabic => OC_UNICODE_ARABIC, + .Syriac => OC_UNICODE_SYRIAC, + .Thaana => OC_UNICODE_THAANA, + .Devanagari => OC_UNICODE_DEVANAGARI, + .BengaliAssamese => OC_UNICODE_BENGALI_ASSAMESE, + .Gurmukhi => OC_UNICODE_GURMUKHI, + .Gujarati => OC_UNICODE_GUJARATI, + .Oriya => OC_UNICODE_ORIYA, + .Tamil => OC_UNICODE_TAMIL, + .Telugu => OC_UNICODE_TELUGU, + .Kannada => OC_UNICODE_KANNADA, + .Malayalam => OC_UNICODE_MALAYALAM, + .Sinhala => OC_UNICODE_SINHALA, + .Thai => OC_UNICODE_THAI, + .Lao => OC_UNICODE_LAO, + .Tibetan => OC_UNICODE_TIBETAN, + .Myanmar => OC_UNICODE_MYANMAR, + .Georgian => OC_UNICODE_GEORGIAN, + .HangulJamo => OC_UNICODE_HANGUL_JAMO, + .Ethiopic => OC_UNICODE_ETHIOPIC, + .Cherokee => OC_UNICODE_CHEROKEE, + .UnifiedCanadianAboriginalSyllabics => OC_UNICODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS, + .Ogham => OC_UNICODE_OGHAM, + .Runic => OC_UNICODE_RUNIC, + .Tagalog => OC_UNICODE_TAGALOG, + .Hanunoo => OC_UNICODE_HANUNOO, + .Buhid => OC_UNICODE_BUHID, + .Tagbanwa => OC_UNICODE_TAGBANWA, + .Khmer => OC_UNICODE_KHMER, + .Mongolian => OC_UNICODE_MONGOLIAN, + .Limbu => OC_UNICODE_LIMBU, + .TaiLe => OC_UNICODE_TAI_LE, + .KhmerSymbols => OC_UNICODE_KHMER_SYMBOLS, + .PhoneticExtensions => OC_UNICODE_PHONETIC_EXTENSIONS, + .LatinExtendedAdditional => OC_UNICODE_LATIN_EXTENDED_ADDITIONAL, + .GreekExtended => OC_UNICODE_GREEK_EXTENDED, + .GeneralPunctuation => OC_UNICODE_GENERAL_PUNCTUATION, + .SuperscriptsAndSubscripts => OC_UNICODE_SUPERSCRIPTS_AND_SUBSCRIPTS, + .CurrencySymbols => OC_UNICODE_CURRENCY_SYMBOLS, + .CombiningDiacriticalMarksForSymbols => OC_UNICODE_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS, + .LetterlikeSymbols => OC_UNICODE_LETTERLIKE_SYMBOLS, + .NumberForms => OC_UNICODE_NUMBER_FORMS, + .Arrows => OC_UNICODE_ARROWS, + .MathematicalOperators => OC_UNICODE_MATHEMATICAL_OPERATORS, + .MiscellaneousTechnical => OC_UNICODE_MISCELLANEOUS_TECHNICAL, + .ControlPictures => OC_UNICODE_CONTROL_PICTURES, + .OpticalCharacterRecognition => OC_UNICODE_OPTICAL_CHARACTER_RECOGNITION, + .EnclosedAlphanumerics => OC_UNICODE_ENCLOSED_ALPHANUMERICS, + .BoxDrawing => OC_UNICODE_BOX_DRAWING, + .BlockElements => OC_UNICODE_BLOCK_ELEMENTS, + .GeometricShapes => OC_UNICODE_GEOMETRIC_SHAPES, + .MiscellaneousSymbols => OC_UNICODE_MISCELLANEOUS_SYMBOLS, + .Dingbats => OC_UNICODE_DINGBATS, + .MiscellaneousMathematicalSymbolsA => OC_UNICODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A, + .SupplementalArrowsA => OC_UNICODE_SUPPLEMENTAL_ARROWS_A, + .BraillePatterns => OC_UNICODE_BRAILLE_PATTERNS, + .SupplementalArrowsB => OC_UNICODE_SUPPLEMENTAL_ARROWS_B, + .MiscellaneousMathematicalSymbolsB => OC_UNICODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B, + .SupplementalMathematicalOperators => OC_UNICODE_SUPPLEMENTAL_MATHEMATICAL_OPERATORS, + .MiscellaneousSymbolsAndArrows => OC_UNICODE_MISCELLANEOUS_SYMBOLS_AND_ARROWS, + .CjkRadicalsSupplement => OC_UNICODE_CJK_RADICALS_SUPPLEMENT, + .KangxiRadicals => OC_UNICODE_KANGXI_RADICALS, + .IdeographicDescriptionCharacters => OC_UNICODE_IDEOGRAPHIC_DESCRIPTION_CHARACTERS, + .CjkSymbolsAndPunctuation => OC_UNICODE_CJK_SYMBOLS_AND_PUNCTUATION, + .Hiragana => OC_UNICODE_HIRAGANA, + .Katakana => OC_UNICODE_KATAKANA, + .Bopomofo => OC_UNICODE_BOPOMOFO, + .HangulCompatibilityJamo => OC_UNICODE_HANGUL_COMPATIBILITY_JAMO, + .KanbunKunten => OC_UNICODE_KANBUN_KUNTEN, + .BopomofoExtended => OC_UNICODE_BOPOMOFO_EXTENDED, + .KatakanaPhoneticExtensions => OC_UNICODE_KATAKANA_PHONETIC_EXTENSIONS, + .EnclosedCjkLettersAndMonths => OC_UNICODE_ENCLOSED_CJK_LETTERS_AND_MONTHS, + .CjkCompatibility => OC_UNICODE_CJK_COMPATIBILITY, + .CjkUnifiedIdeographsExtensionA => OC_UNICODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A, + .YijingHexagramSymbols => OC_UNICODE_YIJING_HEXAGRAM_SYMBOLS, + .CjkUnifiedIdeographs => OC_UNICODE_CJK_UNIFIED_IDEOGRAPHS, + .YiSyllables => OC_UNICODE_YI_SYLLABLES, + .YiRadicals => OC_UNICODE_YI_RADICALS, + .HangulSyllables => OC_UNICODE_HANGUL_SYLLABLES, + .HighSurrogateArea => OC_UNICODE_HIGH_SURROGATE_AREA, + .LowSurrogateArea => OC_UNICODE_LOW_SURROGATE_AREA, + .PrivateUseArea => OC_UNICODE_PRIVATE_USE_AREA, + .CjkCompatibilityIdeographs => OC_UNICODE_CJK_COMPATIBILITY_IDEOGRAPHS, + .AlphabeticPresentationForms => OC_UNICODE_ALPHABETIC_PRESENTATION_FORMS, + .ArabicPresentationFormsA => OC_UNICODE_ARABIC_PRESENTATION_FORMS_A, + .VariationSelectors => OC_UNICODE_VARIATION_SELECTORS, + .CombiningHalfMarks => OC_UNICODE_COMBINING_HALF_MARKS, + .CjkCompatibilityForms => OC_UNICODE_CJK_COMPATIBILITY_FORMS, + .SmallFormVariants => OC_UNICODE_SMALL_FORM_VARIANTS, + .ArabicPresentationFormsB => OC_UNICODE_ARABIC_PRESENTATION_FORMS_B, + .HalfwidthAndFullwidthForms => OC_UNICODE_HALFWIDTH_AND_FULLWIDTH_FORMS, + .Specials => OC_UNICODE_SPECIALS, + .LinearBSyllabary => OC_UNICODE_LINEAR_B_SYLLABARY, + .LinearBIdeograms => OC_UNICODE_LINEAR_B_IDEOGRAMS, + .AegeanNumbers => OC_UNICODE_AEGEAN_NUMBERS, + .OldItalic => OC_UNICODE_OLD_ITALIC, + .Gothic => OC_UNICODE_GOTHIC, + .Ugaritic => OC_UNICODE_UGARITIC, + .Deseret => OC_UNICODE_DESERET, + .Shavian => OC_UNICODE_SHAVIAN, + .Osmanya => OC_UNICODE_OSMANYA, + .CypriotSyllabary => OC_UNICODE_CYPRIOT_SYLLABARY, + .ByzantineMusicalSymbols => OC_UNICODE_BYZANTINE_MUSICAL_SYMBOLS, + .MusicalSymbols => OC_UNICODE_MUSICAL_SYMBOLS, + .TaiXuanJingSymbols => OC_UNICODE_TAI_XUAN_JING_SYMBOLS, + .MathematicalAlphanumericSymbols => OC_UNICODE_MATHEMATICAL_ALPHANUMERIC_SYMBOLS, + .CjkUnifiedIdeographsExtensionB => OC_UNICODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B, + .CjkCompatibilityIdeographsSupplement => OC_UNICODE_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT, + .Tags => OC_UNICODE_TAGS, + .VariationSelectorsSupplement => OC_UNICODE_VARIATION_SELECTORS_SUPPLEMENT, + .SupplementaryPrivateUseAreaA => OC_UNICODE_SUPPLEMENTARY_PRIVATE_USE_AREA_A, + .SupplementaryPrivateUseAreaB => OC_UNICODE_SUPPLEMENTARY_PRIVATE_USE_AREA_B, + }; + } + + return r; + } +}; + +//------------------------------------------------------------------------------------------ +// [FONT]: fonts +//------------------------------------------------------------------------------------------ + +pub const Font = extern struct { + h: u64, + + extern fn oc_font_nil() Font; + extern fn oc_font_is_nil(font: Font) bool; + + extern fn oc_font_create_from_memory(mem: Str8, range_count: u32, ranges: [*]const UnicodeRange) Font; + extern fn oc_font_create_from_file(file: File, range_count: u32, ranges: [*]const UnicodeRange) Font; + extern fn oc_font_create_from_path(path: Str8, range_count: u32, ranges: [*]const UnicodeRange) Font; + + extern fn oc_font_get_glyph_indices(font: Font, code_points: Str32, backing: Str32) Str32; + extern fn oc_font_push_glyph_indices(font: Font, arena: *Arena, code_points: Str32) Str32; + extern fn oc_font_get_glyph_index(font: Font, code_point: Utf32) u32; + extern fn oc_font_destroy(font: Font) void; + + extern fn oc_font_get_metrics(font: Font) FontMetrics; + extern fn oc_font_get_metrics_unscaled(font: Font, em_size: f32) FontMetrics; + extern fn oc_font_get_scale_for_em_pixels(font: Font, em_size: f32) f32; + extern fn oc_font_text_metrics_utf32(font: Font, font_size: f32, code_points: Str32) TextMetrics; + extern fn oc_font_text_metrics(font: Font, font_size: f32, text: Str8) TextMetrics; + + pub const nil = oc_font_nil; + pub const isNil = oc_font_is_nil; + pub fn createFromMemory(mem: []const u8, ranges: []const UnicodeRange) Font { + return oc_font_create_from_memory(Str8.fromSlice(mem), @intCast(ranges.len), ranges.ptr); + } + pub fn createFromFile(file: File, ranges: []const UnicodeRange) Font { + return oc_font_create_from_file(file, @intCast(ranges.len), ranges.ptr); + } + pub fn createFromPath(path: []const u8, ranges: []const UnicodeRange) Font { + return oc_font_create_from_path(Str8.fromSlice(path), @intCast(ranges.len), ranges.ptr); + } + pub const getGlyphIndices = oc_font_get_glyph_indices; + pub const pushGlyphIndices = oc_font_push_glyph_indices; + pub const getGlyphIndex = oc_font_get_glyph_index; + pub const destroy = oc_font_destroy; + pub const getMetrics = oc_font_get_metrics; + pub const getMetricsUnscaled = oc_font_get_metrics_unscaled; + pub const getScaleForEmPixels = oc_font_get_scale_for_em_pixels; + pub const textMetricsUtf32 = oc_font_text_metrics_utf32; + pub const textMetrics = oc_font_text_metrics; +}; + +pub const JointType = enum(c_uint) { + Miter, + Bevel, + None, +}; + +pub const CapType = enum(c_uint) { + None, + Square, +}; + +pub const FontMetrics = extern struct { + ascent: f32, // the extent above the baseline (by convention a positive value extends above the baseline) + descent: f32, // the extent below the baseline (by convention, positive value extends below the baseline) + line_gap: f32, // spacing between one row's descent and the next row's ascent + x_height: f32, // height of the lower case letter 'x' + cap_height: f32, // height of the upper case letter 'M' + width: f32, // maximum width of the font +}; + +pub const GlyphMetrics = extern struct { + ink: Rect, + advance: Vec2, +}; + +pub const TextMetrics = extern struct { + ink: Rect, + logical: Rect, + advance: Vec2, +}; + //------------------------------------------------------------------------------------------ // [APP] //------------------------------------------------------------------------------------------ @@ -255,152 +989,279 @@ const MouseCursor = enum(c_uint) { extern fn oc_set_cursor(cursor: MouseCursor) void; pub const setCursor = oc_set_cursor; +pub const ScanCode = enum(c_uint) { + Unknown = 0, + Space = 32, + Apostrophe = 39, + Comma = 44, + Minus = 45, + Period = 46, + Slash = 47, + Num0 = 48, + Num1 = 49, + Num2 = 50, + Num3 = 51, + Num4 = 52, + Num5 = 53, + Num6 = 54, + Num7 = 55, + Num8 = 56, + Num9 = 57, + Semicolon = 59, + Equal = 61, + LeftBracket = 91, + Backslash = 92, + RightBracket = 93, + GraveAccent = 96, + A = 97, + B = 98, + C = 99, + D = 100, + E = 101, + F = 102, + G = 103, + H = 104, + I = 105, + J = 106, + K = 107, + L = 108, + M = 109, + N = 110, + O = 111, + P = 112, + Q = 113, + R = 114, + S = 115, + T = 116, + U = 117, + V = 118, + W = 119, + X = 120, + Y = 121, + Z = 122, + World1 = 161, + World2 = 162, + Escape = 256, + Enter = 257, + Tab = 258, + Backspace = 259, + Insert = 260, + Delete = 261, + Right = 262, + Left = 263, + Down = 264, + Up = 265, + PageUp = 266, + PageDown = 267, + Home = 268, + End = 269, + CapsLock = 280, + ScrollLock = 281, + NumLock = 282, + PrintScreen = 283, + Pause = 284, + F1 = 290, + F2 = 291, + F3 = 292, + F4 = 293, + F5 = 294, + F6 = 295, + F7 = 296, + F8 = 297, + F9 = 298, + F10 = 299, + F11 = 300, + F12 = 301, + F13 = 302, + F14 = 303, + F15 = 304, + F16 = 305, + F17 = 306, + F18 = 307, + F19 = 308, + F20 = 309, + F21 = 310, + F22 = 311, + F23 = 312, + F24 = 313, + F25 = 314, + Kp0 = 320, + Kp1 = 321, + Kp2 = 322, + Kp3 = 323, + Kp4 = 324, + Kp5 = 325, + Kp6 = 326, + Kp7 = 327, + Kp8 = 328, + Kp9 = 329, + KpDecimal = 330, + KpDivide = 331, + KpMultiply = 332, + KpSubtract = 333, + KpAdd = 334, + KpEnter = 335, + KpEqual = 336, + LeftShift = 340, + LeftControl = 341, + LeftAlt = 342, + LeftSuper = 343, + RightShift = 344, + RightControl = 345, + RightAlt = 346, + RightSuper = 347, + Menu = 348, +}; + pub const KeyCode = enum(c_uint) { - Unknown = orca_c.OC_KEY_UNKNOWN, - Space = orca_c.OC_KEY_SPACE, - Apostrophe = orca_c.OC_KEY_APOSTROPHE, - Comma = orca_c.OC_KEY_COMMA, - Minus = orca_c.OC_KEY_MINUS, - Period = orca_c.OC_KEY_PERIOD, - Slash = orca_c.OC_KEY_SLASH, - Num0 = orca_c.OC_KEY_0, - Num1 = orca_c.OC_KEY_1, - Num2 = orca_c.OC_KEY_2, - Num3 = orca_c.OC_KEY_3, - Num4 = orca_c.OC_KEY_4, - Num5 = orca_c.OC_KEY_5, - Num6 = orca_c.OC_KEY_6, - Num7 = orca_c.OC_KEY_7, - Num8 = orca_c.OC_KEY_8, - Num9 = orca_c.OC_KEY_9, - Semicolon = orca_c.OC_KEY_SEMICOLON, - Equal = orca_c.OC_KEY_EQUAL, - A = orca_c.OC_KEY_A, - B = orca_c.OC_KEY_B, - C = orca_c.OC_KEY_C, - D = orca_c.OC_KEY_D, - E = orca_c.OC_KEY_E, - F = orca_c.OC_KEY_F, - G = orca_c.OC_KEY_G, - H = orca_c.OC_KEY_H, - I = orca_c.OC_KEY_I, - J = orca_c.OC_KEY_J, - K = orca_c.OC_KEY_K, - L = orca_c.OC_KEY_L, - M = orca_c.OC_KEY_M, - N = orca_c.OC_KEY_N, - O = orca_c.OC_KEY_O, - P = orca_c.OC_KEY_P, - Q = orca_c.OC_KEY_Q, - R = orca_c.OC_KEY_R, - S = orca_c.OC_KEY_S, - T = orca_c.OC_KEY_T, - U = orca_c.OC_KEY_U, - V = orca_c.OC_KEY_V, - W = orca_c.OC_KEY_W, - X = orca_c.OC_KEY_X, - Y = orca_c.OC_KEY_Y, - Z = orca_c.OC_KEY_Z, - LeftBracket = orca_c.OC_KEY_LEFT_BRACKET, - Backslash = orca_c.OC_KEY_BACKSLASH, - RightBracket = orca_c.OC_KEY_RIGHT_BRACKET, - GraveAccent = orca_c.OC_KEY_GRAVE_ACCENT, - World1 = orca_c.OC_KEY_WORLD_1, - World2 = orca_c.OC_KEY_WORLD_2, - Escape = orca_c.OC_KEY_ESCAPE, - Enter = orca_c.OC_KEY_ENTER, - Tab = orca_c.OC_KEY_TAB, - Backspace = orca_c.OC_KEY_BACKSPACE, - Insert = orca_c.OC_KEY_INSERT, - Delete = orca_c.OC_KEY_DELETE, - Right = orca_c.OC_KEY_RIGHT, - Left = orca_c.OC_KEY_LEFT, - Down = orca_c.OC_KEY_DOWN, - Up = orca_c.OC_KEY_UP, - PageUp = orca_c.OC_KEY_PAGE_UP, - PageDown = orca_c.OC_KEY_PAGE_DOWN, - Home = orca_c.OC_KEY_HOME, - End = orca_c.OC_KEY_END, - CapsLock = orca_c.OC_KEY_CAPS_LOCK, - ScrollLock = orca_c.OC_KEY_SCROLL_LOCK, - NumLock = orca_c.OC_KEY_NUM_LOCK, - PrintScreen = orca_c.OC_KEY_PRINT_SCREEN, - Pause = orca_c.OC_KEY_PAUSE, - F1 = orca_c.OC_KEY_F1, - F2 = orca_c.OC_KEY_F2, - F3 = orca_c.OC_KEY_F3, - F4 = orca_c.OC_KEY_F4, - F5 = orca_c.OC_KEY_F5, - F6 = orca_c.OC_KEY_F6, - F7 = orca_c.OC_KEY_F7, - F8 = orca_c.OC_KEY_F8, - F9 = orca_c.OC_KEY_F9, - F10 = orca_c.OC_KEY_F10, - F11 = orca_c.OC_KEY_F11, - F12 = orca_c.OC_KEY_F12, - F13 = orca_c.OC_KEY_F13, - F14 = orca_c.OC_KEY_F14, - F15 = orca_c.OC_KEY_F15, - F16 = orca_c.OC_KEY_F16, - F17 = orca_c.OC_KEY_F17, - F18 = orca_c.OC_KEY_F18, - F19 = orca_c.OC_KEY_F19, - F20 = orca_c.OC_KEY_F20, - F21 = orca_c.OC_KEY_F21, - F22 = orca_c.OC_KEY_F22, - F23 = orca_c.OC_KEY_F23, - F24 = orca_c.OC_KEY_F24, - F25 = orca_c.OC_KEY_F25, - Kp0 = orca_c.OC_KEY_KP_0, - Kp1 = orca_c.OC_KEY_KP_1, - Kp2 = orca_c.OC_KEY_KP_2, - Kp3 = orca_c.OC_KEY_KP_3, - Kp4 = orca_c.OC_KEY_KP_4, - Kp5 = orca_c.OC_KEY_KP_5, - Kp6 = orca_c.OC_KEY_KP_6, - Kp7 = orca_c.OC_KEY_KP_7, - Kp8 = orca_c.OC_KEY_KP_8, - Kp9 = orca_c.OC_KEY_KP_9, - KpDecimal = orca_c.OC_KEY_KP_DECIMAL, - KpDivide = orca_c.OC_KEY_KP_DIVIDE, - KpMultiply = orca_c.OC_KEY_KP_MULTIPLY, - KpSubtract = orca_c.OC_KEY_KP_SUBTRACT, - KpAdd = orca_c.OC_KEY_KP_ADD, - KpEnter = orca_c.OC_KEY_KP_ENTER, - KpEqual = orca_c.OC_KEY_KP_EQUAL, - LeftShift = orca_c.OC_KEY_LEFT_SHIFT, - LeftControl = orca_c.OC_KEY_LEFT_CONTROL, - LeftAlt = orca_c.OC_KEY_LEFT_ALT, - LeftSuper = orca_c.OC_KEY_LEFT_SUPER, - RightShift = orca_c.OC_KEY_RIGHT_SHIFT, - RightControl = orca_c.OC_KEY_RIGHT_CONTROL, - RightAlt = orca_c.OC_KEY_RIGHT_ALT, - RightSuper = orca_c.OC_KEY_RIGHT_SUPER, - Menu = orca_c.OC_KEY_MENU, - Count = orca_c.OC_KEY_COUNT, + Unknown = 0, + Space = ' ', + Apostrophe = '\'', + Comma = ',', + Minus = '-', + Period = '.', + Slash = '/', + Num0 = '0', + Num1 = '1', + Num2 = '2', + Num3 = '3', + Num4 = '4', + Num5 = '5', + Num6 = '6', + Num7 = '7', + Num8 = '8', + Num9 = '9', + Semicolon = ';', + Equal = '=', + LeftBracket = '[', + Backslash = '\\', + RightBracket = ']', + GraveAccent = '`', + A = 'a', + B = 'b', + C = 'c', + D = 'd', + E = 'e', + F = 'f', + G = 'g', + H = 'h', + I = 'i', + J = 'j', + K = 'k', + L = 'l', + M = 'm', + N = 'n', + O = 'o', + P = 'p', + Q = 'q', + R = 'r', + S = 's', + T = 't', + U = 'u', + V = 'v', + W = 'w', + X = 'x', + Y = 'y', + Z = 'z', + World1 = 161, + World2 = 162, + Escape = 256, + Enter = 257, + Tab = 258, + Backspace = 259, + Insert = 260, + Delete = 261, + Right = 262, + Left = 263, + Down = 264, + Up = 265, + PageUp = 266, + PageDown = 267, + Home = 268, + End = 269, + CapsLock = 280, + ScrollLock = 281, + NumLock = 282, + PrintScreen = 283, + Pause = 284, + F1 = 290, + F2 = 291, + F3 = 292, + F4 = 293, + F5 = 294, + F6 = 295, + F7 = 296, + F8 = 297, + F9 = 298, + F10 = 299, + F11 = 300, + F12 = 301, + F13 = 302, + F14 = 303, + F15 = 304, + F16 = 305, + F17 = 306, + F18 = 307, + F19 = 308, + F20 = 309, + F21 = 310, + F22 = 311, + F23 = 312, + F24 = 313, + F25 = 314, + Kp0 = 320, + Kp1 = 321, + Kp2 = 322, + Kp3 = 323, + Kp4 = 324, + Kp5 = 325, + Kp6 = 326, + Kp7 = 327, + Kp8 = 328, + Kp9 = 329, + KpDecimal = 330, + KpDivide = 331, + KpMultiply = 332, + KpSubtract = 333, + KpAdd = 334, + KpEnter = 335, + KpEqual = 336, + LeftShift = 340, + LeftControl = 341, + LeftAlt = 342, + LeftSuper = 343, + RightShift = 344, + RightControl = 345, + RightAlt = 346, + RightSuper = 347, + Menu = 348, + Count = 349, }; pub const MouseButton = enum(c_uint) { - Left = orca_c.OC_MOUSE_LEFT, - Right = orca_c.OC_MOUSE_RIGHT, - Middle = orca_c.OC_MOUSE_MIDDLE, - Ext1 = orca_c.OC_MOUSE_EXT1, - Ext2 = orca_c.OC_MOUSE_EXT2, + Left = 0x00, + Right = 0x01, + Middle = 0x02, + Ext1 = 0x03, + Ext2 = 0x04, }; //------------------------------------------------------------------------------------------ // [APP] windows //------------------------------------------------------------------------------------------ +extern fn oc_window_set_title(title: Str8) void; + pub fn windowSetTitle(title: [:0]const u8) void { - var title_str8: Str8 = .{ - .ptr = @constCast(title.ptr), - .len = title.len, - }; - orca_c.oc_window_set_title(title_str8); + // var title_str8: Str8 = .{ + // .ptr = @constCast(title.ptr), + // .len = title.len, + // }; + oc_window_set_title(Str8.fromSlice(title)); } extern fn oc_window_set_size(size: Vec2) void; +// pub const windowSetTitle = oc_window_set_title; pub const windowSetSize = oc_window_set_size; //------------------------------------------------------------------------------------------ @@ -429,19 +1290,6 @@ const FileDialogDesc = extern struct { filters: Str8List, }; -// typedef struct oc_file_dialog_desc -// { -// oc_file_dialog_kind kind; -// oc_file_dialog_flags flags; -// oc_str8 title; -// oc_str8 okLabel; -// oc_file startAt; -// oc_str8 startPath; -// oc_str8_list filters; - -// //... later customization options with checkboxes / radiobuttons -// } oc_file_dialog_desc; - const FileDialogButton = enum(c_uint) { Cancel, Ok, @@ -453,20 +1301,6 @@ const FileDialogResult = extern struct { selection: Str8List, }; -// typedef enum -// { -// OC_FILE_DIALOG_CANCEL = 0, -// OC_FILE_DIALOG_OK, -// } oc_file_dialog_button; - -// typedef struct oc_file_dialog_result -// { -// oc_file_dialog_button button; -// oc_str8 path; -// oc_str8_list selection; - -// } oc_file_dialog_result; - //------------------------------------------------------------------------------------------ // [CLOCK] //------------------------------------------------------------------------------------------ @@ -480,6 +1314,77 @@ pub const ClockKind = enum(c_uint) { extern fn oc_clock_time(clock: ClockKind) f64; pub const clockTime = oc_clock_time; +//------------------------------------------------------------------------------------------ +// [MATH] Vec2 +//------------------------------------------------------------------------------------------ + +pub const Vec2 = extern struct { + x: f32, + y: f32, + + pub fn mul(self: Vec2, scalar: f32) Vec2 { + return .{ + .x = self.x * scalar, + .y = self.y * scalar, + }; + } + + pub fn add(a: Vec2, b: Vec2) Vec2 { + return .{ + .x = a.x + b.x, + .y = a.y + b.y, + }; + } +}; + +//------------------------------------------------------------------------------------------ +// [MATH] Matrix +//------------------------------------------------------------------------------------------ + +pub const Mat2x3 = extern struct { + m: [6]f32, + + extern fn oc_mat2x3_mul(m: Mat2x3, p: Vec2) Vec2; + extern fn oc_mat2x3_mul_m(lhs: Mat2x3, rhs: Mat2x3) Mat2x3; + extern fn oc_mat2x3_inv(x: Mat2x3) Mat2x3; + extern fn oc_mat2x3_rotate(radians: f32) Mat2x3; + extern fn oc_mat2x3_translate(x: f32, y: f32) Mat2x3; + + extern fn oc_matrix_push(matrix: Mat2x3) void; + extern fn oc_matrix_pop() void; + extern fn oc_matrix_top() Mat2x3; + + pub const mul = oc_mat2x3_mul; + pub const mul_m = oc_mat2x3_mul_m; + pub const inv = oc_mat2x3_inv; + pub const rotate = oc_mat2x3_rotate; + pub const translate = oc_mat2x3_translate; + pub fn scale(x: f32, y: f32) Mat2x3 { + return .{ .m = .{ x, 0, 0, 0, y, 0 } }; + } + pub fn scaleUniform(s: f32) Mat2x3 { + return .{ .m = .{ s, 0, 0, 0, s, 0 } }; + } + + pub const push = oc_matrix_push; + pub const pop = oc_matrix_pop; + pub const top = oc_matrix_top; +}; + +//------------------------------------------------------------------------------------------ +// [GRAPHICS] Clip stack +//------------------------------------------------------------------------------------------ + +pub const clip = struct { + extern fn oc_clip_push(x: f32, y: f32, w: f32, h: f32) void; + extern fn oc_clip_pop() void; + extern fn oc_clip_top() Rect; + + pub const push = oc_clip_push; + pub const pop = oc_clip_pop; + pub const top = oc_clip_top; +}; + //------------------------------------------------------------------------------------------ // [GRAPHICS]: resources //------------------------------------------------------------------------------------------ @@ -487,6 +1392,8 @@ pub const clockTime = oc_clock_time; pub const Surface = extern struct { h: u64, + extern fn oc_surface_nil(void) Surface; + extern fn oc_surface_is_nil(surface: Surface) bool; extern fn oc_surface_canvas() Surface; extern fn oc_surface_gles() Surface; extern fn oc_surface_select(surface: Surface) void; @@ -503,8 +1410,9 @@ pub const Surface = extern struct { // elt_count: u32, // elements: [*]PathElt, // ) void; - extern fn oc_render(surface: Surface, canvas: Canvas) void; + pub const nil = oc_surface_nil; + pub const isNil = oc_surface_is_nil; pub const canvas = oc_surface_canvas; pub const gles = oc_surface_gles; pub const select = oc_surface_select; @@ -514,7 +1422,6 @@ pub const Surface = extern struct { pub const bringToFront = oc_surface_bring_to_front; pub const sendToBack = oc_surface_send_to_back; // pub const renderCommands = oc_surface_render_commands; - pub const render = oc_render; }; pub const Canvas = extern struct { @@ -524,31 +1431,40 @@ pub const Canvas = extern struct { extern fn oc_canvas_is_nil(canvas: Canvas) bool; extern fn oc_canvas_create() Canvas; extern fn oc_canvas_destroy(canvas: Canvas) void; - extern fn oc_canvas_set_current(canvas: Canvas) Canvas; + extern fn oc_canvas_select(canvas: Canvas) Canvas; + extern fn oc_render(canvas: Canvas) void; pub const nil = oc_canvas_nil; pub const isNil = oc_canvas_is_nil; pub const create = oc_canvas_create; pub const destroy = oc_canvas_destroy; - pub const setCurrent = oc_canvas_set_current; + pub const select = oc_canvas_select; + pub const render = oc_render; }; pub const Image = extern struct { h: u64, - pub const create = oc_image_create; - pub const destroy = oc_image_destroy; - pub const uploadRegionRGBA = oc_image_upload_region_rgba8; - pub const size = oc_image_size; - + extern fn oc_image_nil(void) Image; + extern fn oc_image_is_nil(image: Image) bool; extern fn oc_image_create(surface: Surface, width: u32, height: u32) Image; + extern fn oc_image_create_from_rgba8(surface: Surface, width: u32, height: u32, pixels: [*]u8) Image; + extern fn oc_image_create_from_memory(surface: Surface, mem: Str8, flip: bool) Image; + extern fn oc_image_create_from_file(surface: Surface, file: File, flip: bool) Image; + extern fn oc_image_create_from_path(surface: Surface, path: Str8, flip: bool) Image; extern fn oc_image_destroy(image: Image) void; extern fn oc_image_upload_region_rgba8(image: Image, region: Rect, pixels: [*]u8) void; extern fn oc_image_size(image: Image) Vec2; extern fn oc_image_draw(image: Image, rect: Rect) void; extern fn oc_image_draw_region(image: Image, srcRegion: Rect, dstRegion: Rect) void; + pub const nil = oc_image_nil; + pub const isNil = oc_image_is_nil; pub const create = oc_image_create; + pub const createFromRgba8 = oc_image_create_from_rgba8; + pub const createFromMemory = oc_image_create_from_memory; + pub const createFromFile = oc_image_create_from_file; + pub const createFromPath = oc_image_create_from_path; pub const destroy = oc_image_destroy; pub const uploadRegionRgba8 = oc_image_upload_region_rgba8; pub const size = oc_image_size; @@ -568,6 +1484,10 @@ pub const Rect = extern union { wh: Vec2, }, Array: [4]f32, + + pub fn xywh(x: f32, y: f32, w: f32, h: f32) Rect { + return .{ .Flat = .{ .x = x, .y = y, .w = w, .h = h } }; + } }; pub const Color = extern union { @@ -580,104 +1500,6 @@ pub const Color = extern union { Array: [4]f32, }; -//------------------------------------------------------------------------------------------ -// [GRAPHICS]: fonts -//------------------------------------------------------------------------------------------ - -//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 -//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. - -const Font = extern struct { - h: u64, - - extern fn oc_font_nil() Font; - extern fn oc_font_create_from_memory(mem: Str8, rangeCount: u32, ranges: [*]UnicodeRange) Font; - extern fn oc_font_destroy(font: Font) void; - extern fn oc_font_get_extents(font: Font) FontExtents; - extern fn oc_font_get_scaled_extents(font: Font, emSize: f32) FontExtents; - extern fn oc_font_get_scale_for_em_pixels(font: Font, emSize: f32) f32; - extern fn oc_font_get_glyph_indices(font: Font, codePoints: Str32, backing: Str32) Str32; - extern fn oc_font_push_glyph_indices(font: Font, arena: *Arena, codePoints: Str32) Str32; - extern fn oc_font_get_glyph_index(font: Font, codePoint: Utf32) u32; - extern fn oc_font_get_codepoint_extents(font: Font, codePoint: Utf32, outExtents: *TextExtents) c_int; - extern fn oc_font_get_glyph_extents(font: Font, glyphIndices: Str32, outExtents: *TextExtents) c_int; - extern fn oc_text_bounding_box_utf32(font: Font, fontSize: f32, text: Str32) Rect; - extern fn oc_text_bounding_box(font: Font, fontSize: f32, text: Str8) Rect; - - pub const nil = oc_font_nil; - pub fn createFromMemory(mem: Str8, ranges: []UnicodeRange) Font { - return oc_font_create_from_memory(mem, @intCast(ranges.len), ranges.ptr); - } - pub const destroy = oc_font_destroy; - pub const getExtents = oc_font_get_extents; - pub const getScaledExtents = oc_font_get_scaled_extents; - pub const getScaleForEmPixels = oc_font_get_scale_for_em_pixels; - pub const getGlyphIndices = oc_font_get_glyph_indices; - pub const pushGlyphIndices = oc_font_push_glyph_indices; - pub const getGlyphIndex = oc_font_get_glyph_index; - pub const getCodepointExtents = oc_font_get_codepoint_extents; - pub const getGlyphExtents = oc_font_get_glyph_extents; - pub const boundingBoxUtf32 = oc_text_bounding_box_utf32; - pub const boundingBox = oc_text_bounding_box; -}; - -const JointType = enum(c_uint) { - Miter, - Bevel, - None, -}; - -const CapType = enum(c_uint) { - None, - Square, -}; - -const FontExtents = extern struct { - ascent: f32, // the extent above the baseline (by convention a positive value extends above the baseline) - descent: f32, // the extent below the baseline (by convention, positive value extends below the baseline) - leading: f32, // spacing between one row's descent and the next row's ascent - x_height: f32, // height of the lower case letter 'x' - cap_height: f32, // height of the upper case letter 'M' - width: f32, // maximum width of the font -}; - -const TextExtents = extern struct { - x_bearing: f32, - y_bearing: f32, - width: f32, - height: f32, - x_advance: f32, - y_advance: f32, -}; - -//------------------------------------------------------------------------------------------ -// [GRAPHICS] Matrix / Clip stack -//------------------------------------------------------------------------------------------ - -pub const Mat2x3 = extern struct { - m: [6]f32, - - extern fn oc_matrix_push(matrix: Mat2x3) void; - extern fn oc_matrix_pop() void; - extern fn oc_matrix_top() Mat2x3; - - pub const push = oc_matrix_push; - pub const pop = oc_matrix_pop; - pub const top = oc_matrix_top; -}; - -pub const clip = struct { - extern fn oc_clip_push(x: f32, y: f32, w: f32, h: f32) void; - extern fn oc_clip_pop() void; - extern fn oc_clip_top() Rect; - - pub const push = oc_clip_push; - pub const pop = oc_clip_pop; - pub const top = oc_clip_top; -}; - //------------------------------------------------------------------------------------------ // [GRAPHICS]: graphics attributes setting/getting //------------------------------------------------------------------------------------------ @@ -687,7 +1509,7 @@ extern fn oc_set_color_rgba(r: f32, g: f32, b: f32, a: f32) void; extern fn oc_set_width(width: f32) void; extern fn oc_set_tolerance(tolerance: f32) void; extern fn oc_set_joint(joint: JointType) void; -extern fn oc_set_max_joint_excursion(maxJointExcursion: f32) void; +extern fn oc_set_max_joint_excursion(max_joint_excursion: f32) void; extern fn oc_set_cap(cap: CapType) void; extern fn oc_set_font(font: Font) void; extern fn oc_set_font_size(size: f32) void; @@ -743,7 +1565,7 @@ extern fn oc_quadratic_to(x1: f32, y1: f32, x2: f32, y2: f32) void; extern fn oc_cubic_to(x1: f32, y1: f32, x2: f32, y2: f32, x3: f32, y3: f32) void; extern fn oc_close_path() void; -extern fn oc_glyph_outlines(glyphIndices: Str32) Rect; +extern fn oc_glyph_outlines(glyph_indices: Str32) Rect; extern fn oc_codepoints_outlines(string: Str32) void; extern fn oc_text_outlines(string: Str8) void; @@ -782,7 +1604,7 @@ extern fn oc_ellipse_fill(x: f32, y: f32, rx: f32, ry: f32) void; extern fn oc_ellipse_stroke(x: f32, y: f32, rx: f32, ry: f32) void; extern fn oc_circle_fill(x: f32, y: f32, r: f32) void; extern fn oc_circle_stroke(x: f32, y: f32, r: f32) void; -extern fn oc_arc(x: f32, y: f32, r: f32, arcAngle: f32, startAngle: f32) void; +extern fn oc_arc(x: f32, y: f32, r: f32, arc_angle: f32, start_angle: f32) void; pub const rectangleFill = oc_rectangle_fill; pub const rectangleStroke = oc_rectangle_stroke; @@ -815,6 +1637,9 @@ const File = extern struct { extern fn oc_file_get_status(file: File) FileStatus; extern fn oc_file_size(file: File) u64; + extern fn oc_file_open_with_request(path: Str8, rights: FileAccessFlags, flags: FileOpenFlags) File; + extern fn oc_file_open_with_dialog(arena: *Arena, rights: FileAccessFlags, flags: FileOpenFlags, desc: *FileDialogDesc) FileOpenWithDialogResult; + pub const nil = oc_file_nil; pub const isNil = oc_file_is_nil; pub const open = oc_file_open; @@ -826,8 +1651,11 @@ const File = extern struct { pub const write = oc_file_write; pub const read = oc_file_read; - const getStatus = oc_file_get_status; - const size = oc_file_size; + pub const getStatus = oc_file_get_status; + pub const size = oc_file_size; + + pub const openWithRequest = oc_file_open_with_request; + pub const openWithDialog = oc_file_open_with_dialog; }; const FileOpenFlags = packed struct(u16) { @@ -967,18 +1795,6 @@ const FileStatus = extern struct { modification_date: DateStamp, }; -//------------------------------------------------------------------------------------------ -// [FILE IO] complete io queue api -//------------------------------------------------------------------------------------------ - -extern fn oc_io_wait_single_req(req: *IoReq) IoCmp; - -pub const ioWaitSingleReq = oc_io_wait_single_req; - -//------------------------------------------------------------------------------------------ -// [FILE IO] Asking users for file capabilities -//------------------------------------------------------------------------------------------ - const FileOpenWithDialogElt = extern struct { list_elt: ListElt, file: File, @@ -990,5 +1806,10 @@ const FileOpenWithDialogResult = extern struct { selection: List, }; -extern fn oc_file_open_with_request(path: Str8, rights: FileAccessFlags, flags: FileOpenFlags) File; -extern fn oc_file_open_with_dialog(arena: *Arena, rights: FileAccessFlags, flags: FileOpenFlags, desc: *FileDialogDesc) FileOpenWithDialogResult; +//------------------------------------------------------------------------------------------ +// [FILE IO] complete io queue api +//------------------------------------------------------------------------------------------ + +extern fn oc_io_wait_single_req(req: *IoReq) IoCmp; + +pub const ioWaitSingleReq = oc_io_wait_single_req;