2019 lines
69 KiB
Zig
2019 lines
69 KiB
Zig
const std = @import("std");
|
|
const AllocError = std.mem.Allocator.Error;
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
// [PLATFORM]
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
pub const Platform = enum(c_uint) {
|
|
MacOS,
|
|
Windows,
|
|
};
|
|
|
|
extern fn oc_get_host_platform() Platform;
|
|
pub const getHostPlatform = oc_get_host_platform;
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
// [DEBUG] Logging
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
pub const log = struct {
|
|
pub const Level = enum(c_uint) {
|
|
Error,
|
|
Warning,
|
|
Info,
|
|
};
|
|
|
|
pub const Output = opaque {
|
|
extern var OC_LOG_DEFAULT_OUTPUT: ?*Output;
|
|
extern fn oc_log_set_output(output: *Output) void;
|
|
|
|
pub inline fn default() ?*Output {
|
|
return OC_LOG_DEFAULT_OUTPUT;
|
|
}
|
|
|
|
const set = oc_log_set_output;
|
|
};
|
|
|
|
extern fn oc_log_set_level(level: Level) void;
|
|
extern fn oc_log_ext(level: Level, function: [*]const u8, file: [*]const u8, line: c_int, fmt: [*]const u8, ...) void;
|
|
|
|
const setLevel = oc_log_set_level;
|
|
|
|
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) {
|
|
var format_buf: [512:0]u8 = undefined;
|
|
_ = std.fmt.bufPrintZ(&format_buf, fmt, args) catch 0;
|
|
var line: c_int = @intCast(source.line);
|
|
|
|
oc_assert_fail(source.file.ptr, source.fn_name.ptr, line, "assertion failed", format_buf[0..].ptr);
|
|
}
|
|
}
|
|
|
|
pub fn abort(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;
|
|
var line: c_int = @intCast(source.line);
|
|
|
|
oc_abort_ext(source.file.ptr, source.fn_name.ptr, line, format_buf[0..].ptr);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
// [INTRUSIVE LIST]
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
pub const ListElt = extern struct {
|
|
prev: ?*ListElt,
|
|
next: ?*ListElt,
|
|
|
|
pub fn entry(self: *ListElt, comptime ParentType: type, comptime field_name_in_parent: []const u8) *ParentType {
|
|
return @fieldParentPtr(ParentType, field_name_in_parent, self);
|
|
}
|
|
|
|
pub fn nextEntry(comptime ParentType: type, comptime field_name_in_parent: []const u8, elt_parent: *ParentType) ?*ParentType {
|
|
const elt: ?*ListElt = @field(elt_parent, field_name_in_parent);
|
|
if (elt.next) |next| {
|
|
return next.entry(ParentType, field_name_in_parent);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
pub fn prevEntry(comptime ParentType: type, comptime field_name_in_parent: []const u8, elt_parent: *ParentType) ?*ParentType {
|
|
const elt: ?*ListElt = @field(elt_parent, field_name_in_parent);
|
|
if (elt.prev) |prev| {
|
|
return prev.entry(ParentType, field_name_in_parent);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
};
|
|
|
|
pub const List = extern struct {
|
|
first: ?*ListElt,
|
|
last: ?*ListElt,
|
|
|
|
pub fn init() List {
|
|
return .{
|
|
.first = null,
|
|
.last = null,
|
|
};
|
|
}
|
|
|
|
pub fn firstEntry(self: *List, comptime EltParentType: type, comptime field_name_in_parent: []const u8) ?*EltParentType {
|
|
if (self.first) |elt| {
|
|
return elt.entry(EltParentType, field_name_in_parent);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
pub fn lastEntry(self: *List, comptime EltParentType: type, comptime field_name_in_parent: []const u8) ?*EltParentType {
|
|
if (self.last) |elt| {
|
|
return elt.entry(EltParentType, field_name_in_parent);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
const IterDirection = enum {
|
|
Forward,
|
|
Backward,
|
|
};
|
|
|
|
pub fn makeIter(comptime direction: IterDirection, comptime EltParentType: type, comptime field_name_in_parent: []const u8) type {
|
|
return struct {
|
|
const Self = @This();
|
|
|
|
item: ?*ListElt,
|
|
|
|
pub fn next(self: *Self) ?*EltParentType {
|
|
if (self.item) |elt| {
|
|
var entry: *EltParentType = elt.entry(EltParentType, field_name_in_parent);
|
|
self.item = if (direction == .Forward) elt.next else elt.prev;
|
|
return entry;
|
|
}
|
|
return null;
|
|
}
|
|
};
|
|
}
|
|
|
|
pub fn iter(self: *const List, comptime EltParentType: type, comptime field_name_in_parent: []const u8) makeIter(.Forward, EltParentType, field_name_in_parent) {
|
|
const Iter = makeIter(.Forward, EltParentType, field_name_in_parent);
|
|
return Iter{
|
|
.item = self.first,
|
|
};
|
|
}
|
|
|
|
pub fn iterReverse(self: *const List, comptime EltParentType: type, comptime field_name_in_parent: []const u8) makeIter(.Backward, EltParentType, field_name_in_parent) {
|
|
const Iter = makeIter(.Backward, EltParentType, field_name_in_parent);
|
|
return Iter{
|
|
.item = self.last,
|
|
};
|
|
}
|
|
|
|
pub fn insert(self: *List, after_elt: ?*ListElt, elt: *ListElt) void {
|
|
elt.prev = after_elt;
|
|
elt.next = after_elt.next;
|
|
if (after_elt.next) |elt_next| {
|
|
after_elt.next.prev = elt_next;
|
|
} else {
|
|
self.last = elt;
|
|
}
|
|
after_elt.next = elt;
|
|
}
|
|
|
|
pub fn insertBefore(self: *List, before_elt: ?*ListElt, elt: *ListElt) void {
|
|
elt.next = before_elt;
|
|
elt.prev = before_elt.prev;
|
|
if (before_elt.prev) |elt_prev| {
|
|
before_elt.prev.next = elt_prev;
|
|
} else {
|
|
self.first = elt;
|
|
}
|
|
before_elt.prev = elt;
|
|
}
|
|
|
|
pub fn remove(self: *List, elt: *ListElt) void {
|
|
if (elt.prev != null) {
|
|
elt.prev.next = elt.next;
|
|
} else {
|
|
self.first = elt.next;
|
|
}
|
|
if (elt.next != null) {
|
|
elt.next.prev = elt.prev;
|
|
} else {
|
|
self.last = elt.prev;
|
|
}
|
|
elt.prev = blk: {
|
|
const tmp = null;
|
|
elt.next = tmp;
|
|
break :blk tmp;
|
|
};
|
|
}
|
|
|
|
pub fn push(self: *List, elt: *ListElt) void {
|
|
elt.next = self.first;
|
|
elt.prev = null;
|
|
if (self.first) |elt_first| {
|
|
elt_first.prev = elt;
|
|
} else {
|
|
self.last = elt;
|
|
}
|
|
self.first = elt;
|
|
}
|
|
|
|
pub fn pop(self: *List) ?*ListElt {
|
|
if (self.first) |elt_begin| {
|
|
remove(self, elt_begin);
|
|
return elt_begin;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
pub fn popEntry(self: *List, comptime EltParentType: type, comptime field_name_in_parent: []const u8) ?*EltParentType {
|
|
if (self.pop()) |elt| {
|
|
return elt.entry(EltParentType, field_name_in_parent);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
pub fn pushBack(self: *List, elt: *ListElt) void {
|
|
elt.prev = self.last;
|
|
elt.next = null;
|
|
if (self.last) |last_elt| {
|
|
last_elt.next = elt;
|
|
} else {
|
|
self.first = elt;
|
|
}
|
|
self.last = elt;
|
|
}
|
|
|
|
pub fn popBack(self: *List) ?*ListElt {
|
|
if (self.last) |last_elt| {
|
|
remove(self, last_elt);
|
|
return last_elt;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
pub fn empty(self: *const List) bool {
|
|
return (self.first == null) or (self.last == null);
|
|
}
|
|
};
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
// [MEMORY]
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
pub const BaseAllocator = extern struct {
|
|
const MemReserveFunction = *const fn (context: *BaseAllocator, size: u64) ?[*]u8;
|
|
const MemModifyFunction = *const fn (context: *BaseAllocator, ptr: ?[*]u8, size: u64) ?[*]u8;
|
|
|
|
func_reserve: MemReserveFunction,
|
|
func_commit: MemModifyFunction,
|
|
func_decommit: MemModifyFunction,
|
|
func_release: MemModifyFunction,
|
|
|
|
extern fn oc_base_allocator_default() *BaseAllocator;
|
|
pub const default = oc_base_allocator_default;
|
|
};
|
|
|
|
pub const ArenaChunk = extern struct {
|
|
list_elt: ListElt,
|
|
ptr: ?[*]u8,
|
|
offset: u64,
|
|
committed: u64,
|
|
cap: u64,
|
|
};
|
|
|
|
pub const ArenaScope = extern struct {
|
|
arena: *Arena,
|
|
chunk: *ArenaChunk,
|
|
offset: u64,
|
|
|
|
extern fn oc_arena_scope_end(scope: ArenaScope) void;
|
|
pub const end = oc_arena_scope_end;
|
|
};
|
|
|
|
pub const ArenaOptions = extern struct {
|
|
base: ?*BaseAllocator,
|
|
reserve: u64,
|
|
};
|
|
|
|
pub const Arena = extern struct {
|
|
base: ?*BaseAllocator,
|
|
chunks: List,
|
|
current_chunk: ?*ArenaChunk,
|
|
|
|
extern fn oc_arena_init(arena: *Arena) void;
|
|
extern fn oc_arena_init_with_options(arena: *Arena, options: *ArenaOptions) void;
|
|
extern fn oc_arena_cleanup(arena: *Arena) void;
|
|
extern fn oc_arena_push(arena: *Arena, size: u64) ?[*]u8;
|
|
extern fn oc_arena_push_aligned(arena: *Arena, size: u64, alignment: u32) ?[*]u8;
|
|
extern fn oc_arena_clear(arena: *Arena) void;
|
|
extern fn oc_arena_scope_begin(arena: *Arena) ArenaScope;
|
|
|
|
extern fn oc_scratch_next(used: *Arena) *Arena;
|
|
extern fn oc_scratch_begin() ArenaScope;
|
|
extern fn oc_scratch_begin_next(used: *Arena) ArenaScope;
|
|
|
|
pub fn init() Arena {
|
|
var arena: Arena = undefined;
|
|
oc_arena_init(&arena);
|
|
return arena;
|
|
}
|
|
pub fn initWithOptions(opts: ArenaOptions) Arena {
|
|
var arena: Arena = undefined;
|
|
oc_arena_init(&arena, &opts);
|
|
return arena;
|
|
}
|
|
pub const deinit = oc_arena_cleanup;
|
|
|
|
pub const clear = oc_arena_clear;
|
|
pub const scopeBegin = oc_arena_scope_begin;
|
|
|
|
pub fn push(arena: *Arena, size: usize) AllocError![]u8 {
|
|
return arena.pushAligned(size, 1);
|
|
}
|
|
|
|
pub fn pushAligned(arena: *Arena, size: usize, alignment: u32) AllocError![]u8 {
|
|
if (oc_arena_push_aligned(arena, size, alignment)) |mem| {
|
|
return mem[0..size];
|
|
}
|
|
return AllocError.OutOfMemory;
|
|
}
|
|
|
|
pub fn pushType(arena: *Arena, comptime T: type) AllocError!*T {
|
|
var mem: []u8 = try arena.pushAligned(@sizeOf(T), @alignOf(T));
|
|
assert(mem.len >= @sizeOf(T), "need at least {} bytes, but got {}", .{ mem.len, @sizeOf(T) }, @src());
|
|
var p: *T = @alignCast(@ptrCast(mem.ptr));
|
|
return p;
|
|
}
|
|
|
|
pub fn pushArray(arena: *Arena, comptime T: type, count: usize) AllocError![]T {
|
|
var mem: []u8 = try arena.pushAligned(@sizeOf(T) * count, @alignOf(T));
|
|
std.debug.assert(mem.len >= @sizeOf(T) * count);
|
|
var items: [*]T = @alignCast(@ptrCast(mem.ptr));
|
|
return items[0..count];
|
|
}
|
|
|
|
pub const scratchNext = oc_scratch_next;
|
|
pub const scratchBegin = oc_scratch_begin;
|
|
pub const scratchBeginNext = oc_scratch_begin_next;
|
|
};
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
// [STRINGS] u8 strings
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
fn stringType(comptime CharType: type) type {
|
|
return extern struct {
|
|
pub const StrListElt = extern struct {
|
|
list_elt: ListElt,
|
|
string: Str,
|
|
};
|
|
|
|
pub const StrList = extern struct {
|
|
list: List,
|
|
elt_count: u64,
|
|
len: u64,
|
|
|
|
pub fn init() StrList {
|
|
return .{
|
|
.list = List.init(),
|
|
.elt_count = 0,
|
|
.len = 0,
|
|
};
|
|
}
|
|
|
|
pub fn push(list: *StrList, arena: *Arena, str: Str) AllocError!void {
|
|
var elt: *StrListElt = try arena.pushType(StrListElt);
|
|
elt.string = str;
|
|
list.list.pushBack(&elt.list_elt);
|
|
list.elt_count += 1;
|
|
list.len += str.len;
|
|
}
|
|
|
|
pub fn pushSlice(list: *StrList, arena: *Arena, str: []const CharType) AllocError!void {
|
|
try list.push(arena, Str.fromSlice(str));
|
|
}
|
|
|
|
pub fn pushf(list: *StrList, arena: *Arena, comptime format: []const u8, args: anytype) AllocError!void {
|
|
var str = try Str.pushf(arena, format, args);
|
|
try list.push(arena, str);
|
|
}
|
|
|
|
pub fn iter(list: *const StrList) List.makeIter(.Forward, StrListElt, "list_elt") {
|
|
return list.list.iter(StrListElt, "list_elt");
|
|
}
|
|
|
|
pub fn iterReverse(list: *const StrList) List.makeIter(.Backward, StrListElt, "list_elt") {
|
|
return list.list.iterReverse(StrListElt, "list_elt");
|
|
}
|
|
|
|
pub fn find(list: *const StrList, needle: *const Str) ?*StrListElt {
|
|
return list.findSlice(needle.slice());
|
|
}
|
|
|
|
pub fn findSlice(list: *const StrList, needle: []const CharType) ?*StrListElt {
|
|
var iterator = list.iter();
|
|
while (iterator.next()) |elt_string| {
|
|
if (std.mem.eql(CharType, elt_string.string.slice(), needle)) {
|
|
return elt_string;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
pub fn contains(list: *const StrList, needle: *const Str) bool {
|
|
return list.findSlice(needle.slice()) != null;
|
|
}
|
|
|
|
pub fn containsSlice(list: *const StrList, needle: []const CharType) bool {
|
|
return list.findSlice(needle) != null;
|
|
}
|
|
|
|
pub fn join(list: *const StrList, arena: *Arena) AllocError!Str {
|
|
const empty = Str{ .ptr = null, .len = 0 };
|
|
return try list.collate(arena, empty, empty, empty);
|
|
}
|
|
|
|
pub fn collate(list: *const StrList, arena: *Arena, prefix: Str, separator: Str, postfix: Str) AllocError!Str {
|
|
var str: Str = undefined;
|
|
str.len = @intCast(prefix.len + list.len + (list.elt_count - 1) * separator.len + postfix.len);
|
|
str.ptr = (try arena.pushArray(CharType, str.len + 1)).ptr;
|
|
@memcpy(str.ptr.?[0..prefix.len], prefix.slice());
|
|
|
|
var offset = prefix.len;
|
|
|
|
var iterator = list.iter();
|
|
var index: usize = 0;
|
|
while (iterator.next()) |list_str| {
|
|
if (index > 0) {
|
|
@memcpy(str.ptr.?[offset .. offset + separator.len], separator.slice());
|
|
offset += separator.len;
|
|
}
|
|
@memcpy(str.ptr.?[offset .. offset + list_str.string.len], list_str.string.slice());
|
|
offset += list_str.string.len;
|
|
index += 1;
|
|
}
|
|
|
|
@memcpy(str.ptr.?[offset .. offset + postfix.len], postfix.slice());
|
|
str.ptr.?[str.len] = 0;
|
|
return str;
|
|
}
|
|
};
|
|
|
|
const Str = @This();
|
|
|
|
ptr: ?[*]CharType,
|
|
len: usize,
|
|
|
|
extern fn strncmp(a: ?[*]u8, b: ?[*]u8, len: usize) c_int;
|
|
|
|
pub fn fromSlice(str: []const CharType) Str {
|
|
return .{
|
|
.ptr = @constCast(str.ptr),
|
|
.len = str.len,
|
|
};
|
|
}
|
|
|
|
pub fn slice(str: *const Str) []CharType {
|
|
if (str.ptr) |p| {
|
|
return p[0..str.len];
|
|
}
|
|
|
|
return &[_]CharType{};
|
|
}
|
|
|
|
pub fn sliceInner(str: *const Str, start: u64, end: u64) []CharType {
|
|
if (str.ptr) |p| {
|
|
assert(start <= end, "{}.sliceLen: start <= end", .{typename()}, @src());
|
|
assert(end <= str.len, "{}.sliceLen: end <= str.len", .{typename()}, @src());
|
|
return p[start..end];
|
|
}
|
|
|
|
return &[_]CharType{};
|
|
}
|
|
|
|
pub fn fromBuffer(len: u64, buffer: ?[]CharType) Str {
|
|
return .{
|
|
.ptr = buffer,
|
|
.len = @intCast(len),
|
|
};
|
|
}
|
|
|
|
pub fn pushBuffer(arena: *Arena, buffer: []u8) Str {
|
|
var str: Str = undefined;
|
|
str.len = buffer.len;
|
|
str.ptr = arena.pushArray(CharType, buffer.len + 1);
|
|
@memcpy(str.ptr[0..buffer.len], buffer);
|
|
str.ptr[buffer.len] = 0;
|
|
return str;
|
|
}
|
|
|
|
pub fn pushCopy(str: *const Str, arena: *Arena) Str {
|
|
return pushBuffer(arena, str.ptr[0..str.len]);
|
|
}
|
|
|
|
pub fn pushSlice(str: *const Str, arena: *Arena, start: usize, end: usize) Str {
|
|
return pushBuffer(arena, str.ptr[start..end]);
|
|
}
|
|
|
|
pub fn pushf(arena: *Arena, comptime format: []const u8, args: anytype) AllocError!Str {
|
|
if (CharType != u8) {
|
|
@compileError("pushf() is only supported for Str8");
|
|
}
|
|
|
|
var str: Str = undefined;
|
|
str.len = @intCast(std.fmt.count(format, args));
|
|
str.ptr = (try arena.pushArray(CharType, str.len + 1)).ptr;
|
|
_ = std.fmt.bufPrintZ(str.ptr.?[0 .. str.len + 1], format, args) catch unreachable;
|
|
return str;
|
|
}
|
|
|
|
pub fn join(arena: *Arena, strings: []const []const CharType) AllocError!Str {
|
|
const empty = &[_]CharType{};
|
|
return collate(arena, strings, empty, empty, empty);
|
|
}
|
|
|
|
pub fn collate(
|
|
arena: *Arena,
|
|
strings: []const []const CharType,
|
|
prefix: []const CharType,
|
|
separator: []const CharType,
|
|
postfix: []const CharType,
|
|
) AllocError!Str {
|
|
var strings_total_len: usize = 0;
|
|
for (strings) |s| {
|
|
strings_total_len += s.len;
|
|
}
|
|
|
|
var str: Str = undefined;
|
|
str.len = prefix.len + strings_total_len + (strings.len - 1) * separator.len + postfix.len;
|
|
str.ptr = (try arena.pushArray(CharType, str.len + 1)).ptr;
|
|
@memcpy(str.ptr.?[0..prefix.len], prefix);
|
|
|
|
var offset = prefix.len;
|
|
|
|
for (strings, 0..) |list_str, index| {
|
|
if (index > 0) {
|
|
@memcpy(str.ptr.?[offset .. offset + separator.len], separator);
|
|
offset += separator.len;
|
|
}
|
|
@memcpy(str.ptr.?[offset .. offset + list_str.len], list_str);
|
|
offset += list_str.len;
|
|
}
|
|
|
|
@memcpy(str.ptr.?[offset .. offset + postfix.len], postfix);
|
|
offset += postfix.len;
|
|
str.ptr.?[str.len] = 0;
|
|
return str;
|
|
}
|
|
|
|
pub fn split(str: *const Str, arena: *Arena, separators: StrList) AllocError!StrList {
|
|
var list = StrList.init();
|
|
if (str.ptr == null) {
|
|
return list;
|
|
}
|
|
|
|
const ptr = str.ptr.?;
|
|
|
|
var offset: usize = 0;
|
|
var offset_substring: usize = 0;
|
|
|
|
while (offset < str.len) {
|
|
const haystack = ptr[offset..str.len];
|
|
var separator_iter = separators.iter();
|
|
while (separator_iter.next()) |list_sep| {
|
|
if (std.mem.startsWith(CharType, haystack, list_sep.string.slice()) and list_sep.string.len > 0) {
|
|
var substr = ptr[offset_substring..offset];
|
|
if (separators.containsSlice(substr)) {
|
|
substr = ptr[offset..offset];
|
|
}
|
|
try list.pushSlice(arena, substr);
|
|
|
|
// -1 / +1 to account for offset += 1 at the end of the loop
|
|
offset += list_sep.string.len - 1;
|
|
offset_substring = offset + 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
offset += 1;
|
|
}
|
|
|
|
if (offset_substring != offset) {
|
|
var substr = ptr[offset_substring..offset];
|
|
try list.pushSlice(arena, substr);
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
pub fn cmp(a: *const Str, b: *const Str) 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));
|
|
if (value < 0) {
|
|
return .lt;
|
|
} else if (value == 0) {
|
|
return .eq;
|
|
} else {
|
|
return .gt;
|
|
}
|
|
}
|
|
|
|
fn typename() []const u8 {
|
|
return switch (CharType) {
|
|
u8 => "Str8",
|
|
u16 => "Str16",
|
|
u32 => "Str32",
|
|
else => unreachable,
|
|
};
|
|
}
|
|
};
|
|
}
|
|
|
|
pub const Str8 = stringType(u8);
|
|
pub const Str16 = stringType(u16);
|
|
pub const Str32 = stringType(u32);
|
|
|
|
pub const Str8ListElt = Str8.StrListElt;
|
|
pub const Str16ListElt = Str16.StrListElt;
|
|
pub const Str32ListElt = Str32.StrListElt;
|
|
|
|
pub const Str8List = Str8.StrList;
|
|
pub const Str16List = Str16.StrList;
|
|
pub const Str32List = Str32.StrList;
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
// [UTF8]
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
pub const Utf32 = u32;
|
|
|
|
pub const Utf8Dec = extern struct {
|
|
code_point: Utf32, // decoded codepoint
|
|
size: u32, // size of corresponding oc_utf8 sequence
|
|
};
|
|
|
|
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(code_point: Utf32) u32;
|
|
extern fn oc_utf8_codepoint_count_for_string(string: Str8) 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;
|
|
|
|
pub const sizeFromLeadingChar = oc_utf8_size_from_leading_char;
|
|
pub const codepointSize = oc_utf8_codepoint_size;
|
|
pub const codepointCountForString = oc_utf8_codepoint_count_for_string;
|
|
pub const byteCountForCodepoints = oc_utf8_byte_count_for_codepoints;
|
|
pub const nextOffset = oc_utf8_next_offset;
|
|
pub const prevOffset = oc_utf8_prev_offset;
|
|
|
|
// 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, 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, 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, code_points: Str32) Str8;
|
|
|
|
pub const decode = oc_utf8_decode;
|
|
pub const decodeAt = oc_utf8_decode_at;
|
|
pub const encode = oc_utf8_encode;
|
|
pub const toCodepoints = oc_utf8_to_codepoints;
|
|
pub const fromCodepoints = oc_utf8_from_codepoints;
|
|
pub const pushToCodepoints = oc_utf8_push_to_codepoints;
|
|
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]
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
extern fn oc_request_quit() void;
|
|
pub const requestQuit = oc_request_quit;
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
// [APP] input
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
const MouseCursor = enum(c_uint) {
|
|
Arrow,
|
|
Resize0,
|
|
Resize90,
|
|
Resize45,
|
|
Resize135,
|
|
Text,
|
|
};
|
|
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 = 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 = 0x00,
|
|
Right = 0x01,
|
|
Middle = 0x02,
|
|
Ext1 = 0x03,
|
|
Ext2 = 0x04,
|
|
};
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
// [APP] windows
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
extern fn oc_window_set_title(title: Str8) void;
|
|
extern fn oc_window_set_size(size: Vec2) void;
|
|
|
|
pub fn windowSetTitle(title: []const u8) void {
|
|
oc_window_set_title(Str8.fromSlice(title));
|
|
}
|
|
|
|
pub const windowSetSize = oc_window_set_size;
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
// [CLOCK]
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
pub const clock = struct {
|
|
pub const Kind = enum(c_uint) {
|
|
Monotonic,
|
|
Uptime,
|
|
Date,
|
|
};
|
|
|
|
extern fn oc_clock_time(clock: Kind) f64;
|
|
pub const time = 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 stack
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
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
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
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;
|
|
extern fn oc_surface_present(surface: Surface) void;
|
|
extern fn oc_surface_get_size(surface: Surface) Vec2;
|
|
extern fn oc_surface_contents_scaling(surface: Surface) Vec2;
|
|
extern fn oc_surface_bring_to_front(surface: Surface) void;
|
|
extern fn oc_surface_send_to_back(surface: Surface) void;
|
|
// TODO
|
|
// extern fn oc_surface_render_commands(
|
|
// surface: Surface,
|
|
// color: Color,
|
|
// primitive_count: u32,
|
|
// primitives: [*]Primitive,
|
|
// elt_count: u32,
|
|
// elements: [*]PathElt,
|
|
// ) 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;
|
|
pub const present = oc_surface_present;
|
|
pub const getSize = oc_surface_get_size;
|
|
pub const contentsScaling = oc_surface_contents_scaling;
|
|
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 Image = extern struct {
|
|
h: u64,
|
|
|
|
extern fn oc_image_nil() 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;
|
|
pub const draw = oc_image_draw;
|
|
pub const drawRegion = oc_image_draw_region;
|
|
};
|
|
|
|
pub const Rect = extern union {
|
|
Flat: extern struct {
|
|
x: f32,
|
|
y: f32,
|
|
w: f32,
|
|
h: f32,
|
|
},
|
|
Pairs: extern struct {
|
|
xy: Vec2,
|
|
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 {
|
|
Flat: extern struct {
|
|
r: f32,
|
|
g: f32,
|
|
b: f32,
|
|
a: f32,
|
|
},
|
|
Array: [4]f32,
|
|
};
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
// [GRAPHICS]: Canvas
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
pub const Canvas = extern struct {
|
|
h: u64,
|
|
|
|
extern fn oc_canvas_nil() Canvas;
|
|
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_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 select = oc_canvas_select;
|
|
pub const render = oc_render;
|
|
|
|
// vector graphics
|
|
|
|
extern fn oc_clear() void;
|
|
extern fn oc_fill() void;
|
|
extern fn oc_stroke() void;
|
|
|
|
pub const clear = oc_clear;
|
|
pub const fill = oc_fill;
|
|
pub const stroke = oc_stroke;
|
|
|
|
// attributes setting/getting
|
|
|
|
extern fn oc_set_color(color: Color) void;
|
|
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(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;
|
|
extern fn oc_set_text_flip(flip: bool) void;
|
|
extern fn oc_set_image(image: Image) void;
|
|
extern fn oc_set_image_source_region(region: Rect) void;
|
|
|
|
extern fn oc_get_color() Color;
|
|
extern fn oc_get_width() f32;
|
|
extern fn oc_get_tolerance() f32;
|
|
extern fn oc_get_joint() JointType;
|
|
extern fn oc_get_max_joint_excursion() f32;
|
|
extern fn oc_get_cap() CapType;
|
|
extern fn oc_get_font() Font;
|
|
extern fn oc_get_font_size() f32;
|
|
extern fn oc_get_text_flip() bool;
|
|
extern fn oc_get_image() Image;
|
|
extern fn oc_get_image_source_region() Rect;
|
|
|
|
pub const setColor = oc_set_color;
|
|
pub const setColorRgba = oc_set_color_rgba;
|
|
pub const setWidth = oc_set_width;
|
|
pub const setTolerance = oc_set_tolerance;
|
|
pub const setJoint = oc_set_joint;
|
|
pub const setMaxJointExcursion = oc_set_max_joint_excursion;
|
|
pub const setCap = oc_set_cap;
|
|
pub const setFont = oc_set_font;
|
|
pub const setFontSize = oc_set_font_size;
|
|
pub const setTextFlip = oc_set_text_flip;
|
|
pub const setImage = oc_set_image;
|
|
pub const setImageSourceRegion = oc_set_image_source_region;
|
|
|
|
pub const getColor = oc_get_color;
|
|
pub const getWidth = oc_get_width;
|
|
pub const getTolerance = oc_get_tolerance;
|
|
pub const getJoint = oc_get_joint;
|
|
pub const getMaxJointExcursion = oc_get_max_joint_excursion;
|
|
pub const getCap = oc_get_cap;
|
|
pub const getFont = oc_get_font;
|
|
pub const getFontSize = oc_get_font_size;
|
|
pub const getTextFlip = oc_get_text_flip;
|
|
pub const getImage = oc_get_image;
|
|
pub const getImageSourceRegion = oc_get_image_source_region;
|
|
|
|
// path construction
|
|
|
|
extern fn oc_get_position() Vec2;
|
|
extern fn oc_move_to(x: f32, y: f32) void;
|
|
extern fn oc_line_to(x: f32, y: f32) void;
|
|
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(glyph_indices: Str32) Rect;
|
|
extern fn oc_codepoints_outlines(string: Str32) void;
|
|
extern fn oc_text_outlines(string: Str8) void;
|
|
|
|
pub const getPosition = oc_get_position;
|
|
pub const moveTo = oc_move_to;
|
|
pub const lineTo = oc_line_to;
|
|
pub const quadraticTo = oc_quadratic_to;
|
|
pub const cubicTo = oc_cubic_to;
|
|
pub const closePath = oc_close_path;
|
|
|
|
pub const glyphOutlines = oc_glyph_outlines;
|
|
pub const codepointsOutlines = oc_codepoints_outlines;
|
|
pub const textOutlines = oc_text_outlines;
|
|
|
|
// shape helpers
|
|
|
|
extern fn oc_rectangle_fill(x: f32, y: f32, w: f32, h: f32) void;
|
|
extern fn oc_rectangle_stroke(x: f32, y: f32, w: f32, h: f32) void;
|
|
extern fn oc_rounded_rectangle_fill(x: f32, y: f32, w: f32, h: f32, r: f32) void;
|
|
extern fn oc_rounded_rectangle_stroke(x: f32, y: f32, w: f32, h: f32, r: f32) void;
|
|
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, arc_angle: f32, start_angle: f32) void;
|
|
|
|
pub const rectangleFill = oc_rectangle_fill;
|
|
pub const rectangleStroke = oc_rectangle_stroke;
|
|
pub const roundedRectangleFill = oc_rounded_rectangle_fill;
|
|
pub const roundedRectangleStroke = oc_rounded_rectangle_stroke;
|
|
pub const ellipseFill = oc_ellipse_fill;
|
|
pub const ellipseStroke = oc_ellipse_stroke;
|
|
pub const circleFill = oc_circle_fill;
|
|
pub const circleStroke = oc_circle_stroke;
|
|
pub const arc = oc_arc;
|
|
};
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
// [GRAPHICS]: GLES
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
// TODO
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
// [UI]
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
// TODO
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
// [FILE IO] basic API
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
const File = extern struct {
|
|
h: u64,
|
|
|
|
extern fn oc_file_nil() File;
|
|
extern fn oc_file_is_nil(file: File) bool;
|
|
extern fn oc_file_open(path: Str8, rights: FileAccessFlags, flags: FileOpenFlags) File;
|
|
extern fn oc_file_open_at(dir: File, path: Str8, rights: FileAccessFlags, flags: FileOpenFlags) File;
|
|
extern fn oc_file_close(file: File) void;
|
|
extern fn oc_file_last_error(file: File) IoError;
|
|
extern fn oc_file_pos(file: File) i64;
|
|
extern fn oc_file_seek(file: File, offset: i64, whence: FileWhence) i64;
|
|
extern fn oc_file_write(file: File, size: u64, buffer: ?[*]u8) u64;
|
|
extern fn oc_file_read(file: File, size: u64, buffer: ?[*]u8) u64;
|
|
|
|
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;
|
|
pub const openAt = oc_file_open_at;
|
|
pub const close = oc_file_close;
|
|
pub const lastError = oc_file_last_error;
|
|
pub const pos = oc_file_pos;
|
|
pub const seek = oc_file_seek;
|
|
pub const write = oc_file_write;
|
|
pub const read = oc_file_read;
|
|
|
|
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) {
|
|
none: bool,
|
|
append: bool,
|
|
truncate: bool,
|
|
create: bool,
|
|
|
|
symlink: bool,
|
|
no_follow: bool,
|
|
restrict: bool,
|
|
};
|
|
|
|
const FileAccessFlags = packed struct(u16) {
|
|
none: bool,
|
|
read: bool,
|
|
write: bool,
|
|
};
|
|
|
|
const FileWhence = enum(c_uint) {
|
|
Set,
|
|
End,
|
|
Current,
|
|
};
|
|
|
|
const IoReqId = u16;
|
|
const IoOp = u32;
|
|
|
|
const IoOpEnum = enum(c_uint) {
|
|
OpenAt = 0,
|
|
Close,
|
|
FStat,
|
|
Seek,
|
|
Read,
|
|
Write,
|
|
Error,
|
|
};
|
|
|
|
const IoReq = extern struct {
|
|
id: IoReqId,
|
|
op: IoOp,
|
|
handle: File,
|
|
|
|
offset: i64,
|
|
size: u64,
|
|
|
|
buffer: extern union {
|
|
data: ?[*]u8,
|
|
unused: u64, // This is a horrible hack to get the same layout on wasm and on host
|
|
},
|
|
|
|
type: extern union {
|
|
open: extern struct {
|
|
rights: FileAccessFlags,
|
|
flags: FileOpenFlags,
|
|
},
|
|
whence: FileWhence,
|
|
},
|
|
};
|
|
|
|
const IoError = enum(i32) {
|
|
Ok = 0,
|
|
Unknown,
|
|
Op, // unsupported operation
|
|
Handle, // invalid handle
|
|
Prev, // previously had a fatal error (last error stored on handle)
|
|
Arg, // invalid argument or argument combination
|
|
Perm, // access denied
|
|
Space, // no space left
|
|
NoEntry, // file or directory does not exist
|
|
Exists, // file already exists
|
|
NotDir, // path element is not a directory
|
|
Dir, // attempted to write directory
|
|
MaxFiles, // max open files reached
|
|
MaxLinks, // too many symbolic links in path
|
|
PathLength, // path too long
|
|
FileSize, // file too big
|
|
Overflow, // offset too big
|
|
NotReady, // no data ready to be read/written
|
|
Mem, // failed to allocate memory
|
|
Interrupt, // operation interrupted by a signal
|
|
Physical, // physical IO error
|
|
NoDevice, // device not found
|
|
Walkout, // attempted to walk out of root directory
|
|
};
|
|
|
|
const IoCmp = extern struct {
|
|
id: IoReqId,
|
|
err: IoError,
|
|
data: extern union {
|
|
result: i64,
|
|
size: u64,
|
|
offset: i64,
|
|
handle: File,
|
|
},
|
|
};
|
|
|
|
const FileType = enum(c_uint) {
|
|
Unknown,
|
|
Regular,
|
|
Directory,
|
|
Symlink,
|
|
Block,
|
|
Character,
|
|
Fifo,
|
|
Socket,
|
|
};
|
|
|
|
const FilePerm = packed struct(u16) {
|
|
other_exec: bool,
|
|
other_write: bool,
|
|
other_read: bool,
|
|
group_exec: bool,
|
|
group_write: bool,
|
|
group_read: bool,
|
|
owner_exec: bool,
|
|
owner_write: bool,
|
|
owner_read: bool,
|
|
sticky_bit: bool,
|
|
set_gid: bool,
|
|
set_uid: bool,
|
|
};
|
|
|
|
const DateStamp = extern struct {
|
|
seconds: i64, // seconds relative to NTP epoch.
|
|
fraction: u64, // fraction of seconds elapsed since the time specified by seconds.
|
|
};
|
|
|
|
const FileStatus = extern struct {
|
|
uid: u64,
|
|
type: FileType,
|
|
perm: FilePerm,
|
|
size: u64,
|
|
|
|
creation_date: DateStamp,
|
|
access_date: DateStamp,
|
|
modification_date: DateStamp,
|
|
};
|
|
|
|
const FileDialogKind = enum(c_uint) {
|
|
Save,
|
|
Open,
|
|
};
|
|
|
|
const FileDialogFlags = packed struct(u32) {
|
|
files: bool,
|
|
directories: bool,
|
|
multiple: bool,
|
|
create_directories: bool,
|
|
};
|
|
|
|
const FileDialogDesc = extern struct {
|
|
kind: FileDialogKind,
|
|
flags: FileDialogFlags,
|
|
title: Str8,
|
|
ok_label: Str8,
|
|
start_at: File,
|
|
start_path: Str8,
|
|
filters: Str8List,
|
|
};
|
|
|
|
const FileDialogButton = enum(c_uint) {
|
|
Cancel,
|
|
Ok,
|
|
};
|
|
|
|
const FileOpenWithDialogElt = extern struct {
|
|
list_elt: ListElt,
|
|
file: File,
|
|
};
|
|
|
|
const FileOpenWithDialogResult = extern struct {
|
|
button: FileDialogButton,
|
|
file: File,
|
|
selection: List,
|
|
};
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
// [FILE IO] complete io queue api
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
extern fn oc_io_wait_single_req(req: *IoReq) IoCmp;
|
|
|
|
pub const ioWaitSingleReq = oc_io_wait_single_req;
|