commit f0393aad5b2cd3b872d09793efcf74bdc446fd2b
parent 3ced436227108c9e41564dded5f9ef509c87331c
Author: Jack Mordaunt <jackmordaunt.dev@gmail.com>
Date: Sat, 25 Oct 2025 23:19:33 -0300
binding: add initial set of bindings
Diffstat:
34 files changed, 5730 insertions(+), 0 deletions(-)
diff --git a/binding/api-impl.odin b/binding/api-impl.odin
@@ -0,0 +1,15 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
diff --git a/binding/api.odin b/binding/api.odin
@@ -0,0 +1,376 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+BYTE_ORDER :: 1234
+
+//! \ingroup bl_globals
+//!
+//! Result code used by most Blend2D functions (32-bit unsigned integer).
+//!
+//! The \ref BLResultCode enumeration contains Blend2D result codes that contain Blend2D specific set of errors
+//! and an extended set of errors that can come from WIN32 or POSIX APIs. Since the success result code is zero
+//! it's recommended to use the following check to determine whether a call failed or not:
+//!
+//! ```
+//! BLResult result = do_something();
+//! if (result != BL_SUCCESS) {
+//! // `do_something()` failed...
+//! }
+//! ```
+Result :: u32
+
+//! \ingroup bl_globals
+//!
+//! Tag is a 32-bit integer consisting of 4 characters in the following format:
+//!
+//! ```
+//! tag = ((a << 24) | (b << 16) | (c << 8) | d)
+//! ```
+//!
+//! Tags are used extensively by OpenType fonts and other binary formats like PNG. In most cases TAGs should only
+//! contain ASCII letters, digits, and spaces.
+//!
+//! Blend2D uses \ref BLTag in public and internal APIs to distinguish between a regular `uint32_t` and tag.
+Tag :: u32
+
+//! \ingroup bl_globals
+//!
+//! Unique identifier that can be used for caching purposes.
+//!
+//! Some objects such as \ref BLImage and \ref BLFontFace have assigned an unique identifier that can be used to
+//! identify such objects for caching purposes. This identifier is never zero, so zero can be safely used as
+//! "uncached".
+//!
+//! \note Unique identifier is per-process. It's implemented as an increasing global or thread-local counter in
+//! a way that identifiers would not collide.
+UniqueId :: u64
+
+//! \ingroup bl_globals
+//!
+//! BLUnknown is `void` - it's used in places that accept pointer to \ref BLVarCore or any \ref BLObjectCore
+//! compatible object.
+Unknown :: struct {}
+
+//! \ingroup bl_globals
+//!
+//! A sink that can be used to debug various parts of Blend2D.
+DebugMessageSinkFunc :: proc "c" (message: cstring, size: c.size_t, user_data: rawptr)
+
+//! \ingroup bl_globals
+//!
+//! Blend2D result code.
+ResultCode :: enum u32 {
+ //! Successful result code.
+ SUCCESS = 0,
+ ERROR_START_INDEX = 65536,
+ ERROR_OUT_OF_MEMORY = 65536, //!< Out of memory [ENOMEM].
+ ERROR_INVALID_VALUE = 65537, //!< Invalid value/argument [EINVAL].
+ ERROR_INVALID_STATE = 65538, //!< Invalid state [EFAULT].
+ ERROR_INVALID_HANDLE = 65539, //!< Invalid handle or file. [EBADF].
+ ERROR_INVALID_CONVERSION = 65540, //!< Invalid conversion.
+ ERROR_OVERFLOW = 65541, //!< Overflow or value too large [EOVERFLOW].
+ ERROR_NOT_INITIALIZED = 65542, //!< Object not initialized.
+ ERROR_NOT_IMPLEMENTED = 65543, //!< Not implemented [ENOSYS].
+ ERROR_NOT_PERMITTED = 65544, //!< Operation not permitted [EPERM].
+ ERROR_IO = 65545, //!< IO error [EIO].
+ ERROR_BUSY = 65546, //!< Device or resource busy [EBUSY].
+ ERROR_INTERRUPTED = 65547, //!< Operation interrupted [EINTR].
+ ERROR_TRY_AGAIN = 65548, //!< Try again [EAGAIN].
+ ERROR_TIMED_OUT = 65549, //!< Timed out [ETIMEDOUT].
+ ERROR_BROKEN_PIPE = 65550, //!< Broken pipe [EPIPE].
+ ERROR_INVALID_SEEK = 65551, //!< File is not seekable [ESPIPE].
+ ERROR_SYMLINK_LOOP = 65552, //!< Too many levels of symlinks [ELOOP].
+ ERROR_FILE_TOO_LARGE = 65553, //!< File is too large [EFBIG].
+ ERROR_ALREADY_EXISTS = 65554, //!< File/directory already exists [EEXIST].
+ ERROR_ACCESS_DENIED = 65555, //!< Access denied [EACCES].
+ ERROR_MEDIA_CHANGED = 65556, //!< Media changed [Windows::ERROR_MEDIA_CHANGED].
+ ERROR_READ_ONLY_FS = 65557, //!< The file/FS is read-only [EROFS].
+ ERROR_NO_DEVICE = 65558, //!< Device doesn't exist [ENXIO].
+ ERROR_NO_ENTRY = 65559, //!< Not found, no entry (fs) [ENOENT].
+ ERROR_NO_MEDIA = 65560, //!< No media in drive/device [ENOMEDIUM].
+ ERROR_NO_MORE_DATA = 65561, //!< No more data / end of file [ENODATA].
+ ERROR_NO_MORE_FILES = 65562, //!< No more files [ENMFILE].
+ ERROR_NO_SPACE_LEFT = 65563, //!< No space left on device [ENOSPC].
+ ERROR_NOT_EMPTY = 65564, //!< Directory is not empty [ENOTEMPTY].
+ ERROR_NOT_FILE = 65565, //!< Not a file [EISDIR].
+ ERROR_NOT_DIRECTORY = 65566, //!< Not a directory [ENOTDIR].
+ ERROR_NOT_SAME_DEVICE = 65567, //!< Not same device [EXDEV].
+ ERROR_NOT_BLOCK_DEVICE = 65568, //!< Not a block device [ENOTBLK].
+ ERROR_INVALID_FILE_NAME = 65569, //!< File/path name is invalid [n/a].
+ ERROR_FILE_NAME_TOO_LONG = 65570, //!< File/path name is too long [ENAMETOOLONG].
+ ERROR_TOO_MANY_OPEN_FILES = 65571, //!< Too many open files [EMFILE].
+ ERROR_TOO_MANY_OPEN_FILES_BY_OS = 65572, //!< Too many open files by OS [ENFILE].
+ ERROR_TOO_MANY_LINKS = 65573, //!< Too many symbolic links on FS [EMLINK].
+ ERROR_TOO_MANY_THREADS = 65574, //!< Too many threads [EAGAIN].
+ ERROR_THREAD_POOL_EXHAUSTED = 65575, //!< Thread pool is exhausted and couldn't acquire the requested thread count.
+ ERROR_FILE_EMPTY = 65576, //!< File is empty (not specific to any OS error).
+ ERROR_OPEN_FAILED = 65577, //!< File open failed [Windows::ERROR_OPEN_FAILED].
+ ERROR_NOT_ROOT_DEVICE = 65578, //!< Not a root device/directory [Windows::ERROR_DIR_NOT_ROOT].
+ ERROR_UNKNOWN_SYSTEM_ERROR = 65579, //!< Unknown system error that failed to translate to Blend2D result code.
+ ERROR_INVALID_ALIGNMENT = 65580, //!< Invalid data alignment.
+ ERROR_INVALID_SIGNATURE = 65581, //!< Invalid data signature or header.
+ ERROR_INVALID_DATA = 65582, //!< Invalid or corrupted data.
+ ERROR_INVALID_STRING = 65583, //!< Invalid string (invalid data of either UTF8, UTF16, or UTF32).
+ ERROR_INVALID_KEY = 65584, //!< Invalid key or property.
+ ERROR_DATA_TRUNCATED = 65585, //!< Truncated data (more data required than memory/stream provides).
+ ERROR_DATA_TOO_LARGE = 65586, //!< Input data too large to be processed.
+ ERROR_DECOMPRESSION_FAILED = 65587, //!< Decompression failed due to invalid data (RLE, Huffman, etc).
+ ERROR_INVALID_GEOMETRY = 65588, //!< Invalid geometry (invalid path data or shape).
+ ERROR_NO_MATCHING_VERTEX = 65589, //!< Returned when there is no matching vertex in path data.
+ ERROR_INVALID_CREATE_FLAGS = 65590, //!< Invalid create flags (BLContext).
+ ERROR_NO_MATCHING_COOKIE = 65591, //!< No matching cookie (BLContext).
+ ERROR_NO_STATES_TO_RESTORE = 65592, //!< No states to restore (BLContext).
+ ERROR_TOO_MANY_SAVED_STATES = 65593, //!< Cannot save state as the number of saved states reached the limit (BLContext).
+ ERROR_IMAGE_TOO_LARGE = 65594, //!< The size of the image is too large.
+ ERROR_IMAGE_NO_MATCHING_CODEC = 65595, //!< Image codec for a required format doesn't exist.
+ ERROR_IMAGE_UNKNOWN_FILE_FORMAT = 65596, //!< Unknown or invalid file format that cannot be read.
+ ERROR_IMAGE_DECODER_NOT_PROVIDED = 65597, //!< Image codec doesn't support reading the file format.
+ ERROR_IMAGE_ENCODER_NOT_PROVIDED = 65598, //!< Image codec doesn't support writing the file format.
+ ERROR_PNG_MULTIPLE_IHDR = 65599, //!< Multiple IHDR chunks are not allowed (PNG).
+ ERROR_PNG_INVALID_IDAT = 65600, //!< Invalid IDAT chunk (PNG).
+ ERROR_PNG_INVALID_IEND = 65601, //!< Invalid IEND chunk (PNG).
+ ERROR_PNG_INVALID_PLTE = 65602, //!< Invalid PLTE chunk (PNG).
+ ERROR_PNG_INVALID_TRNS = 65603, //!< Invalid tRNS chunk (PNG).
+ ERROR_PNG_INVALID_FILTER = 65604, //!< Invalid filter type (PNG).
+ ERROR_JPEG_UNSUPPORTED_FEATURE = 65605, //!< Unsupported feature (JPEG).
+ ERROR_JPEG_INVALID_SOS = 65606, //!< Invalid SOS marker or header (JPEG).
+ ERROR_JPEG_INVALID_SOF = 65607, //!< Invalid SOF marker (JPEG).
+ ERROR_JPEG_MULTIPLE_SOF = 65608, //!< Multiple SOF markers (JPEG).
+ ERROR_JPEG_UNSUPPORTED_SOF = 65609, //!< Unsupported SOF marker (JPEG).
+ ERROR_FONT_NOT_INITIALIZED = 65610, //!< Font doesn't have any data as it's not initialized.
+ ERROR_FONT_NO_MATCH = 65611, //!< Font or font face was not matched (BLFontManager).
+ ERROR_FONT_NO_CHARACTER_MAPPING = 65612, //!< Font has no character to glyph mapping data.
+ ERROR_FONT_MISSING_IMPORTANT_TABLE = 65613, //!< Font has missing an important table.
+ ERROR_FONT_FEATURE_NOT_AVAILABLE = 65614, //!< Font feature is not available.
+ ERROR_FONT_CFF_INVALID_DATA = 65615, //!< Font has an invalid CFF data.
+ ERROR_FONT_PROGRAM_TERMINATED = 65616, //!< Font program terminated because the execution reached the limit.
+ ERROR_GLYPH_SUBSTITUTION_TOO_LARGE = 65617, //!< Glyph substitution requires too much space and was terminated.
+ ERROR_INVALID_GLYPH = 65618, //!< Invalid glyph identifier.
+ ERROR_FORCE_UINT = 4294967295,
+}
+
+//! \ingroup bl_globals
+//!
+//! Byte order.
+ByteOrder :: enum u32 {
+ //! Little endian byte-order.
+ LE = 0,
+
+ //! Big endian byte-order.
+ BE = 1,
+
+ //! Native (host) byte-order.
+ NATIVE = 0,
+
+ //! Swapped byte-order (BE if host is LE and vice versa).
+ SWAPPED = 1,
+ FORCE_UINT = 4294967295,
+}
+
+//! \ingroup bl_globals
+//!
+//! Data access flags.
+DataAccessFlags :: enum u32 {
+ //! No data access flags.
+ NO_FLAGS = 0,
+
+ //! Read access.
+ READ = 1,
+
+ //! Write access.
+ WRITE = 2,
+
+ //! Read and write access.
+ RW = 3,
+ FORCE_UINT = 4294967295,
+}
+
+//! \ingroup bl_globals
+//!
+//! Data source type.
+DataSourceType :: enum u32 {
+ //! No data source.
+ NONE = 0,
+
+ //! Memory data source.
+ MEMORY = 1,
+
+ //! File data source.
+ FILE = 2,
+
+ //! Custom data source.
+ CUSTOM = 3,
+
+ //! Maximum value `BLDataSourceType`.
+ MAX_VALUE = 3,
+ FORCE_UINT = 4294967295,
+}
+
+//! \ingroup bl_globals
+//!
+//! Modification operation applied to Blend2D containers.
+ModifyOp :: enum u32 {
+ //! Assign operation, which reserves space only to fit the requested input.
+ ASSIGN_FIT = 0,
+
+ //! Assign operation, which takes into consideration successive appends.
+ ASSIGN_GROW = 1,
+
+ //! Append operation, which reserves space only to fit the current and appended content.
+ APPEND_FIT = 2,
+
+ //! Append operation, which takes into consideration successive appends.
+ APPEND_GROW = 3,
+
+ //! Maximum value of `BLModifyOp`.
+ MAX_VALUE = 3,
+ FORCE_UINT = 4294967295,
+}
+
+//! \ingroup bl_globals
+//!
+//! Boolean operator.
+BooleanOp :: enum u32 {
+ //! Result = B.
+ COPY = 0,
+
+ //! Result = A & B.
+ AND = 1,
+
+ //! Result = A | B.
+ OR = 2,
+
+ //! Result = A ^ B.
+ XOR = 3,
+
+ //! Result = A & ~B.
+ AND_NOT = 4,
+
+ //! Result = ~A & B.
+ NOT_AND = 5,
+
+ //! Maximum value of `BLBooleanOp`.
+ MAX_VALUE = 5,
+ FORCE_UINT = 4294967295,
+}
+
+//! \ingroup bl_styling
+//!
+//! Extend mode.
+ExtendMode :: enum u32 {
+ //! Pad extend [default].
+ PAD = 0,
+
+ //! Repeat extend.
+ REPEAT = 1,
+
+ //! Reflect extend.
+ REFLECT = 2,
+
+ //! Alias of `BL_EXTEND_MODE_PAD`.
+ PAD_X_PAD_Y = 0,
+
+ //! Pad X and repeat Y.
+ PAD_X_REPEAT_Y = 3,
+
+ //! Pad X and reflect Y.
+ PAD_X_REFLECT_Y = 4,
+
+ //! Alias of `BL_EXTEND_MODE_REPEAT`.
+ REPEAT_X_REPEAT_Y = 1,
+
+ //! Repeat X and pad Y.
+ REPEAT_X_PAD_Y = 5,
+
+ //! Repeat X and reflect Y.
+ REPEAT_X_REFLECT_Y = 6,
+
+ //! Alias of `BL_EXTEND_MODE_REFLECT`.
+ REFLECT_X_REFLECT_Y = 2,
+
+ //! Reflect X and pad Y.
+ REFLECT_X_PAD_Y = 7,
+
+ //! Reflect X and repeat Y.
+ REFLECT_X_REPEAT_Y = 8,
+
+ //! Count of simple extend modes (that use the same value for X and Y).
+ SIMPLE_MAX_VALUE = 2,
+
+ //! Count of complex extend modes (that can use independent values for X and Y).
+ COMPLEX_MAX_VALUE = 8,
+
+ //! Maximum value of `BLExtendMode`.
+ MAX_VALUE = 8,
+ FORCE_UINT = 4294967295,
+}
+
+//! \ingroup bl_text
+//!
+//! Text encoding.
+TextEncoding :: enum u32 {
+ //! UTF-8 encoding.
+ UTF8 = 0,
+
+ //! UTF-16 encoding (native endian).
+ UTF16 = 1,
+
+ //! UTF-32 encoding (native endian).
+ UTF32 = 2,
+
+ //! LATIN1 encoding (one byte per character).
+ LATIN1 = 3,
+
+ //! Platform native `wchar_t` (or Windows `WCHAR`) encoding, alias to
+ //! either UTF-32, UTF-16, or UTF-8 depending on `sizeof(wchar_t)`.
+ WCHAR = 2,
+
+ //! Maximum value of `BLTextEncoding`.
+ MAX_VALUE = 3,
+ FORCE_UINT = 4294967295,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! This function is called by Blend2D when an internal assertion failure happens.
+ //!
+ //! Failing an assertion means that there is either a bug in Blend2D or in user code that uses Blend2D and that the
+ //! state of the application is already corrupted and thus irrecoverable. Note that this would be a fatal error if
+ //! this function gets called in production.
+ runtime_assertion_failure :: proc(file: cstring, line: i32, msg: cstring) ---
+}
+
+//! Provides start and end indexes. It has the same semantics as Slices in other programming languages - range is
+//! always within [star, end) internal (start is inclusive, end is exclusive). It's used to specify a range of an
+//! operation of indexed containers like \ref BLString, \ref BLArray, \ref BLGradient, \ref BLPath, etc...
+Range :: struct {
+ start: c.size_t,
+ end: c.size_t,
+}
+
+ArrayView :: struct {
+ data: rawptr,
+ size: c.size_t,
+}
+
+StringView :: struct {
+ data: cstring,
+ size: c.size_t,
+}
+
+DataView :: ArrayView
+
diff --git a/binding/array.odin b/binding/array.odin
@@ -0,0 +1,88 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Array container [C API].
+ArrayCore :: struct {
+ _d: ObjectDetail,
+}
+
+//! \cond INTERNAL
+//! Array container [C API Impl].
+ArrayImpl :: struct {
+ //! Pointer to array data.
+ data: rawptr,
+
+ //! Array size [in items].
+ size: c.size_t,
+
+ //! Array capacity [in items].
+ capacity: c.size_t,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \endcond
+ array_init :: proc(self: ^ArrayCore, array_type: ObjectType) -> Result ---
+ array_init_move :: proc(self: ^ArrayCore, other: ^ArrayCore) -> Result ---
+ array_init_weak :: proc(self: ^ArrayCore, other: ^ArrayCore) -> Result ---
+ array_destroy :: proc(self: ^ArrayCore) -> Result ---
+ array_reset :: proc(self: ^ArrayCore) -> Result ---
+ array_get_size :: proc(self: ^ArrayCore) -> c.size_t ---
+ array_get_capacity :: proc(self: ^ArrayCore) -> c.size_t ---
+ array_get_item_size :: proc(self: ^ArrayCore) -> c.size_t ---
+ array_get_data :: proc(self: ^ArrayCore) -> rawptr ---
+ array_clear :: proc(self: ^ArrayCore) -> Result ---
+ array_shrink :: proc(self: ^ArrayCore) -> Result ---
+ array_reserve :: proc(self: ^ArrayCore, n: c.size_t) -> Result ---
+ array_resize :: proc(self: ^ArrayCore, n: c.size_t, fill: rawptr) -> Result ---
+ array_make_mutable :: proc(self: ^ArrayCore, data_out: ^rawptr) -> Result ---
+ array_modify_op :: proc(self: ^ArrayCore, op: ModifyOp, n: c.size_t, data_out: ^rawptr) -> Result ---
+ array_insert_op :: proc(self: ^ArrayCore, index: c.size_t, n: c.size_t, data_out: ^rawptr) -> Result ---
+ array_assign_move :: proc(self: ^ArrayCore, other: ^ArrayCore) -> Result ---
+ array_assign_weak :: proc(self: ^ArrayCore, other: ^ArrayCore) -> Result ---
+ array_assign_deep :: proc(self: ^ArrayCore, other: ^ArrayCore) -> Result ---
+ array_assign_data :: proc(self: ^ArrayCore, data: rawptr, n: c.size_t) -> Result ---
+ array_assign_external_data :: proc(self: ^ArrayCore, data: rawptr, size: c.size_t, capacity: c.size_t, data_access_flags: DataAccessFlags, destroy_func: DestroyExternalDataFunc, user_data: rawptr) -> Result ---
+ array_append_u8 :: proc(self: ^ArrayCore, value: u8) -> Result ---
+ array_append_u16 :: proc(self: ^ArrayCore, value: u16) -> Result ---
+ array_append_u32 :: proc(self: ^ArrayCore, value: u32) -> Result ---
+ array_append_u64 :: proc(self: ^ArrayCore, value: u64) -> Result ---
+ array_append_f32 :: proc(self: ^ArrayCore, value: f32) -> Result ---
+ array_append_f64 :: proc(self: ^ArrayCore, value: f64) -> Result ---
+ array_append_item :: proc(self: ^ArrayCore, item: rawptr) -> Result ---
+ array_append_data :: proc(self: ^ArrayCore, data: rawptr, n: c.size_t) -> Result ---
+ array_insert_u8 :: proc(self: ^ArrayCore, index: c.size_t, value: u8) -> Result ---
+ array_insert_u16 :: proc(self: ^ArrayCore, index: c.size_t, value: u16) -> Result ---
+ array_insert_u32 :: proc(self: ^ArrayCore, index: c.size_t, value: u32) -> Result ---
+ array_insert_u64 :: proc(self: ^ArrayCore, index: c.size_t, value: u64) -> Result ---
+ array_insert_f32 :: proc(self: ^ArrayCore, index: c.size_t, value: f32) -> Result ---
+ array_insert_f64 :: proc(self: ^ArrayCore, index: c.size_t, value: f64) -> Result ---
+ array_insert_item :: proc(self: ^ArrayCore, index: c.size_t, item: rawptr) -> Result ---
+ array_insert_data :: proc(self: ^ArrayCore, index: c.size_t, data: rawptr, n: c.size_t) -> Result ---
+ array_replace_u8 :: proc(self: ^ArrayCore, index: c.size_t, value: u8) -> Result ---
+ array_replace_u16 :: proc(self: ^ArrayCore, index: c.size_t, value: u16) -> Result ---
+ array_replace_u32 :: proc(self: ^ArrayCore, index: c.size_t, value: u32) -> Result ---
+ array_replace_u64 :: proc(self: ^ArrayCore, index: c.size_t, value: u64) -> Result ---
+ array_replace_f32 :: proc(self: ^ArrayCore, index: c.size_t, value: f32) -> Result ---
+ array_replace_f64 :: proc(self: ^ArrayCore, index: c.size_t, value: f64) -> Result ---
+ array_replace_item :: proc(self: ^ArrayCore, index: c.size_t, item: rawptr) -> Result ---
+ array_replace_data :: proc(self: ^ArrayCore, r_start: c.size_t, r_end: c.size_t, data: rawptr, n: c.size_t) -> Result ---
+ array_remove_index :: proc(self: ^ArrayCore, index: c.size_t) -> Result ---
+ array_remove_range :: proc(self: ^ArrayCore, r_start: c.size_t, r_end: c.size_t) -> Result ---
+ array_equals :: proc(a: ^ArrayCore, b: ^ArrayCore) -> i32 ---
+}
+
diff --git a/binding/bitarray.odin b/binding/bitarray.odin
@@ -0,0 +1,75 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! BitArray container [C API].
+BitArrayCore :: struct {
+ _d: ObjectDetail,
+}
+
+//! \cond INTERNAL
+//! BitArray container [C API Impl].
+BitArrayImpl :: struct {
+ //! Size in bit units.
+ size: u32,
+
+ //! Capacity in bit-word units.
+ capacity: u32,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \endcond
+ bit_array_init :: proc(self: ^BitArrayCore) -> Result ---
+ bit_array_init_move :: proc(self: ^BitArrayCore, other: ^BitArrayCore) -> Result ---
+ bit_array_init_weak :: proc(self: ^BitArrayCore, other: ^BitArrayCore) -> Result ---
+ bit_array_destroy :: proc(self: ^BitArrayCore) -> Result ---
+ bit_array_reset :: proc(self: ^BitArrayCore) -> Result ---
+ bit_array_assign_move :: proc(self: ^BitArrayCore, other: ^BitArrayCore) -> Result ---
+ bit_array_assign_weak :: proc(self: ^BitArrayCore, other: ^BitArrayCore) -> Result ---
+ bit_array_assign_words :: proc(self: ^BitArrayCore, word_data: ^u32, word_count: u32) -> Result ---
+ bit_array_is_empty :: proc(self: ^BitArrayCore) -> i32 ---
+ bit_array_get_size :: proc(self: ^BitArrayCore) -> u32 ---
+ bit_array_get_word_count :: proc(self: ^BitArrayCore) -> u32 ---
+ bit_array_get_capacity :: proc(self: ^BitArrayCore) -> u32 ---
+ bit_array_get_data :: proc(self: ^BitArrayCore) -> ^u32 ---
+ bit_array_get_cardinality :: proc(self: ^BitArrayCore) -> u32 ---
+ bit_array_get_cardinality_in_range :: proc(self: ^BitArrayCore, start_bit: u32, end_bit: u32) -> u32 ---
+ bit_array_has_bit :: proc(self: ^BitArrayCore, bit_index: u32) -> i32 ---
+ bit_array_has_bits_in_range :: proc(self: ^BitArrayCore, start_bit: u32, end_bit: u32) -> i32 ---
+ bit_array_subsumes :: proc(a: ^BitArrayCore, b: ^BitArrayCore) -> i32 ---
+ bit_array_intersects :: proc(a: ^BitArrayCore, b: ^BitArrayCore) -> i32 ---
+ bit_array_get_range :: proc(self: ^BitArrayCore, start_out: ^u32, end_out: ^u32) -> i32 ---
+ bit_array_equals :: proc(a: ^BitArrayCore, b: ^BitArrayCore) -> i32 ---
+ bit_array_compare :: proc(a: ^BitArrayCore, b: ^BitArrayCore) -> i32 ---
+ bit_array_clear :: proc(self: ^BitArrayCore) -> Result ---
+ bit_array_resize :: proc(self: ^BitArrayCore, n_bits: u32) -> Result ---
+ bit_array_reserve :: proc(self: ^BitArrayCore, n_bits: u32) -> Result ---
+ bit_array_shrink :: proc(self: ^BitArrayCore) -> Result ---
+ bit_array_set_bit :: proc(self: ^BitArrayCore, bit_index: u32) -> Result ---
+ bit_array_fill_range :: proc(self: ^BitArrayCore, start_bit: u32, end_bit: u32) -> Result ---
+ bit_array_fill_words :: proc(self: ^BitArrayCore, bit_index: u32, word_data: ^u32, word_count: u32) -> Result ---
+ bit_array_clear_bit :: proc(self: ^BitArrayCore, bit_index: u32) -> Result ---
+ bit_array_clear_range :: proc(self: ^BitArrayCore, start_bit: u32, end_bit: u32) -> Result ---
+ bit_array_clear_word :: proc(self: ^BitArrayCore, bit_index: u32, word_value: u32) -> Result ---
+ bit_array_clear_words :: proc(self: ^BitArrayCore, bit_index: u32, word_data: ^u32, word_count: u32) -> Result ---
+ bit_array_replace_op :: proc(self: ^BitArrayCore, n_bits: u32, data_out: ^^u32) -> Result ---
+ bit_array_replace_bit :: proc(self: ^BitArrayCore, bit_index: u32, bit_value: i32) -> Result ---
+ bit_array_replace_word :: proc(self: ^BitArrayCore, bit_index: u32, word_value: u32) -> Result ---
+ bit_array_replace_words :: proc(self: ^BitArrayCore, bit_index: u32, word_data: ^u32, word_count: u32) -> Result ---
+ bit_array_append_bit :: proc(self: ^BitArrayCore, bit_value: i32) -> Result ---
+ bit_array_append_word :: proc(self: ^BitArrayCore, word_value: u32) -> Result ---
+ bit_array_append_words :: proc(self: ^BitArrayCore, word_data: ^u32, word_count: u32) -> Result ---
+}
+
diff --git a/binding/bitset.odin b/binding/bitset.odin
@@ -0,0 +1,121 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! \name BLBitSet - Constants
+//! \{
+BitSetConstants :: enum u32 {
+ //! Invalid bit-index.
+ //!
+ //! This is the only index that cannot be stored in `BLBitSet`.
+ INVALID_INDEX = 4294967295,
+
+ //! Range mask used by `BLBitsetSegment::start` value - if set the segment is a range of all ones.
+ RANGE_MASK = 2147483648,
+
+ //! Number of words in a BLBitSetSegment.
+ SEGMENT_WORD_COUNT = 4,
+}
+
+//! BitSet segment.
+//!
+//! Segment provides either a dense set of bits starting at `start` or a range of bits all set to one. The start of
+//! the segment is always aligned to segment size, which can be calculated as `32 * BL_BIT_SET_SEGMENT_WORD_COUNT`.
+//! Even ranges are aligned to this value, thus up to 3 segments are used to describe a range that doesn't start/end
+//! at the segment boundary.
+//!
+//! When the segment describes dense bits its size is always fixed and represents `32 * BL_BIT_SET_SEGMENT_WORD_COUNT`
+//! bits, which is currently 128 bits. However, when the segment describes all ones, the first value in data `data[0]`
+//! describes the last bit of the range, which means that an arbitrary range can be encoded within a single segment.
+BitSetSegment :: struct {
+ _start_word: u32,
+ _data: [4]u32,
+}
+
+//! BitSet data view.
+BitSetData :: struct {
+ segment_data: ^BitSetSegment,
+ segment_count: u32,
+ sso_segments: [3]BitSetSegment,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \name BLBitSet - C API
+ //! \{
+ bit_set_init :: proc(self: ^BitSetCore) -> Result ---
+ bit_set_init_move :: proc(self: ^BitSetCore, other: ^BitSetCore) -> Result ---
+ bit_set_init_weak :: proc(self: ^BitSetCore, other: ^BitSetCore) -> Result ---
+ bit_set_init_range :: proc(self: ^BitSetCore, start_bit: u32, end_bit: u32) -> Result ---
+ bit_set_destroy :: proc(self: ^BitSetCore) -> Result ---
+ bit_set_reset :: proc(self: ^BitSetCore) -> Result ---
+ bit_set_assign_move :: proc(self: ^BitSetCore, other: ^BitSetCore) -> Result ---
+ bit_set_assign_weak :: proc(self: ^BitSetCore, other: ^BitSetCore) -> Result ---
+ bit_set_assign_deep :: proc(self: ^BitSetCore, other: ^BitSetCore) -> Result ---
+ bit_set_assign_range :: proc(self: ^BitSetCore, start_bit: u32, end_bit: u32) -> Result ---
+ bit_set_assign_words :: proc(self: ^BitSetCore, start_word: u32, word_data: ^u32, word_count: u32) -> Result ---
+ bit_set_is_empty :: proc(self: ^BitSetCore) -> i32 ---
+ bit_set_get_data :: proc(self: ^BitSetCore, out: ^BitSetData) -> Result ---
+ bit_set_get_segment_count :: proc(self: ^BitSetCore) -> u32 ---
+ bit_set_get_segment_capacity :: proc(self: ^BitSetCore) -> u32 ---
+ bit_set_get_cardinality :: proc(self: ^BitSetCore) -> u32 ---
+ bit_set_get_cardinality_in_range :: proc(self: ^BitSetCore, start_bit: u32, end_bit: u32) -> u32 ---
+ bit_set_has_bit :: proc(self: ^BitSetCore, bit_index: u32) -> i32 ---
+ bit_set_has_bits_in_range :: proc(self: ^BitSetCore, start_bit: u32, end_bit: u32) -> i32 ---
+ bit_set_subsumes :: proc(a: ^BitSetCore, b: ^BitSetCore) -> i32 ---
+ bit_set_intersects :: proc(a: ^BitSetCore, b: ^BitSetCore) -> i32 ---
+ bit_set_get_range :: proc(self: ^BitSetCore, start_out: ^u32, end_out: ^u32) -> i32 ---
+ bit_set_equals :: proc(a: ^BitSetCore, b: ^BitSetCore) -> i32 ---
+ bit_set_compare :: proc(a: ^BitSetCore, b: ^BitSetCore) -> i32 ---
+ bit_set_clear :: proc(self: ^BitSetCore) -> Result ---
+ bit_set_shrink :: proc(self: ^BitSetCore) -> Result ---
+ bit_set_optimize :: proc(self: ^BitSetCore) -> Result ---
+ bit_set_chop :: proc(self: ^BitSetCore, start_bit: u32, end_bit: u32) -> Result ---
+ bit_set_add_bit :: proc(self: ^BitSetCore, bit_index: u32) -> Result ---
+ bit_set_add_range :: proc(self: ^BitSetCore, range_start_bit: u32, range_end_bit: u32) -> Result ---
+ bit_set_add_words :: proc(self: ^BitSetCore, start_word: u32, word_data: ^u32, word_count: u32) -> Result ---
+ bit_set_clear_bit :: proc(self: ^BitSetCore, bit_index: u32) -> Result ---
+ bit_set_clear_range :: proc(self: ^BitSetCore, range_start_bit: u32, range_end_bit: u32) -> Result ---
+
+ // TODO: Future API (BitSet).
+ /*
+ BL_API BLResult BL_CDECL bl_bit_set_combine(BLBitSetCore* dst, const BLBitSetCore* a, const BLBitSetCore* b, BLBooleanOp boolean_op) BL_NOEXCEPT_C;
+ */
+ bit_set_builder_commit :: proc(self: ^BitSetCore, builder: ^BitSetBuilderCore, new_area_index: u32) -> Result ---
+ bit_set_builder_add_range :: proc(self: ^BitSetCore, builder: ^BitSetBuilderCore, start_bit: u32, end_bit: u32) -> Result ---
+}
+
+//! BitSet container [C API].
+BitSetCore :: struct {
+ _d: ObjectDetail,
+}
+
+//! BitSet builder [C API].
+BitSetBuilderCore :: struct {
+ //! Shift to get `_area_index` from bit index, equals to `log2(kBitCount)`.
+ _area_shift: u32,
+
+ //! Area index - index from 0...N where each index represents `kBitCount` bits.
+ _area_index: u32,
+}
+
+//! BitSet container [Impl].
+BitSetImpl :: struct {
+ //! Count of used segments in `segment_data`.
+ segment_count: u32,
+
+ //! Count of allocated segments in `segment_data`.
+ segment_capacity: u32,
+}
+
diff --git a/binding/context.odin b/binding/context.odin
@@ -0,0 +1,759 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Rendering context type.
+ContextType :: enum u32 {
+ //! No rendering context.
+ NONE = 0,
+
+ //! Dummy rendering context.
+ DUMMY = 1,
+
+ /*
+ //! Proxy rendering context.
+ BL_CONTEXT_TYPE_PROXY = 2,
+ */
+
+ //! Software-accelerated rendering context.
+ RASTER = 3,
+
+ //! Maximum value of `BLContextType`.
+ MAX_VALUE = 3,
+ FORCE_UINT = 4294967295,
+}
+
+//! Rendering context hint.
+ContextHint :: enum u32 {
+ //! Rendering quality.
+ RENDERING_QUALITY = 0,
+
+ //! Gradient quality.
+ GRADIENT_QUALITY = 1,
+
+ //! Pattern quality.
+ PATTERN_QUALITY = 2,
+
+ //! Maximum value of `BLContextHint`.
+ MAX_VALUE = 7,
+ FORCE_UINT = 4294967295,
+}
+
+//! Describes a rendering context style slot - fill or stroke.
+ContextStyleSlot :: enum u32 {
+ //! Fill operation style slot.
+ FILL = 0,
+
+ //! Stroke operation style slot.
+ STROKE = 1,
+
+ //! Maximum value of `BLContextStyleSlot`
+ MAX_VALUE = 1,
+ FORCE_UINT = 4294967295,
+}
+
+//! The type of a text rendering operation.
+//!
+//! This value specifies the type of the parameter passed to the text rendering API.
+//!
+//! \note In most cases this should not be required to use by Blend2D users. The C API provides functions that
+//! wrap all of the text operations and C++ API provides functions that use `BLContextRenderTextOp` internally.
+ContextRenderTextOp :: enum u32 {
+ //! UTF-8 text rendering operation - UTF-8 string passed as \ref BLStringView or \ref BLArrayView<uint8_t>.
+ UTF8 = 0,
+
+ //! UTF-16 text rendering operation - UTF-16 string passed as \ref BLArrayView<uint16_t>.
+ UTF16 = 1,
+
+ //! UTF-32 text rendering operation - UTF-32 string passed as \ref BLArrayView<uint32_t>.
+ UTF32 = 2,
+
+ //! LATIN1 text rendering operation - LATIN1 string is passed as \ref BLStringView or \ref BLArrayView<uint8_t>.
+ LATIN1 = 3,
+
+ //! `wchar_t` text rendering operation - wchar_t string is passed as \ref BLArrayView<wchar_t>.
+ WCHAR = 2,
+
+ //! Glyph run text rendering operation - the \ref BLGlyphRun parameter is passed.
+ GLYPH_RUN = 4,
+
+ //! Maximum value of `BLContextRenderTextInputType`
+ MAX_VALUE = 4,
+ TYPE_FORCE_UINT = 4294967295,
+}
+
+//! Rendering context flush flags, used by \ref BLContext::flush().
+ContextFlushFlags :: enum u32 {
+ NO_FLAGS = 0,
+
+ //! Flushes the command queue and waits for its completion (will block until done).
+ SYNC = 2147483648,
+ FORCE_UINT = 4294967295,
+}
+
+//! Rendering context creation flags.
+ContextCreateFlags :: enum u32 {
+ //! No flags.
+ NO_FLAGS = 0,
+
+ //! Disables JIT pipeline generator.
+ FLAG_DISABLE_JIT = 1,
+
+ //! Fallbacks to a synchronous rendering in case that the rendering engine wasn't able to acquire threads. This
+ //! flag only makes sense when the asynchronous mode was specified by having `thread_count` greater than 0. If the
+ //! rendering context fails to acquire at least one thread it would fallback to synchronous mode with no worker
+ //! threads.
+ //!
+ //! \note If this flag is specified with `thread_count == 1` it means to immediately fallback to synchronous
+ //! rendering. It's only practical to use this flag with 2 or more requested threads.
+ FLAG_FALLBACK_TO_SYNC = 1048576,
+
+ //! If this flag is specified and asynchronous rendering is enabled then the context would create its own isolated
+ //! thread-pool, which is useful for debugging purposes.
+ //!
+ //! Do not use this flag in production as rendering contexts with isolated thread-pool have to create and destroy all
+ //! threads they use. This flag is only useful for testing, debugging, and isolated benchmarking.
+ FLAG_ISOLATED_THREAD_POOL = 16777216,
+
+ //! If this flag is specified and JIT pipeline generation enabled then the rendering context would create its own
+ //! isolated JIT runtime. which is useful for debugging purposes. This flag will be ignored if JIT pipeline
+ //! compilation is either not supported or was disabled by other flags.
+ //!
+ //! Do not use this flag in production as rendering contexts with isolated JIT runtime do not use global pipeline
+ //! cache, that's it, after the rendering context is destroyed the JIT runtime is destroyed with it with all
+ //! compiled pipelines. This flag is only useful for testing, debugging, and isolated benchmarking.
+ FLAG_ISOLATED_JIT_RUNTIME = 33554432,
+
+ //! Enables logging to stderr of isolated runtime.
+ //!
+ //! \note Must be used with \ref BL_CONTEXT_CREATE_FLAG_ISOLATED_JIT_RUNTIME otherwise it would have no effect.
+ FLAG_ISOLATED_JIT_LOGGING = 67108864,
+
+ //! Override CPU features when creating isolated context.
+ FLAG_OVERRIDE_CPU_FEATURES = 134217728,
+ FLAG_FORCE_UINT = 4294967295,
+}
+
+//! Error flags that are accumulated during the rendering context lifetime and that can be queried through
+//! \ref BLContext::accumulated_error_flags(). The reason why these flags exist is that errors can happen during
+//! asynchronous rendering, and there is no way the user can catch these errors.
+ContextErrorFlags :: enum u32 {
+ //! No flags.
+ NO_FLAGS = 0,
+
+ //! The rendering context returned or encountered \ref BL_ERROR_INVALID_VALUE, which is mostly related to
+ //! the function argument handling. It's very likely some argument was wrong when calling \ref BLContext API.
+ FLAG_INVALID_VALUE = 1,
+
+ //! Invalid state describes something wrong, for example a pipeline compilation error.
+ FLAG_INVALID_STATE = 2,
+
+ //! The rendering context has encountered invalid geometry.
+ FLAG_INVALID_GEOMETRY = 4,
+
+ //! The rendering context has encountered invalid glyph.
+ FLAG_INVALID_GLYPH = 8,
+
+ //! The rendering context has encountered invalid or uninitialized font.
+ FLAG_INVALID_FONT = 16,
+
+ //! Thread pool was exhausted and couldn't acquire the requested number of threads.
+ FLAG_THREAD_POOL_EXHAUSTED = 536870912,
+
+ //! Out of memory condition.
+ FLAG_OUT_OF_MEMORY = 1073741824,
+
+ //! Unknown error, which we don't have flag for.
+ FLAG_UNKNOWN_ERROR = 2147483648,
+ FLAG_FORCE_UINT = 4294967295,
+}
+
+//! Specifies the behavior of \ref BLContext::swap_styles() operation.
+ContextStyleSwapMode :: enum u32 {
+ //! Swap only fill and stroke styles without affecting fill and stroke alpha.
+ STYLES = 0,
+
+ //! Swap both fill and stroke styles and their alpha values.
+ STYLES_WITH_ALPHA = 1,
+
+ //! Maximum value of `BLContextStyleSwapMode`.
+ MAX_VALUE = 1,
+ FORCE_UINT = 4294967295,
+}
+
+//! Specifies how style transformation matrix is combined with the rendering context transformation matrix, used by
+//! \ref BLContext::set_style() function.
+ContextStyleTransformMode :: enum u32 {
+ //! Style transformation matrix should be transformed with the rendering context user and meta matrix (default).
+ //!
+ //! \note This transformation mode is identical to how user geometry is transformed and it's the default
+ //! transformation and most likely the behavior expected in most cases.
+ USER = 0,
+
+ //! Style transformation matrix should be transformed with the rendering context meta matrix.
+ META = 1,
+
+ //! Style transformation matrix is considered absolute, and is not combined with a rendering context transform.
+ NONE = 2,
+
+ //! Maximum value of `BLContextStyleTransformMode`.
+ MAX_VALUE = 2,
+ FORCE_UINT = 4294967295,
+}
+
+//! Clip mode.
+ClipMode :: enum u32 {
+ //! Clipping to a rectangle that is aligned to the pixel grid.
+ ALIGNED_RECT = 0,
+
+ //! Clipping to a rectangle that is not aligned to pixel grid.
+ UNALIGNED_RECT = 1,
+
+ //! Clipping to a non-rectangular area that is defined by using mask.
+ MASK = 2,
+
+ //! Count of clip modes.
+ COUNT = 3,
+ FORCE_UINT = 4294967295,
+}
+
+//! Composition & blending operator.
+CompOp :: enum u32 {
+ //! Source-over [default].
+ SRC_OVER = 0,
+
+ //! Source-copy.
+ SRC_COPY = 1,
+
+ //! Source-in.
+ SRC_IN = 2,
+
+ //! Source-out.
+ SRC_OUT = 3,
+
+ //! Source-atop.
+ SRC_ATOP = 4,
+
+ //! Destination-over.
+ DST_OVER = 5,
+
+ //! Destination-copy [nop].
+ DST_COPY = 6,
+
+ //! Destination-in.
+ DST_IN = 7,
+
+ //! Destination-out.
+ DST_OUT = 8,
+
+ //! Destination-atop.
+ DST_ATOP = 9,
+
+ //! Xor.
+ XOR = 10,
+
+ //! Clear.
+ CLEAR = 11,
+
+ //! Plus.
+ PLUS = 12,
+
+ //! Minus.
+ MINUS = 13,
+
+ //! Modulate.
+ MODULATE = 14,
+
+ //! Multiply.
+ MULTIPLY = 15,
+
+ //! Screen.
+ SCREEN = 16,
+
+ //! Overlay.
+ OVERLAY = 17,
+
+ //! Darken.
+ DARKEN = 18,
+
+ //! Lighten.
+ LIGHTEN = 19,
+
+ //! Color dodge.
+ COLOR_DODGE = 20,
+
+ //! Color burn.
+ COLOR_BURN = 21,
+
+ //! Linear burn.
+ LINEAR_BURN = 22,
+
+ //! Linear light.
+ LINEAR_LIGHT = 23,
+
+ //! Pin light.
+ PIN_LIGHT = 24,
+
+ //! Hard-light.
+ HARD_LIGHT = 25,
+
+ //! Soft-light.
+ SOFT_LIGHT = 26,
+
+ //! Difference.
+ DIFFERENCE = 27,
+
+ //! Exclusion.
+ EXCLUSION = 28,
+
+ //! Count of composition & blending operators.
+ MAX_VALUE = 28,
+ FORCE_UINT = 4294967295,
+}
+
+//! Rendering quality.
+RenderingQuality :: enum u32 {
+ //! Render using anti-aliasing.
+ ANTIALIAS = 0,
+
+ //! Maximum value of `BLRenderingQuality`.
+ MAX_VALUE = 0,
+ FORCE_UINT = 4294967295,
+}
+
+//! Information that can be used to customize the rendering context.
+ContextCreateInfo :: struct {
+ //! Create flags, see \ref BLContextCreateFlags.
+ flags: u32,
+
+ //! Number of worker threads to use for asynchronous rendering, if non-zero.
+ //!
+ //! If `thread_count` is zero it means to initialize the context for synchronous rendering. This means that every
+ //! operation will take effect immediately. If `thread_count` is `1` it means that the rendering will be asynchronous,
+ //! but no thread would be acquired from a thread-pool, because the user thread will be used as a worker. And
+ //! finally, if `thread_count` is greater than `1` then total of `thread_count - 1` threads will be acquired from
+ //! thread-pool and used as additional workers.
+ thread_count: u32,
+
+ //! CPU features to use in isolated JIT runtime (if supported), only used when `flags` contains
+ //! \ref BL_CONTEXT_CREATE_FLAG_OVERRIDE_CPU_FEATURES.
+ cpu_features: u32,
+
+ //! Maximum number of commands to be queued.
+ //!
+ //! If this parameter is zero the queue size will be determined automatically.
+ //!
+ //! TODO: To be documented, has no effect at the moment.
+ command_queue_limit: u32,
+
+ //! Maximum number of saved states.
+ //!
+ //! \note Zero value tells the rendering engine to use the default saved state limit, which currently defaults
+ //! to 4096 states. This option allows to even increase or decrease the limit, depending on the use case.
+ saved_state_limit: u32,
+
+ //! Pixel origin.
+ //!
+ //! Pixel origin is an offset in pixel units that can be used as an origin for fetchers and effects that use a pixel
+ //! X/Y coordinate in the calculation. One example of using pixel origin is dithering, where it's used to shift the
+ //! dithering matrix.
+ pixel_origin: PointI,
+
+ //! Reserved for future use, must be zero.
+ reserved: [1]u32,
+}
+
+//! Holds an arbitrary 128-bit value (cookie) that can be used to match other cookies. Blend2D uses cookies in places
+//! where it allows to "lock" some state that can only be unlocked by a matching cookie. Please don't confuse cookies
+//! with a security of any kind, it's just an arbitrary data that must match to proceed with a certain operation.
+//!
+//! Cookies can be used with \ref BLContext::save() and \ref BLContext::restore() operations.
+ContextCookie :: struct {
+ data: [2]u64,
+}
+
+//! Rendering context hints.
+ContextHints :: struct {
+ using _: struct #raw_union {
+ using _: struct {
+ rendering_quality: u8,
+ gradient_quality: u8,
+ pattern_quality: u8,
+ },
+
+ hints: [8]u8,
+ },
+}
+
+//! Rendering context [C API].
+ContextCore :: struct {
+ _d: ObjectDetail,
+}
+
+//! \cond INTERNAL
+//! Rendering context [Virtual Function Table].
+ContextVirt :: struct {
+ base: ObjectVirtBase,
+
+ // Interface - Most Used Functions
+ // -------------------------------
+
+ // NOTE 1: These functions are called directly by the BLContext C++ API (the dispatch is inlined). So in general
+ // on x86 targets the compiler will generate something like `call [base + offset]` instruction to perform the call.
+ // We want to have the most used functions first as these would use 8-bit offset instead of 32-bit offset. We have
+ // space for 12 functions as 8-bit offset is signed (from -128 to 127) and the BLObjectVirt already uses 3 functions.
+ //
+ // NOTE 2: On non-X86 platforms such as AArch64 we don't have to worry about offsets as the instruction would be
+ // encoded in 32-bits regardless of the offset.
+ apply_transform_op: proc "c" (impl: ^ContextImpl, op_type: TransformOp, op_data: rawptr) -> Result,
+ fill_rect_i: proc "c" (impl: ^ContextImpl, rect: ^RectI) -> Result,
+ fill_rect_i_rgba32: proc "c" (impl: ^ContextImpl, rect: ^RectI, rgba32: u32) -> Result,
+ fill_rect_i_ext: proc "c" (impl: ^ContextImpl, rect: ^RectI, style: ^ObjectCore) -> Result,
+ fill_rect_d: proc "c" (impl: ^ContextImpl, rect: ^Rect) -> Result,
+ fill_rect_d_rgba32: proc "c" (impl: ^ContextImpl, rect: ^Rect, rgba32: u32) -> Result,
+ fill_rect_d_ext: proc "c" (impl: ^ContextImpl, rect: ^Rect, style: ^ObjectCore) -> Result,
+ fill_path_d: proc "c" (impl: ^ContextImpl, origin: ^Point, path: ^PathCore) -> Result,
+ fill_path_d_rgba32: proc "c" (impl: ^ContextImpl, origin: ^Point, path: ^PathCore, rgba32: u32) -> Result,
+ fill_path_d_ext: proc "c" (impl: ^ContextImpl, origin: ^Point, path: ^PathCore, style: ^ObjectCore) -> Result,
+ blit_image_i: proc "c" (impl: ^ContextImpl, origin: ^PointI, img: ^ImageCore, img_area: ^RectI) -> Result,
+ blit_scaled_image_i: proc "c" (impl: ^ContextImpl, rect: ^RectI, img: ^ImageCore, img_area: ^RectI) -> Result,
+
+ // Interface
+ // ---------
+ flush: proc "c" (impl: ^ContextImpl, flags: ContextFlushFlags) -> Result,
+ save: proc "c" (impl: ^ContextImpl, cookie: ^ContextCookie) -> Result,
+ restore: proc "c" (impl: ^ContextImpl, cookie: ^ContextCookie) -> Result,
+ user_to_meta: proc "c" (impl: ^ContextImpl) -> Result,
+ set_hint: proc "c" (impl: ^ContextImpl, hint_type: ContextHint, value: u32) -> Result,
+ set_hints: proc "c" (impl: ^ContextImpl, hints: ^ContextHints) -> Result,
+ set_flatten_mode: proc "c" (impl: ^ContextImpl, mode: FlattenMode) -> Result,
+ set_flatten_tolerance: proc "c" (impl: ^ContextImpl, tolerance: f64) -> Result,
+ set_approximation_options: proc "c" (impl: ^ContextImpl, options: ^ApproximationOptions) -> Result,
+ get_style: proc "c" (impl: ^ContextImpl, slot: ContextStyleSlot, transformed: i32, style_out: ^VarCore) -> Result,
+ set_style: proc "c" (impl: ^ContextImpl, slot: ContextStyleSlot, style: ^ObjectCore, transform_mode: ContextStyleTransformMode) -> Result,
+ set_style_rgba: proc "c" (impl: ^ContextImpl, slot: ContextStyleSlot, rgba: ^Rgba) -> Result,
+ set_style_rgba32: proc "c" (impl: ^ContextImpl, slot: ContextStyleSlot, rgba32: u32) -> Result,
+ set_style_rgba64: proc "c" (impl: ^ContextImpl, slot: ContextStyleSlot, rgba64: u64) -> Result,
+ disable_style: proc "c" (impl: ^ContextImpl, slot: ContextStyleSlot) -> Result,
+ set_style_alpha: proc "c" (impl: ^ContextImpl, slot: ContextStyleSlot, alpha: f64) -> Result,
+ swap_styles: proc "c" (impl: ^ContextImpl, mode: ContextStyleSwapMode) -> Result,
+ set_global_alpha: proc "c" (impl: ^ContextImpl, alpha: f64) -> Result,
+ set_comp_op: proc "c" (impl: ^ContextImpl, comp_op: CompOp) -> Result,
+ set_fill_rule: proc "c" (impl: ^ContextImpl, fill_rule: FillRule) -> Result,
+ set_stroke_width: proc "c" (impl: ^ContextImpl, width: f64) -> Result,
+ set_stroke_miter_limit: proc "c" (impl: ^ContextImpl, miter_limit: f64) -> Result,
+ set_stroke_cap: proc "c" (impl: ^ContextImpl, position: StrokeCapPosition, stroke_cap: StrokeCap) -> Result,
+ set_stroke_caps: proc "c" (impl: ^ContextImpl, stroke_cap: StrokeCap) -> Result,
+ set_stroke_join: proc "c" (impl: ^ContextImpl, stroke_join: StrokeJoin) -> Result,
+ set_stroke_dash_offset: proc "c" (impl: ^ContextImpl, dash_offset: f64) -> Result,
+ set_stroke_dash_array: proc "c" (impl: ^ContextImpl, dash_array: ^ArrayCore) -> Result,
+ set_stroke_transform_order: proc "c" (impl: ^ContextImpl, transform_order: StrokeTransformOrder) -> Result,
+ set_stroke_options: proc "c" (impl: ^ContextImpl, options: ^StrokeOptionsCore) -> Result,
+ clip_to_rect_i: proc "c" (impl: ^ContextImpl, rect: ^RectI) -> Result,
+ clip_to_rect_d: proc "c" (impl: ^ContextImpl, rect: ^Rect) -> Result,
+ restore_clipping: proc "c" (impl: ^ContextImpl) -> Result,
+ clear_all: proc "c" (impl: ^ContextImpl) -> Result,
+ clear_recti: proc "c" (impl: ^ContextImpl, rect: ^RectI) -> Result,
+ clear_rectd: proc "c" (impl: ^ContextImpl, rect: ^Rect) -> Result,
+ fill_all: proc "c" (impl: ^ContextImpl) -> Result,
+ fill_all_rgba32: proc "c" (impl: ^ContextImpl, rgba32: u32) -> Result,
+ fill_all_ext: proc "c" (impl: ^ContextImpl, style: ^ObjectCore) -> Result,
+ fill_geometry: proc "c" (impl: ^ContextImpl, type: GeometryType, data: rawptr) -> Result,
+ fill_geometry_rgba32: proc "c" (impl: ^ContextImpl, type: GeometryType, data: rawptr, rgba32: u32) -> Result,
+ fill_geometry_ext: proc "c" (impl: ^ContextImpl, type: GeometryType, data: rawptr, style: ^ObjectCore) -> Result,
+ fill_text_op_i: proc "c" (self: ^ContextImpl, origin: ^PointI, font: ^FontCore, op: ContextRenderTextOp, data: rawptr) -> Result,
+ fill_text_op_i_rgba32: proc "c" (self: ^ContextImpl, origin: ^PointI, font: ^FontCore, op: ContextRenderTextOp, data: rawptr, rgba32: u32) -> Result,
+ fill_text_op_i_ext: proc "c" (self: ^ContextImpl, origin: ^PointI, font: ^FontCore, op: ContextRenderTextOp, data: rawptr, style: ^ObjectCore) -> Result,
+ fill_text_op_d: proc "c" (self: ^ContextImpl, origin: ^Point, font: ^FontCore, op: ContextRenderTextOp, data: rawptr) -> Result,
+ fill_text_op_d_rgba32: proc "c" (self: ^ContextImpl, origin: ^Point, font: ^FontCore, op: ContextRenderTextOp, data: rawptr, rgba32: u32) -> Result,
+ fill_text_op_d_ext: proc "c" (self: ^ContextImpl, origin: ^Point, font: ^FontCore, op: ContextRenderTextOp, data: rawptr, style: ^ObjectCore) -> Result,
+ fill_mask_i: proc "c" (impl: ^ContextImpl, origin: ^PointI, mask: ^ImageCore, mask_area: ^RectI) -> Result,
+ fill_mask_i_rgba32: proc "c" (impl: ^ContextImpl, origin: ^PointI, mask: ^ImageCore, mask_area: ^RectI, rgba32: u32) -> Result,
+ fill_mask_i_ext: proc "c" (impl: ^ContextImpl, origin: ^PointI, mask: ^ImageCore, mask_area: ^RectI, style: ^ObjectCore) -> Result,
+ fill_mask_d: proc "c" (impl: ^ContextImpl, origin: ^Point, mask: ^ImageCore, mask_area: ^RectI) -> Result,
+ fill_mask_d_Rgba32: proc "c" (impl: ^ContextImpl, origin: ^Point, mask: ^ImageCore, mask_area: ^RectI, rgba32: u32) -> Result,
+ fill_mask_d_ext: proc "c" (impl: ^ContextImpl, origin: ^Point, mask: ^ImageCore, mask_area: ^RectI, style: ^ObjectCore) -> Result,
+ stroke_path_d: proc "c" (impl: ^ContextImpl, origin: ^Point, path: ^PathCore) -> Result,
+ stroke_path_d_rgba32: proc "c" (impl: ^ContextImpl, origin: ^Point, path: ^PathCore, rgba32: u32) -> Result,
+ stroke_path_d_ext: proc "c" (impl: ^ContextImpl, origin: ^Point, path: ^PathCore, style: ^ObjectCore) -> Result,
+ stroke_geometry: proc "c" (impl: ^ContextImpl, type: GeometryType, data: rawptr) -> Result,
+ stroke_geometry_rgba32: proc "c" (impl: ^ContextImpl, type: GeometryType, data: rawptr, rgba32: u32) -> Result,
+ stroke_geometry_ext: proc "c" (impl: ^ContextImpl, type: GeometryType, data: rawptr, style: ^ObjectCore) -> Result,
+ stroke_text_op_i: proc "c" (self: ^ContextImpl, origin: ^PointI, font: ^FontCore, op: ContextRenderTextOp, data: rawptr) -> Result,
+ stroke_text_op_i_rgba32: proc "c" (self: ^ContextImpl, origin: ^PointI, font: ^FontCore, op: ContextRenderTextOp, data: rawptr, rgba32: u32) -> Result,
+ stroke_text_op_i_ext: proc "c" (self: ^ContextImpl, origin: ^PointI, font: ^FontCore, op: ContextRenderTextOp, data: rawptr, style: ^ObjectCore) -> Result,
+ stroke_text_op_d: proc "c" (self: ^ContextImpl, origin: ^Point, font: ^FontCore, op: ContextRenderTextOp, data: rawptr) -> Result,
+ stroke_text_op_d_rgba32: proc "c" (self: ^ContextImpl, origin: ^Point, font: ^FontCore, op: ContextRenderTextOp, data: rawptr, rgba32: u32) -> Result,
+ stroke_text_op_d_ext: proc "c" (self: ^ContextImpl, origin: ^Point, font: ^FontCore, op: ContextRenderTextOp, data: rawptr, style: ^ObjectCore) -> Result,
+ blit_image_d: proc "c" (impl: ^ContextImpl, origin: ^Point, img: ^ImageCore, img_area: ^RectI) -> Result,
+ blit_scaled_image_d: proc "c" (impl: ^ContextImpl, rect: ^Rect, img: ^ImageCore, img_area: ^RectI) -> Result,
+}
+
+//! Rendering context state.
+//!
+//! This state is not meant to be created by users, it's only provided for users that want to introspect
+//! the rendering context state and for C++ API that accesses it directly for performance reasons.
+ContextState :: struct {
+ //! Target image or image object with nullptr impl in case that the rendering context doesn't render to an image.
+ target_image: ^ImageCore,
+
+ //! Current size of the target in abstract units, pixels if rendering to \ref BLImage.
+ target_size: Size,
+
+ //! Current rendering context hints.
+ hints: ContextHints,
+
+ //! Current composition operator.
+ comp_op: u8,
+
+ //! Current fill rule.
+ fill_rule: u8,
+
+ //! Current type of a style object of fill and stroke operations indexed by \ref BLContextStyleSlot.
+ style_type: [2]u8,
+
+ //! Count of saved states in the context.
+ saved_state_count: u32,
+
+ //! Current global alpha value [0, 1].
+ global_alpha: f64,
+
+ //! Current fill or stroke alpha indexed by style slot, see \ref BLContextStyleSlot.
+ style_alpha: [2]f64,
+
+ //! Current stroke options.
+ stroke_options: StrokeOptionsCore,
+
+ //! Current approximation options.
+ approximation_options: ApproximationOptions,
+
+ //! Current meta transformation matrix.
+ meta_transform: Matrix2D,
+
+ //! Current user transformation matrix.
+ user_transform: Matrix2D,
+
+ //! Current final transformation matrix, which combines all transformation matrices.
+ final_transform: Matrix2D,
+}
+
+//! Rendering context [C API Impl].
+ContextImpl :: struct {
+ //! Virtual function table.
+ virt: ^ContextVirt,
+
+ //! Current state of the context.
+ state: ^ContextState,
+
+ //! Type of the rendering context, see \ref BLContextType.
+ context_type: u32,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \endcond
+ context_init :: proc(self: ^ContextCore) -> Result ---
+ context_init_move :: proc(self: ^ContextCore, other: ^ContextCore) -> Result ---
+ context_init_weak :: proc(self: ^ContextCore, other: ^ContextCore) -> Result ---
+ context_init_as :: proc(self: ^ContextCore, image: ^ImageCore, cci: ^ContextCreateInfo) -> Result ---
+ context_destroy :: proc(self: ^ContextCore) -> Result ---
+ context_reset :: proc(self: ^ContextCore) -> Result ---
+ context_assign_move :: proc(self: ^ContextCore, other: ^ContextCore) -> Result ---
+ context_assign_weak :: proc(self: ^ContextCore, other: ^ContextCore) -> Result ---
+ context_get_type :: proc(self: ^ContextCore) -> ContextType ---
+ context_get_target_size :: proc(self: ^ContextCore, target_size_out: ^Size) -> Result ---
+ context_get_target_image :: proc(self: ^ContextCore) -> ^ImageCore ---
+ context_begin :: proc(self: ^ContextCore, image: ^ImageCore, cci: ^ContextCreateInfo) -> Result ---
+ context_end :: proc(self: ^ContextCore) -> Result ---
+ context_flush :: proc(self: ^ContextCore, flags: ContextFlushFlags) -> Result ---
+ context_save :: proc(self: ^ContextCore, cookie: ^ContextCookie) -> Result ---
+ context_restore :: proc(self: ^ContextCore, cookie: ^ContextCookie) -> Result ---
+ context_get_meta_transform :: proc(self: ^ContextCore, transform_out: ^Matrix2D) -> Result ---
+ context_get_user_transform :: proc(self: ^ContextCore, transform_out: ^Matrix2D) -> Result ---
+ context_get_final_transform :: proc(self: ^ContextCore, transform_out: ^Matrix2D) -> Result ---
+ context_user_to_meta :: proc(self: ^ContextCore) -> Result ---
+ context_apply_transform_op :: proc(self: ^ContextCore, op_type: TransformOp, op_data: rawptr) -> Result ---
+ context_get_hint :: proc(self: ^ContextCore, hint_type: ContextHint) -> u32 ---
+ context_set_hint :: proc(self: ^ContextCore, hint_type: ContextHint, value: u32) -> Result ---
+ context_get_hints :: proc(self: ^ContextCore, hints_out: ^ContextHints) -> Result ---
+ context_set_hints :: proc(self: ^ContextCore, hints: ^ContextHints) -> Result ---
+ context_set_flatten_mode :: proc(self: ^ContextCore, mode: FlattenMode) -> Result ---
+ context_set_flatten_tolerance :: proc(self: ^ContextCore, tolerance: f64) -> Result ---
+ context_set_approximation_options :: proc(self: ^ContextCore, options: ^ApproximationOptions) -> Result ---
+ context_get_fill_style :: proc(self: ^ContextCore, style_out: ^VarCore) -> Result ---
+ context_get_transformed_fill_style :: proc(self: ^ContextCore, style_out: ^VarCore) -> Result ---
+ context_set_fill_style :: proc(self: ^ContextCore, style: ^Unknown) -> Result ---
+ context_set_fill_style_with_mode :: proc(self: ^ContextCore, style: ^Unknown, transform_mode: ContextStyleTransformMode) -> Result ---
+ context_set_fill_style_rgba :: proc(self: ^ContextCore, rgba: ^Rgba) -> Result ---
+ context_set_fill_style_rgba32 :: proc(self: ^ContextCore, rgba32: u32) -> Result ---
+ context_set_fill_style_rgba64 :: proc(self: ^ContextCore, rgba64: u64) -> Result ---
+ context_disable_fill_style :: proc(self: ^ContextCore) -> Result ---
+ context_get_fill_alpha :: proc(self: ^ContextCore) -> f64 ---
+ context_set_fill_alpha :: proc(self: ^ContextCore, alpha: f64) -> Result ---
+ context_get_stroke_style :: proc(self: ^ContextCore, style_out: ^VarCore) -> Result ---
+ context_get_transformed_stroke_style :: proc(self: ^ContextCore, style_out: ^VarCore) -> Result ---
+ context_set_stroke_style :: proc(self: ^ContextCore, style: ^Unknown) -> Result ---
+ context_set_stroke_style_with_mode :: proc(self: ^ContextCore, style: ^Unknown, transform_mode: ContextStyleTransformMode) -> Result ---
+ context_set_stroke_style_rgba :: proc(self: ^ContextCore, rgba: ^Rgba) -> Result ---
+ context_set_stroke_style_rgba32 :: proc(self: ^ContextCore, rgba32: u32) -> Result ---
+ context_set_stroke_style_rgba64 :: proc(self: ^ContextCore, rgba64: u64) -> Result ---
+ context_disable_stroke_style :: proc(self: ^ContextCore) -> Result ---
+ context_get_stroke_alpha :: proc(self: ^ContextCore) -> f64 ---
+ context_set_stroke_alpha :: proc(self: ^ContextCore, alpha: f64) -> Result ---
+ context_swap_styles :: proc(self: ^ContextCore, mode: ContextStyleSwapMode) -> Result ---
+ context_get_global_alpha :: proc(self: ^ContextCore) -> f64 ---
+ context_set_global_alpha :: proc(self: ^ContextCore, alpha: f64) -> Result ---
+ context_get_comp_op :: proc(self: ^ContextCore) -> CompOp ---
+ context_set_comp_op :: proc(self: ^ContextCore, comp_op: CompOp) -> Result ---
+ context_get_fill_rule :: proc(self: ^ContextCore) -> FillRule ---
+ context_set_fill_rule :: proc(self: ^ContextCore, fill_rule: FillRule) -> Result ---
+ context_get_stroke_width :: proc(self: ^ContextCore) -> f64 ---
+ context_set_stroke_width :: proc(self: ^ContextCore, width: f64) -> Result ---
+ context_get_stroke_miter_limit :: proc(self: ^ContextCore) -> f64 ---
+ context_set_stroke_miter_limit :: proc(self: ^ContextCore, miter_limit: f64) -> Result ---
+ context_get_stroke_cap :: proc(self: ^ContextCore, position: StrokeCapPosition) -> StrokeCap ---
+ context_set_stroke_cap :: proc(self: ^ContextCore, position: StrokeCapPosition, stroke_cap: StrokeCap) -> Result ---
+ context_set_stroke_caps :: proc(self: ^ContextCore, stroke_cap: StrokeCap) -> Result ---
+ context_get_stroke_join :: proc(self: ^ContextCore) -> StrokeJoin ---
+ context_set_stroke_join :: proc(self: ^ContextCore, stroke_join: StrokeJoin) -> Result ---
+ context_get_stroke_transform_order :: proc(self: ^ContextCore) -> StrokeTransformOrder ---
+ context_set_stroke_transform_order :: proc(self: ^ContextCore, transform_order: StrokeTransformOrder) -> Result ---
+ context_get_stroke_dash_offset :: proc(self: ^ContextCore) -> f64 ---
+ context_set_stroke_dash_offset :: proc(self: ^ContextCore, dash_offset: f64) -> Result ---
+ context_get_stroke_dash_array :: proc(self: ^ContextCore, dash_array_out: ^ArrayCore) -> Result ---
+ context_set_stroke_dash_array :: proc(self: ^ContextCore, dash_array: ^ArrayCore) -> Result ---
+ context_get_stroke_options :: proc(self: ^ContextCore, options: ^StrokeOptionsCore) -> Result ---
+ context_set_stroke_options :: proc(self: ^ContextCore, options: ^StrokeOptionsCore) -> Result ---
+ context_clip_to_rect_i :: proc(self: ^ContextCore, rect: ^RectI) -> Result ---
+ context_clip_to_rect_d :: proc(self: ^ContextCore, rect: ^Rect) -> Result ---
+ context_restore_clipping :: proc(self: ^ContextCore) -> Result ---
+ context_clear_all :: proc(self: ^ContextCore) -> Result ---
+ context_clear_rect_i :: proc(self: ^ContextCore, rect: ^RectI) -> Result ---
+ context_clear_rect_d :: proc(self: ^ContextCore, rect: ^Rect) -> Result ---
+ context_fill_all :: proc(self: ^ContextCore) -> Result ---
+ context_fill_all_rgba32 :: proc(self: ^ContextCore, rgba32: u32) -> Result ---
+ context_fill_all_rgba64 :: proc(self: ^ContextCore, rgba64: u64) -> Result ---
+ context_fill_all_ext :: proc(self: ^ContextCore, style: ^Unknown) -> Result ---
+ context_fill_rect_i :: proc(self: ^ContextCore, rect: ^RectI) -> Result ---
+ context_fill_rect_i_rgba32 :: proc(self: ^ContextCore, rect: ^RectI, rgba32: u32) -> Result ---
+ context_fill_rect_i_rgba64 :: proc(self: ^ContextCore, rect: ^RectI, rgba64: u64) -> Result ---
+ context_fill_rect_i_ext :: proc(self: ^ContextCore, rect: ^RectI, style: ^Unknown) -> Result ---
+ context_fill_rect_d :: proc(self: ^ContextCore, rect: ^Rect) -> Result ---
+ context_fill_rect_d_rgba32 :: proc(self: ^ContextCore, rect: ^Rect, rgba32: u32) -> Result ---
+ context_fill_rect_d_rgba64 :: proc(self: ^ContextCore, rect: ^Rect, rgba64: u64) -> Result ---
+ context_fill_rect_d_ext :: proc(self: ^ContextCore, rect: ^Rect, style: ^Unknown) -> Result ---
+ context_fill_path_d :: proc(self: ^ContextCore, origin: ^Point, path: ^PathCore) -> Result ---
+ context_fill_path_d_rgba32 :: proc(self: ^ContextCore, origin: ^Point, path: ^PathCore, rgba32: u32) -> Result ---
+ context_fill_path_d_rgba64 :: proc(self: ^ContextCore, origin: ^Point, path: ^PathCore, rgba64: u64) -> Result ---
+ context_fill_path_d_ext :: proc(self: ^ContextCore, origin: ^Point, path: ^PathCore, style: ^Unknown) -> Result ---
+ context_fill_geometry :: proc(self: ^ContextCore, type: GeometryType, data: rawptr) -> Result ---
+ context_fill_geometry_rgba32 :: proc(self: ^ContextCore, type: GeometryType, data: rawptr, rgba32: u32) -> Result ---
+ context_fill_geometry_rgba64 :: proc(self: ^ContextCore, type: GeometryType, data: rawptr, rgba64: u64) -> Result ---
+ context_fill_geometry_ext :: proc(self: ^ContextCore, type: GeometryType, data: rawptr, style: ^Unknown) -> Result ---
+ context_fill_utf8_text_i :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: cstring, size: c.size_t) -> Result ---
+ context_fill_utf8_text_i_rgba32 :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: cstring, size: c.size_t, rgba32: u32) -> Result ---
+ context_fill_utf8_text_i_rgba64 :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: cstring, size: c.size_t, rgba64: u64) -> Result ---
+ context_fill_utf8_text_i_ext :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: cstring, size: c.size_t, style: ^Unknown) -> Result ---
+ context_fill_utf8_text_d :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: cstring, size: c.size_t) -> Result ---
+ context_fill_utf8_text_d_rgba32 :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: cstring, size: c.size_t, rgba32: u32) -> Result ---
+ context_fill_utf8_text_d_rgba64 :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: cstring, size: c.size_t, rgba64: u64) -> Result ---
+ context_fill_utf8_text_d_ext :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: cstring, size: c.size_t, style: ^Unknown) -> Result ---
+ context_fill_utf16_text_i :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: ^u16, size: c.size_t) -> Result ---
+ context_fill_utf16_text_i_rgba32 :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: ^u16, size: c.size_t, rgba32: u32) -> Result ---
+ context_fill_utf16_text_i_rgba64 :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: ^u16, size: c.size_t, rgba64: u64) -> Result ---
+ context_fill_utf16_text_i_ext :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: ^u16, size: c.size_t, style: ^Unknown) -> Result ---
+ context_fill_utf16_text_d :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: ^u16, size: c.size_t) -> Result ---
+ context_fill_utf16_text_d_rgba32 :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: ^u16, size: c.size_t, rgba32: u32) -> Result ---
+ context_fill_utf16_text_d_rgba64 :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: ^u16, size: c.size_t, rgba64: u64) -> Result ---
+ context_fill_utf16_text_d_ext :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: ^u16, size: c.size_t, style: ^Unknown) -> Result ---
+ context_fill_utf32_text_i :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: ^u32, size: c.size_t) -> Result ---
+ context_fill_utf32_text_i_rgba32 :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: ^u32, size: c.size_t, rgba32: u32) -> Result ---
+ context_fill_utf32_text_i_rgba64 :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: ^u32, size: c.size_t, rgba64: u64) -> Result ---
+ context_fill_utf32_text_i_ext :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: ^u32, size: c.size_t, style: ^Unknown) -> Result ---
+ context_fill_utf32_text_d :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: ^u32, size: c.size_t) -> Result ---
+ context_fill_utf32_text_d_rgba32 :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: ^u32, size: c.size_t, rgba32: u32) -> Result ---
+ context_fill_utf32_text_d_rgba64 :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: ^u32, size: c.size_t, rgba64: u64) -> Result ---
+ context_fill_utf32_text_d_ext :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: ^u32, size: c.size_t, style: ^Unknown) -> Result ---
+ context_fill_glyph_run_i :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, glyph_run: ^GlyphRun) -> Result ---
+ context_fill_glyph_run_i_rgba32 :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, glyph_run: ^GlyphRun, rgba32: u32) -> Result ---
+ context_fill_glyph_run_i_rgba64 :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, glyph_run: ^GlyphRun, rgba64: u64) -> Result ---
+ context_fill_glyph_run_i_ext :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, glyph_run: ^GlyphRun, style: ^Unknown) -> Result ---
+ context_fill_glyph_run_d :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, glyph_run: ^GlyphRun) -> Result ---
+ context_fill_glyph_run_d_rgba32 :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, glyph_run: ^GlyphRun, rgba32: u32) -> Result ---
+ context_fill_glyph_run_d_rgba64 :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, glyph_run: ^GlyphRun, rgba64: u64) -> Result ---
+ context_fill_glyph_run_d_ext :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, glyph_run: ^GlyphRun, style: ^Unknown) -> Result ---
+ context_fill_mask_i :: proc(self: ^ContextCore, origin: ^PointI, mask: ^ImageCore, mask_area: ^RectI) -> Result ---
+ context_fill_mask_i_rgba32 :: proc(self: ^ContextCore, origin: ^PointI, mask: ^ImageCore, mask_area: ^RectI, rgba32: u32) -> Result ---
+ context_fill_mask_i_rgba64 :: proc(self: ^ContextCore, origin: ^PointI, mask: ^ImageCore, mask_area: ^RectI, rgba64: u64) -> Result ---
+ context_fill_mask_i_ext :: proc(self: ^ContextCore, origin: ^PointI, mask: ^ImageCore, mask_area: ^RectI, style: ^Unknown) -> Result ---
+ context_fill_mask_d :: proc(self: ^ContextCore, origin: ^Point, mask: ^ImageCore, mask_area: ^RectI) -> Result ---
+ context_fill_mask_d_rgba32 :: proc(self: ^ContextCore, origin: ^Point, mask: ^ImageCore, mask_area: ^RectI, rgba32: u32) -> Result ---
+ context_fill_mask_d_rgba64 :: proc(self: ^ContextCore, origin: ^Point, mask: ^ImageCore, mask_area: ^RectI, rgba64: u64) -> Result ---
+ context_fill_mask_d_ext :: proc(self: ^ContextCore, origin: ^Point, mask: ^ImageCore, mask_area: ^RectI, style: ^Unknown) -> Result ---
+ context_stroke_rect_i :: proc(self: ^ContextCore, rect: ^RectI) -> Result ---
+ context_stroke_rect_i_rgba32 :: proc(self: ^ContextCore, rect: ^RectI, rgba32: u32) -> Result ---
+ context_stroke_rect_i_rgba64 :: proc(self: ^ContextCore, rect: ^RectI, rgba64: u64) -> Result ---
+ context_stroke_rect_i_ext :: proc(self: ^ContextCore, rect: ^RectI, style: ^Unknown) -> Result ---
+ context_stroke_rect_d :: proc(self: ^ContextCore, rect: ^Rect) -> Result ---
+ context_stroke_rect_d_rgba32 :: proc(self: ^ContextCore, rect: ^Rect, rgba32: u32) -> Result ---
+ context_stroke_rect_d_rgba64 :: proc(self: ^ContextCore, rect: ^Rect, rgba64: u64) -> Result ---
+ context_stroke_rect_d_ext :: proc(self: ^ContextCore, rect: ^Rect, style: ^Unknown) -> Result ---
+ context_stroke_path_d :: proc(self: ^ContextCore, origin: ^Point, path: ^PathCore) -> Result ---
+ context_stroke_path_d_rgba32 :: proc(self: ^ContextCore, origin: ^Point, path: ^PathCore, rgba32: u32) -> Result ---
+ context_stroke_path_d_rgba64 :: proc(self: ^ContextCore, origin: ^Point, path: ^PathCore, rgba64: u64) -> Result ---
+ context_stroke_path_d_ext :: proc(self: ^ContextCore, origin: ^Point, path: ^PathCore, style: ^Unknown) -> Result ---
+ context_stroke_geometry :: proc(self: ^ContextCore, type: GeometryType, data: rawptr) -> Result ---
+ context_stroke_geometry_rgba32 :: proc(self: ^ContextCore, type: GeometryType, data: rawptr, rgba32: u32) -> Result ---
+ context_stroke_geometry_rgba64 :: proc(self: ^ContextCore, type: GeometryType, data: rawptr, rgba64: u64) -> Result ---
+ context_stroke_geometry_ext :: proc(self: ^ContextCore, type: GeometryType, data: rawptr, style: ^Unknown) -> Result ---
+ context_stroke_utf8_text_i :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: cstring, size: c.size_t) -> Result ---
+ context_stroke_utf8_text_i_rgba32 :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: cstring, size: c.size_t, rgba32: u32) -> Result ---
+ context_stroke_utf8_text_i_rgba64 :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: cstring, size: c.size_t, rgba64: u64) -> Result ---
+ context_stroke_utf8_text_i_ext :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: cstring, size: c.size_t, style: ^Unknown) -> Result ---
+ context_stroke_utf8_text_d :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: cstring, size: c.size_t) -> Result ---
+ context_stroke_utf8_text_d_rgba32 :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: cstring, size: c.size_t, rgba32: u32) -> Result ---
+ context_stroke_utf8_text_d_rgba64 :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: cstring, size: c.size_t, rgba64: u64) -> Result ---
+ context_stroke_utf8_text_d_ext :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: cstring, size: c.size_t, style: ^Unknown) -> Result ---
+ context_stroke_utf16_text_i :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: ^u16, size: c.size_t) -> Result ---
+ context_stroke_utf16_text_i_rgba32 :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: ^u16, size: c.size_t, rgba32: u32) -> Result ---
+ context_stroke_utf16_text_i_rgba64 :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: ^u16, size: c.size_t, rgba64: u64) -> Result ---
+ context_stroke_utf16_text_i_ext :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: ^u16, size: c.size_t, style: ^Unknown) -> Result ---
+ context_stroke_utf16_text_d :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: ^u16, size: c.size_t) -> Result ---
+ context_stroke_utf16_text_d_rgba32 :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: ^u16, size: c.size_t, rgba32: u32) -> Result ---
+ context_stroke_utf16_text_d_rgba64 :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: ^u16, size: c.size_t, rgba64: u64) -> Result ---
+ context_stroke_utf16_text_d_ext :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: ^u16, size: c.size_t, style: ^Unknown) -> Result ---
+ context_stroke_utf32_text_i :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: ^u32, size: c.size_t) -> Result ---
+ context_stroke_utf32_text_i_rgba32 :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: ^u32, size: c.size_t, rgba32: u32) -> Result ---
+ context_stroke_utf32_text_i_rgba64 :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: ^u32, size: c.size_t, rgba64: u64) -> Result ---
+ context_stroke_utf32_text_i_ext :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, text: ^u32, size: c.size_t, style: ^Unknown) -> Result ---
+ context_stroke_utf32_text_d :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: ^u32, size: c.size_t) -> Result ---
+ context_stroke_utf32_text_d_rgba32 :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: ^u32, size: c.size_t, rgba32: u32) -> Result ---
+ context_stroke_utf32_text_d_rgba64 :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: ^u32, size: c.size_t, rgba64: u64) -> Result ---
+ context_stroke_utf32_text_d_ext :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, text: ^u32, size: c.size_t, style: ^Unknown) -> Result ---
+ context_stroke_glyph_run_i :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, glyph_run: ^GlyphRun) -> Result ---
+ context_stroke_glyph_run_i_rgba32 :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, glyph_run: ^GlyphRun, rgba32: u32) -> Result ---
+ context_stroke_glyph_run_i_rgba64 :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, glyph_run: ^GlyphRun, rgba64: u64) -> Result ---
+ context_stroke_glyph_run_i_ext :: proc(self: ^ContextCore, origin: ^PointI, font: ^FontCore, glyph_run: ^GlyphRun, style: ^Unknown) -> Result ---
+ context_stroke_glyph_run_d :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, glyph_run: ^GlyphRun) -> Result ---
+ context_stroke_glyph_run_d_rgba32 :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, glyph_run: ^GlyphRun, rgba32: u32) -> Result ---
+ context_stroke_glyph_run_d_rgba64 :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, glyph_run: ^GlyphRun, rgba64: u64) -> Result ---
+ context_stroke_glyph_run_d_ext :: proc(self: ^ContextCore, origin: ^Point, font: ^FontCore, glyph_run: ^GlyphRun, style: ^Unknown) -> Result ---
+ context_blit_image_i :: proc(self: ^ContextCore, origin: ^PointI, img: ^ImageCore, img_area: ^RectI) -> Result ---
+ context_blit_image_d :: proc(self: ^ContextCore, origin: ^Point, img: ^ImageCore, img_area: ^RectI) -> Result ---
+ context_blit_scaled_image_i :: proc(self: ^ContextCore, rect: ^RectI, img: ^ImageCore, img_area: ^RectI) -> Result ---
+ context_blit_scaled_image_d :: proc(self: ^ContextCore, rect: ^Rect, img: ^ImageCore, img_area: ^RectI) -> Result ---
+}
+
diff --git a/binding/filesystem.odin b/binding/filesystem.odin
@@ -0,0 +1,266 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! File information flags, used by \ref BLFileInfo.
+FileInfoFlags :: enum u32 {
+ //! File owner has read permission (compatible with 0400 octal notation).
+ OWNER_R = 256,
+
+ //! File owner has write permission (compatible with 0200 octal notation).
+ OWNER_W = 128,
+
+ //! File owner has execute permission (compatible with 0100 octal notation).
+ OWNER_X = 64,
+
+ //! A combination of \ref BL_FILE_INFO_OWNER_R, \ref BL_FILE_INFO_OWNER_W, and \ref BL_FILE_INFO_OWNER_X.
+ OWNER_MASK = 448,
+
+ //! File group owner has read permission (compatible with 040 octal notation).
+ GROUP_R = 32,
+
+ //! File group owner has write permission (compatible with 020 octal notation).
+ GROUP_W = 16,
+
+ //! File group owner has execute permission (compatible with 010 octal notation).
+ GROUP_X = 8,
+
+ //! A combination of \ref BL_FILE_INFO_GROUP_R, \ref BL_FILE_INFO_GROUP_W, and \ref BL_FILE_INFO_GROUP_X.
+ GROUP_MASK = 56,
+
+ //! Other users have read permission (compatible with 04 octal notation).
+ OTHER_R = 4,
+
+ //! Other users have write permission (compatible with 02 octal notation).
+ OTHER_W = 2,
+
+ //! Other users have execute permission (compatible with 01 octal notation).
+ OTHER_X = 1,
+
+ //! A combination of \ref BL_FILE_INFO_OTHER_R, \ref BL_FILE_INFO_OTHER_W, and \ref BL_FILE_INFO_OTHER_X.
+ OTHER_MASK = 7,
+
+ //! Set user ID to file owner user ID on execution (compatible with 04000 octal notation).
+ SUID = 2048,
+
+ //! Set group ID to file's user group ID on execution (compatible with 02000 octal notation).
+ SGID = 1024,
+
+ //! A combination of all file permission bits.
+ PERMISSIONS_MASK = 4095,
+
+ //! A flag specifying that this is a regular file.
+ REGULAR = 65536,
+
+ //! A flag specifying that this is a directory.
+ DIRECTORY = 131072,
+
+ //! A flag specifying that this is a symbolic link.
+ SYMLINK = 262144,
+
+ //! A flag describing a character device.
+ CHAR_DEVICE = 1048576,
+
+ //! A flag describing a block device.
+ BLOCK_DEVICE = 2097152,
+
+ //! A flag describing a FIFO (named pipe).
+ FIFO = 4194304,
+
+ //! A flag describing a socket.
+ SOCKET = 8388608,
+
+ //! A flag describing a hidden file (Windows only).
+ HIDDEN = 16777216,
+
+ //! A flag describing a hidden file (Windows only).
+ EXECUTABLE = 33554432,
+
+ //! A flag describing an archive (Windows only).
+ ARCHIVE = 67108864,
+
+ //! A flag describing a system file (Windows only).
+ SYSTEM = 134217728,
+
+ //! File information is valid (the request succeeded).
+ VALID = 2147483648,
+ FORCE_UINT = 4294967295,
+}
+
+//! File open flags, see \ref BLFile::open().
+FileOpenFlags :: enum u32 {
+ //! No flags.
+ NO_FLAGS = 0,
+
+ //! Opens the file for reading.
+ //!
+ //! The following system flags are used when opening the file:
+ //! - `O_RDONLY` (Posix)
+ //! - `GENERIC_READ` (Windows)
+ READ = 1,
+
+ //! Opens the file for writing:
+ //!
+ //! The following system flags are used when opening the file:
+ //! - `O_WRONLY` (Posix)
+ //! - `GENERIC_WRITE` (Windows)
+ WRITE = 2,
+
+ //! Opens the file for reading & writing.
+ //!
+ //! The following system flags are used when opening the file:
+ //! - `O_RDWR` (Posix)
+ //! - `GENERIC_READ | GENERIC_WRITE` (Windows)
+ RW = 3,
+
+ //! Creates the file if it doesn't exist or opens it if it does.
+ //!
+ //! The following system flags are used when opening the file:
+ //! - `O_CREAT` (Posix)
+ //! - `CREATE_ALWAYS` or `OPEN_ALWAYS` depending on other flags (Windows)
+ CREATE = 4,
+
+ //! Opens the file for deleting or renaming (Windows).
+ //!
+ //! Adds `DELETE` flag when opening the file to `ACCESS_MASK`.
+ DELETE = 8,
+
+ //! Truncates the file.
+ //!
+ //! The following system flags are used when opening the file:
+ //! - `O_TRUNC` (Posix)
+ //! - `TRUNCATE_EXISTING` (Windows)
+ TRUNCATE = 16,
+
+ //! Opens the file for reading in exclusive mode (Windows).
+ //!
+ //! Exclusive mode means to not specify the `FILE_SHARE_READ` option.
+ READ_EXCLUSIVE = 268435456,
+
+ //! Opens the file for writing in exclusive mode (Windows).
+ //!
+ //! Exclusive mode means to not specify the `FILE_SHARE_WRITE` option.
+ WRITE_EXCLUSIVE = 536870912,
+
+ //! Opens the file for both reading and writing (Windows).
+ //!
+ //! This is a combination of both `BL_FILE_OPEN_READ_EXCLUSIVE` and `BL_FILE_OPEN_WRITE_EXCLUSIVE`.
+ RW_EXCLUSIVE = 805306368,
+
+ //! Creates the file in exclusive mode - fails if the file already exists.
+ //!
+ //! The following system flags are used when opening the file:
+ //! - `O_EXCL` (Posix)
+ //! - `CREATE_NEW` (Windows)
+ CREATE_EXCLUSIVE = 1073741824,
+
+ //! Opens the file for deleting or renaming in exclusive mode (Windows).
+ //!
+ //! Exclusive mode means to not specify the `FILE_SHARE_DELETE` option.
+ DELETE_EXCLUSIVE = 2147483648,
+ FORCE_UINT = 4294967295,
+}
+
+//! File seek mode, see \ref BLFile::seek().
+//!
+//! \note Seek constants should be compatible with constants used by both POSIX
+//! and Windows API.
+FileSeekType :: enum u32 {
+ //! Seek from the beginning of the file (SEEK_SET).
+ SET = 0,
+
+ //! Seek from the current position (SEEK_CUR).
+ CUR = 1,
+
+ //! Seek from the end of the file (SEEK_END).
+ END = 2,
+
+ //! Maximum value of `BLFileSeekType`.
+ MAX_VALUE = 3,
+ FORCE_UINT = 4294967295,
+}
+
+//! File read flags used by \ref BLFileSystem::read_file().
+FileReadFlags :: enum u32 {
+ //! No flags.
+ NO_FLAGS = 0,
+
+ //! Use memory mapping to read the content of the file.
+ //!
+ //! The destination buffer `BLArray<>` would be configured to use the memory mapped buffer instead of allocating its
+ //! own.
+ MMAP_ENABLED = 1,
+
+ //! Avoid memory mapping of small files.
+ //!
+ //! The size of small file is determined by Blend2D, however, you should expect it to be 16kB or 64kB depending on
+ //! host operating system.
+ MMAP_AVOID_SMALL = 2,
+
+ //! Do not fallback to regular read if memory mapping fails. It's worth noting that memory mapping would fail for
+ //! files stored on filesystem that is not local (like a mounted network filesystem, etc...).
+ MMAP_NO_FALLBACK = 8,
+ FORCE_UINT = 4294967295,
+}
+
+//! A thin abstraction over a native OS file IO [C API].
+FileCore :: struct {
+ //! A file handle - either a file descriptor used by POSIX or file handle used by Windows. On both platforms the
+ //! handle is always `intptr_t` to make FFI easier (it's basically the size of a pointer / machine register).
+ //!
+ //! \note A handle of value `-1` is considered invalid and/or uninitialized. This value also matches Windows API
+ //! `INVALID_HANDLE_VALUE`, which is also defined to be -1.
+ handle: c.intptr_t,
+}
+
+//! File information.
+FileInfo :: struct {
+ //! \name Members
+ //! \{
+ size: u64,
+ modified_time: i64,
+ flags: FileInfoFlags,
+ uid: u32,
+ gid: u32,
+ reserved: [5]u32,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \name BLFile C API Functions
+ //!
+ //! File read/write functionality is provided by \ref BLFileCore in C API and wrapped by \ref BLFile in C++ API.
+ //!
+ //! \{
+ file_init :: proc(self: ^FileCore) -> Result ---
+ file_reset :: proc(self: ^FileCore) -> Result ---
+ file_open :: proc(self: ^FileCore, file_name: cstring, open_flags: FileOpenFlags) -> Result ---
+ file_close :: proc(self: ^FileCore) -> Result ---
+ file_seek :: proc(self: ^FileCore, offset: i64, seek_type: FileSeekType, position_out: ^i64) -> Result ---
+ file_read :: proc(self: ^FileCore, buffer: rawptr, n: c.size_t, bytes_read_out: ^c.size_t) -> Result ---
+ file_write :: proc(self: ^FileCore, buffer: rawptr, n: c.size_t, bytes_written_out: ^c.size_t) -> Result ---
+ file_truncate :: proc(self: ^FileCore, max_size: i64) -> Result ---
+ file_get_info :: proc(self: ^FileCore, info_out: ^FileInfo) -> Result ---
+ file_get_size :: proc(self: ^FileCore, file_size_out: ^u64) -> Result ---
+
+ //! \name BLFileSystem C API Functions
+ //!
+ //! \{
+ file_system_get_info :: proc(file_name: cstring, info_out: ^FileInfo) -> Result ---
+ file_system_read_file :: proc(file_name: cstring, dst: ^ArrayCore, max_size: c.size_t, read_flags: FileReadFlags) -> Result ---
+ file_system_write_file :: proc(file_name: cstring, data: rawptr, size: c.size_t, bytes_written_out: ^c.size_t) -> Result ---
+}
+
diff --git a/binding/font.odin b/binding/font.odin
@@ -0,0 +1,91 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Font [C API].
+FontCore :: struct {
+ _d: ObjectDetail,
+}
+
+//! \cond INTERNAL
+//! Font [C API Impl].
+FontImpl :: struct {
+ //! Font face used by this font.
+ face: FontFaceCore,
+
+ //! Font width (1..1000) [0 if the font is not initialized].
+ weight: u16,
+
+ //! Font stretch (1..9) [0 if the font is not initialized].
+ stretch: u8,
+
+ //! Font style.
+ style: u8,
+
+ //! Reserved for future use.
+ reserved: u32,
+
+ //! Font metrics.
+ metrics: FontMetrics,
+
+ //! Font matrix.
+ _matrix: FontMatrix,
+
+ //! Assigned font features (key/value pairs).
+ feature_settings: FontFeatureSettingsCore,
+
+ //! Assigned font variations (key/value pairs).
+ variation_settings: FontVariationSettingsCore,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \endcond
+ font_init :: proc(self: ^FontCore) -> Result ---
+ font_init_move :: proc(self: ^FontCore, other: ^FontCore) -> Result ---
+ font_init_weak :: proc(self: ^FontCore, other: ^FontCore) -> Result ---
+ font_destroy :: proc(self: ^FontCore) -> Result ---
+ font_reset :: proc(self: ^FontCore) -> Result ---
+ font_assign_move :: proc(self: ^FontCore, other: ^FontCore) -> Result ---
+ font_assign_weak :: proc(self: ^FontCore, other: ^FontCore) -> Result ---
+ font_equals :: proc(a: ^FontCore, b: ^FontCore) -> i32 ---
+ font_create_from_face :: proc(self: ^FontCore, face: ^FontFaceCore, size: f32) -> Result ---
+ font_create_from_face_with_settings :: proc(self: ^FontCore, face: ^FontFaceCore, size: f32, feature_settings: ^FontFeatureSettingsCore, variation_settings: ^FontVariationSettingsCore) -> Result ---
+ font_get_face :: proc(self: ^FontCore, out: ^FontFaceCore) -> Result ---
+ font_get_size :: proc(self: ^FontCore) -> f32 ---
+ font_set_size :: proc(self: ^FontCore, size: f32) -> Result ---
+ font_get_metrics :: proc(self: ^FontCore, out: ^FontMetrics) -> Result ---
+ font_get_matrix :: proc(self: ^FontCore, out: ^FontMatrix) -> Result ---
+ font_get_design_metrics :: proc(self: ^FontCore, out: ^FontDesignMetrics) -> Result ---
+ font_get_feature_settings :: proc(self: ^FontCore, out: ^FontFeatureSettingsCore) -> Result ---
+ font_set_feature_settings :: proc(self: ^FontCore, feature_settings: ^FontFeatureSettingsCore) -> Result ---
+ font_reset_feature_settings :: proc(self: ^FontCore) -> Result ---
+ font_get_variation_settings :: proc(self: ^FontCore, out: ^FontVariationSettingsCore) -> Result ---
+ font_set_variation_settings :: proc(self: ^FontCore, variation_settings: ^FontVariationSettingsCore) -> Result ---
+ font_reset_variation_settings :: proc(self: ^FontCore) -> Result ---
+ font_shape :: proc(self: ^FontCore, gb: ^GlyphBufferCore) -> Result ---
+ font_map_text_to_glyphs :: proc(self: ^FontCore, gb: ^GlyphBufferCore, state_out: ^GlyphMappingState) -> Result ---
+ font_position_glyphs :: proc(self: ^FontCore, gb: ^GlyphBufferCore) -> Result ---
+ font_apply_kerning :: proc(self: ^FontCore, gb: ^GlyphBufferCore) -> Result ---
+ font_apply_gsub :: proc(self: ^FontCore, gb: ^GlyphBufferCore, lookups: ^BitArrayCore) -> Result ---
+ font_apply_gpos :: proc(self: ^FontCore, gb: ^GlyphBufferCore, lookups: ^BitArrayCore) -> Result ---
+ font_get_text_metrics :: proc(self: ^FontCore, gb: ^GlyphBufferCore, out: ^TextMetrics) -> Result ---
+ font_get_glyph_bounds :: proc(self: ^FontCore, glyph_data: ^u32, glyph_advance: c.intptr_t, out: ^BoxI, count: c.size_t) -> Result ---
+ font_get_glyph_advances :: proc(self: ^FontCore, glyph_data: ^u32, glyph_advance: c.intptr_t, out: ^GlyphPlacement, count: c.size_t) -> Result ---
+ font_get_glyph_outlines :: proc(self: ^FontCore, glyph_id: GlyphId, user_transform: ^Matrix2D, out: ^PathCore, sink: PathSinkFunc, user_data: rawptr) -> Result ---
+ font_get_glyph_run_outlines :: proc(self: ^FontCore, glyph_run: ^GlyphRun, user_transform: ^Matrix2D, out: ^PathCore, sink: PathSinkFunc, user_data: rawptr) -> Result ---
+}
+
diff --git a/binding/fontdata.odin b/binding/fontdata.odin
@@ -0,0 +1,88 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Flags used by \ref BLFontData (or \ref BLFontDataCore).
+FontDataFlags :: enum u32 {
+ //! No flags.
+ NO_FLAGS = 0,
+
+ //!< Font data references a font-collection.
+ FLAG_COLLECTION = 1,
+ FLAG_FORCE_UINT = 4294967295,
+}
+
+//! A read only data that represents a font table or its sub-table.
+FontTable :: struct {
+ //! \name Members
+ //! \{
+
+ //! Pointer to the beginning of the data interpreted as `uint8_t*`.
+ data: ^u8,
+
+ //! Size of `data` in bytes.
+ size: c.size_t,
+}
+
+//! Font data [C API].
+FontDataCore :: struct {
+ _d: ObjectDetail,
+}
+
+//! \cond INTERNAL
+//! Font data [C API Virtual Function Table].
+FontDataVirt :: struct {
+ base: ObjectVirtBase,
+ get_table_tags: proc "c" (impl: ^FontDataImpl, face_index: u32, out: ^ArrayCore) -> Result,
+ get_tables: proc "c" (impl: ^FontDataImpl, face_index: u32, dst: ^FontTable, tags: ^Tag, n: c.size_t) -> c.size_t,
+}
+
+//! Font data [C API Impl].
+FontDataImpl :: struct {
+ //! Virtual function table.
+ virt: ^FontDataVirt,
+
+ //! Type of the face that would be created with this font data.
+ face_type: u8,
+
+ //! Number of font faces stored in this font data instance.
+ face_count: u32,
+
+ //! Font data flags.
+ flags: u32,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \endcond
+ font_data_init :: proc(self: ^FontDataCore) -> Result ---
+ font_data_init_move :: proc(self: ^FontDataCore, other: ^FontDataCore) -> Result ---
+ font_data_init_weak :: proc(self: ^FontDataCore, other: ^FontDataCore) -> Result ---
+ font_data_destroy :: proc(self: ^FontDataCore) -> Result ---
+ font_data_reset :: proc(self: ^FontDataCore) -> Result ---
+ font_data_assign_move :: proc(self: ^FontDataCore, other: ^FontDataCore) -> Result ---
+ font_data_assign_weak :: proc(self: ^FontDataCore, other: ^FontDataCore) -> Result ---
+ font_data_create_from_file :: proc(self: ^FontDataCore, file_name: cstring, read_flags: FileReadFlags) -> Result ---
+ font_data_create_from_data_array :: proc(self: ^FontDataCore, data_array: ^ArrayCore) -> Result ---
+ font_data_create_from_data :: proc(self: ^FontDataCore, data: rawptr, data_size: c.size_t, destroy_func: DestroyExternalDataFunc, user_data: rawptr) -> Result ---
+ font_data_equals :: proc(a: ^FontDataCore, b: ^FontDataCore) -> i32 ---
+ font_data_get_face_count :: proc(self: ^FontDataCore) -> u32 ---
+ font_data_get_face_type :: proc(self: ^FontDataCore) -> FontFaceType ---
+ font_data_get_flags :: proc(self: ^FontDataCore) -> FontDataFlags ---
+ font_data_get_table_tags :: proc(self: ^FontDataCore, face_index: u32, dst: ^ArrayCore) -> Result ---
+ font_data_get_tables :: proc(self: ^FontDataCore, face_index: u32, dst: ^FontTable, tags: ^Tag, count: c.size_t) -> c.size_t ---
+}
+
diff --git a/binding/fontdefs.odin b/binding/fontdefs.odin
@@ -0,0 +1,730 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Orientation.
+Orientation :: enum u32 {
+ //! Horizontal orientation.
+ HORIZONTAL = 0,
+
+ //! Vertical orientation.
+ VERTICAL = 1,
+
+ //! Maximum value of `BLOrientation`.
+ MAX_VALUE = 1,
+ FORCE_UINT = 4294967295,
+}
+
+//! Type of a font or font face, see \ref BLFontFace (or \ref BLFontFaceCore).
+FontFaceType :: enum u32 {
+ //! None or unknown font type.
+ NONE = 0,
+
+ //! TrueType/OpenType font type (.ttf/.otf files and font collections).
+ OPENTYPE = 1,
+
+ //! Maximum value of `BLFontFaceType`.
+ MAX_VALUE = 1,
+ FORCE_UINT = 4294967295,
+}
+
+//! Font stretch.
+FontStretch :: enum u32 {
+ //! Ultra condensed stretch.
+ ULTRA_CONDENSED = 1,
+
+ //! Extra condensed stretch.
+ EXTRA_CONDENSED = 2,
+
+ //! Condensed stretch.
+ CONDENSED = 3,
+
+ //! Semi condensed stretch.
+ SEMI_CONDENSED = 4,
+
+ //! Normal stretch.
+ NORMAL = 5,
+
+ //! Semi expanded stretch.
+ SEMI_EXPANDED = 6,
+
+ //! Expanded stretch.
+ EXPANDED = 7,
+
+ //! Extra expanded stretch.
+ EXTRA_EXPANDED = 8,
+
+ //! Ultra expanded stretch.
+ ULTRA_EXPANDED = 9,
+
+ //! Maximum value of `BLFontStretch`.
+ MAX_VALUE = 9,
+ FORCE_UINT = 4294967295,
+}
+
+//! Font style.
+FontStyle :: enum u32 {
+ //! Normal style.
+ NORMAL = 0,
+
+ //! Oblique.
+ OBLIQUE = 1,
+
+ //! Italic.
+ ITALIC = 2,
+
+ //! Maximum value of `BLFontStyle`.
+ MAX_VALUE = 2,
+ FORCE_UINT = 4294967295,
+}
+
+//! Font weight.
+FontWeight :: enum u32 {
+ //! Thin weight (100).
+ THIN = 100,
+
+ //! Extra light weight (200).
+ EXTRA_LIGHT = 200,
+
+ //! Light weight (300).
+ LIGHT = 300,
+
+ //! Semi light weight (350).
+ SEMI_LIGHT = 350,
+
+ //! Normal weight (400).
+ NORMAL = 400,
+
+ //! Medium weight (500).
+ MEDIUM = 500,
+
+ //! Semi bold weight (600).
+ SEMI_BOLD = 600,
+
+ //! Bold weight (700).
+ BOLD = 700,
+
+ //! Extra bold weight (800).
+ EXTRA_BOLD = 800,
+
+ //! Black weight (900).
+ BLACK = 900,
+
+ //! Extra black weight (950).
+ EXTRA_BLACK = 950,
+ FORCE_UINT = 4294967295,
+}
+
+//! Font string identifiers used by OpenType 'name' table.
+FontStringId :: enum u32 {
+ //! Copyright notice.
+ COPYRIGHT_NOTICE = 0,
+
+ //! Font family name.
+ FAMILY_NAME = 1,
+
+ //! Font subfamily name.
+ SUBFAMILY_NAME = 2,
+
+ //! Unique font identifier.
+ UNIQUE_IDENTIFIER = 3,
+
+ //! Full font name that reflects all family and relevant subfamily descriptors.
+ FULL_NAME = 4,
+
+ //! Version string. Should begin with the synta `Version <number>.<number>`.
+ VERSION_STRING = 5,
+
+ //! PostScript name for the font.
+ POST_SCRIPT_NAME = 6,
+
+ //! Trademark notice/information for this font.
+ TRADEMARK = 7,
+
+ //! Manufacturer name.
+ MANUFACTURER_NAME = 8,
+
+ //! Name of the designer of the typeface.
+ DESIGNER_NAME = 9,
+
+ //! Description of the typeface.
+ DESCRIPTION = 10,
+
+ //! URL of font vendor.
+ VENDOR_URL = 11,
+
+ //! URL of typeface designer.
+ DESIGNER_URL = 12,
+
+ //! Description of how the font may be legally used.
+ LICENSE_DESCRIPTION = 13,
+
+ //! URL where additional licensing information can be found.
+ LICENSE_INFO_URL = 14,
+
+ //! Reserved.
+ RESERVED = 15,
+
+ //! Typographic family name.
+ TYPOGRAPHIC_FAMILY_NAME = 16,
+
+ //! Typographic subfamily name.
+ TYPOGRAPHIC_SUBFAMILY_NAME = 17,
+
+ //! Compatible full name (MAC only).
+ COMPATIBLE_FULL_NAME = 18,
+
+ //! Sample text - font name or any other text from the designer.
+ SAMPLE_TEXT = 19,
+
+ //! PostScript CID findfont name.
+ POST_SCRIPT_CID_NAME = 20,
+
+ //! WWS family name.
+ WWS_FAMILY_NAME = 21,
+
+ //! WWS subfamily name.
+ WWS_SUBFAMILY_NAME = 22,
+
+ //! Light background palette.
+ LIGHT_BACKGROUND_PALETTE = 23,
+
+ //! Dark background palette.
+ DARK_BACKGROUND_PALETTE = 24,
+
+ //! Variations PostScript name prefix.
+ VARIATIONS_POST_SCRIPT_PREFIX = 25,
+
+ //! Count of common font string ids.
+ COMMON_MAX_VALUE = 26,
+
+ //! Start of custom font string ids.
+ CUSTOM_START_INDEX = 255,
+ FORCE_UINT = 4294967295,
+}
+
+//! Bit positions used by \ref BLFontCoverageInfo structure.
+//!
+//! Each bit represents a range (or multiple ranges) of unicode characters.
+FontCoverageGroup :: enum u32 {
+ BASIC_LATIN = 0, //!< [000000-00007F] Basic Latin.
+ LATIN1_SUPPLEMENT = 1, //!< [000080-0000FF] Latin-1 Supplement.
+ LATIN_EXTENDED_A = 2, //!< [000100-00017F] Latin Extended-A.
+ LATIN_EXTENDED_B = 3, //!< [000180-00024F] Latin Extended-B.
+ IPA_EXTENSIONS = 4, //!< [000250-0002AF] IPA Extensions.
+
+ //!< [001D00-001D7F] Phonetic Extensions.
+ //!< [001D80-001DBF] Phonetic Extensions Supplement.
+ SPACING_MODIFIER_LETTERS = 5, //!< [0002B0-0002FF] Spacing Modifier Letters.
+
+ //!< [00A700-00A71F] Modifier Tone Letters.
+ //!< [001DC0-001DFF] Combining Diacritical Marks Supplement.
+ COMBINING_DIACRITICAL_MARKS = 6, //!< [000300-00036F] Combining Diacritical Marks.
+ GREEK_AND_COPTIC = 7, //!< [000370-0003FF] Greek and Coptic.
+ COPTIC = 8, //!< [002C80-002CFF] Coptic.
+ CYRILLIC = 9, //!< [000400-0004FF] Cyrillic.
+
+ //!< [000500-00052F] Cyrillic Supplement.
+ //!< [002DE0-002DFF] Cyrillic Extended-A.
+ //!< [00A640-00A69F] Cyrillic Extended-B.
+ ARMENIAN = 10, //!< [000530-00058F] Armenian.
+ HEBREW = 11, //!< [000590-0005FF] Hebrew.
+ VAI = 12, //!< [00A500-00A63F] Vai.
+ ARABIC = 13, //!< [000600-0006FF] Arabic.
+
+ //!< [000750-00077F] Arabic Supplement.
+ NKO = 14, //!< [0007C0-0007FF] NKo.
+ DEVANAGARI = 15, //!< [000900-00097F] Devanagari.
+ BENGALI = 16, //!< [000980-0009FF] Bengali.
+ GURMUKHI = 17, //!< [000A00-000A7F] Gurmukhi.
+ GUJARATI = 18, //!< [000A80-000AFF] Gujarati.
+ ORIYA = 19, //!< [000B00-000B7F] Oriya.
+ TAMIL = 20, //!< [000B80-000BFF] Tamil.
+ TELUGU = 21, //!< [000C00-000C7F] Telugu.
+ KANNADA = 22, //!< [000C80-000CFF] Kannada.
+ MALAYALAM = 23, //!< [000D00-000D7F] Malayalam.
+ THAI = 24, //!< [000E00-000E7F] Thai.
+ LAO = 25, //!< [000E80-000EFF] Lao.
+ GEORGIAN = 26, //!< [0010A0-0010FF] Georgian.
+
+ //!< [002D00-002D2F] Georgian Supplement.
+ BALINESE = 27, //!< [001B00-001B7F] Balinese.
+ HANGUL_JAMO = 28, //!< [001100-0011FF] Hangul Jamo.
+ LATIN_EXTENDED_ADDITIONAL = 29, //!< [001E00-001EFF] Latin Extended Additional.
+
+ //!< [002C60-002C7F] Latin Extended-C.
+ //!< [00A720-00A7FF] Latin Extended-D.
+ GREEK_EXTENDED = 30, //!< [001F00-001FFF] Greek Extended.
+ GENERAL_PUNCTUATION = 31, //!< [002000-00206F] General Punctuation.
+
+ //!< [002E00-002E7F] Supplemental Punctuation.
+ SUPERSCRIPTS_AND_SUBSCRIPTS = 32, //!< [002070-00209F] Superscripts And Subscripts.
+ CURRENCY_SYMBOLS = 33, //!< [0020A0-0020CF] Currency Symbols.
+ COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS = 34, //!< [0020D0-0020FF] Combining Diacritical Marks For Symbols.
+ LETTERLIKE_SYMBOLS = 35, //!< [002100-00214F] Letterlike Symbols.
+ NUMBER_FORMS = 36, //!< [002150-00218F] Number Forms.
+ ARROWS = 37, //!< [002190-0021FF] Arrows.
+
+ //!< [0027F0-0027FF] Supplemental Arrows-A.
+ //!< [002900-00297F] Supplemental Arrows-B.
+ //!< [002B00-002BFF] Miscellaneous Symbols and Arrows.
+ MATHEMATICAL_OPERATORS = 38, //!< [002200-0022FF] Mathematical Operators.
+
+ //!< [002A00-002AFF] Supplemental Mathematical Operators.
+ //!< [0027C0-0027EF] Miscellaneous Mathematical Symbols-A.
+ //!< [002980-0029FF] Miscellaneous Mathematical Symbols-B.
+ MISCELLANEOUS_TECHNICAL = 39, //!< [002300-0023FF] Miscellaneous Technical.
+ CONTROL_PICTURES = 40, //!< [002400-00243F] Control Pictures.
+ OPTICAL_CHARACTER_RECOGNITION = 41, //!< [002440-00245F] Optical Character Recognition.
+ ENCLOSED_ALPHANUMERICS = 42, //!< [002460-0024FF] Enclosed Alphanumerics.
+ BOX_DRAWING = 43, //!< [002500-00257F] Box Drawing.
+ BLOCK_ELEMENTS = 44, //!< [002580-00259F] Block Elements.
+ GEOMETRIC_SHAPES = 45, //!< [0025A0-0025FF] Geometric Shapes.
+ MISCELLANEOUS_SYMBOLS = 46, //!< [002600-0026FF] Miscellaneous Symbols.
+ DINGBATS = 47, //!< [002700-0027BF] Dingbats.
+ CJK_SYMBOLS_AND_PUNCTUATION = 48, //!< [003000-00303F] CJK Symbols And Punctuation.
+ HIRAGANA = 49, //!< [003040-00309F] Hiragana.
+ KATAKANA = 50, //!< [0030A0-0030FF] Katakana.
+
+ //!< [0031F0-0031FF] Katakana Phonetic Extensions.
+ BOPOMOFO = 51, //!< [003100-00312F] Bopomofo.
+
+ //!< [0031A0-0031BF] Bopomofo Extended.
+ HANGUL_COMPATIBILITY_JAMO = 52, //!< [003130-00318F] Hangul Compatibility Jamo.
+ PHAGS_PA = 53, //!< [00A840-00A87F] Phags-pa.
+ ENCLOSED_CJK_LETTERS_AND_MONTHS = 54, //!< [003200-0032FF] Enclosed CJK Letters And Months.
+ CJK_COMPATIBILITY = 55, //!< [003300-0033FF] CJK Compatibility.
+ HANGUL_SYLLABLES = 56, //!< [00AC00-00D7AF] Hangul Syllables.
+ NON_PLANE = 57, //!< [00D800-00DFFF] Non-Plane 0 *.
+ PHOENICIAN = 58, //!< [010900-01091F] Phoenician.
+ CJK_UNIFIED_IDEOGRAPHS = 59, //!< [004E00-009FFF] CJK Unified Ideographs.
+
+ //!< [002E80-002EFF] CJK Radicals Supplement.
+ //!< [002F00-002FDF] Kangxi Radicals.
+ //!< [002FF0-002FFF] Ideographic Description Characters.
+ //!< [003400-004DBF] CJK Unified Ideographs Extension A.
+ //!< [020000-02A6DF] CJK Unified Ideographs Extension B.
+ //!< [003190-00319F] Kanbun.
+ PRIVATE_USE_PLANE0 = 60, //!< [00E000-00F8FF] Private Use (Plane 0).
+ CJK_STROKES = 61, //!< [0031C0-0031EF] CJK Strokes.
+
+ //!< [00F900-00FAFF] CJK Compatibility Ideographs.
+ //!< [02F800-02FA1F] CJK Compatibility Ideographs Supplement.
+ ALPHABETIC_PRESENTATION_FORMS = 62, //!< [00FB00-00FB4F] Alphabetic Presentation Forms.
+ ARABIC_PRESENTATION_FORMS_A = 63, //!< [00FB50-00FDFF] Arabic Presentation Forms-A.
+ COMBINING_HALF_MARKS = 64, //!< [00FE20-00FE2F] Combining Half Marks.
+ VERTICAL_FORMS = 65, //!< [00FE10-00FE1F] Vertical Forms.
+
+ //!< [00FE30-00FE4F] CJK Compatibility Forms.
+ SMALL_FORM_VARIANTS = 66, //!< [00FE50-00FE6F] Small Form Variants.
+ ARABIC_PRESENTATION_FORMS_B = 67, //!< [00FE70-00FEFF] Arabic Presentation Forms-B.
+ HALFWIDTH_AND_FULLWIDTH_FORMS = 68, //!< [00FF00-00FFEF] Halfwidth And Fullwidth Forms.
+ SPECIALS = 69, //!< [00FFF0-00FFFF] Specials.
+ TIBETAN = 70, //!< [000F00-000FFF] Tibetan.
+ SYRIAC = 71, //!< [000700-00074F] Syriac.
+ THAANA = 72, //!< [000780-0007BF] Thaana.
+ SINHALA = 73, //!< [000D80-000DFF] Sinhala.
+ MYANMAR = 74, //!< [001000-00109F] Myanmar.
+ ETHIOPIC = 75, //!< [001200-00137F] Ethiopic.
+
+ //!< [001380-00139F] Ethiopic Supplement.
+ //!< [002D80-002DDF] Ethiopic Extended.
+ CHEROKEE = 76, //!< [0013A0-0013FF] Cherokee.
+ UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS = 77, //!< [001400-00167F] Unified Canadian Aboriginal Syllabics.
+ OGHAM = 78, //!< [001680-00169F] Ogham.
+ RUNIC = 79, //!< [0016A0-0016FF] Runic.
+ KHMER = 80, //!< [001780-0017FF] Khmer.
+
+ //!< [0019E0-0019FF] Khmer Symbols.
+ MONGOLIAN = 81, //!< [001800-0018AF] Mongolian.
+ BRAILLE_PATTERNS = 82, //!< [002800-0028FF] Braille Patterns.
+ YI_SYLLABLES_AND_RADICALS = 83, //!< [00A000-00A48F] Yi Syllables.
+
+ //!< [00A490-00A4CF] Yi Radicals.
+ TAGALOG_HANUNOO_BUHID_TAGBANWA = 84, //!< [001700-00171F] Tagalog.
+
+ //!< [001720-00173F] Hanunoo.
+ //!< [001740-00175F] Buhid.
+ //!< [001760-00177F] Tagbanwa.
+ OLD_ITALIC = 85, //!< [010300-01032F] Old Italic.
+ GOTHIC = 86, //!< [010330-01034F] Gothic.
+ DESERET = 87, //!< [010400-01044F] Deseret.
+ MUSICAL_SYMBOLS = 88, //!< [01D000-01D0FF] Byzantine Musical Symbols.
+
+ //!< [01D100-01D1FF] Musical Symbols.
+ //!< [01D200-01D24F] Ancient Greek Musical Notation.
+ MATHEMATICAL_ALPHANUMERIC_SYMBOLS = 89, //!< [01D400-01D7FF] Mathematical Alphanumeric Symbols.
+ PRIVATE_USE_PLANE_15_16 = 90, //!< [0F0000-0FFFFD] Private Use (Plane 15).
+
+ //!< [100000-10FFFD] Private Use (Plane 16).
+ VARIATION_SELECTORS = 91, //!< [00FE00-00FE0F] Variation Selectors.
+
+ //!< [0E0100-0E01EF] Variation Selectors Supplement.
+ TAGS = 92, //!< [0E0000-0E007F] Tags.
+ LIMBU = 93, //!< [001900-00194F] Limbu.
+ TAI_LE = 94, //!< [001950-00197F] Tai Le.
+ NEW_TAI_LUE = 95, //!< [001980-0019DF] New Tai Lue.
+ BUGINESE = 96, //!< [001A00-001A1F] Buginese.
+ GLAGOLITIC = 97, //!< [002C00-002C5F] Glagolitic.
+ TIFINAGH = 98, //!< [002D30-002D7F] Tifinagh.
+ YIJING_HEXAGRAM_SYMBOLS = 99, //!< [004DC0-004DFF] Yijing Hexagram Symbols.
+ SYLOTI_NAGRI = 100, //!< [00A800-00A82F] Syloti Nagri.
+ LINEAR_B_SYLLABARY_AND_IDEOGRAMS = 101, //!< [010000-01007F] Linear B Syllabary.
+
+ //!< [010080-0100FF] Linear B Ideograms.
+ //!< [010100-01013F] Aegean Numbers.
+ ANCIENT_GREEK_NUMBERS = 102, //!< [010140-01018F] Ancient Greek Numbers.
+ UGARITIC = 103, //!< [010380-01039F] Ugaritic.
+ OLD_PERSIAN = 104, //!< [0103A0-0103DF] Old Persian.
+ SHAVIAN = 105, //!< [010450-01047F] Shavian.
+ OSMANYA = 106, //!< [010480-0104AF] Osmanya.
+ CYPRIOT_SYLLABARY = 107, //!< [010800-01083F] Cypriot Syllabary.
+ KHAROSHTHI = 108, //!< [010A00-010A5F] Kharoshthi.
+ TAI_XUAN_JING_SYMBOLS = 109, //!< [01D300-01D35F] Tai Xuan Jing Symbols.
+ CUNEIFORM = 110, //!< [012000-0123FF] Cuneiform.
+
+ //!< [012400-01247F] Cuneiform Numbers and Punctuation.
+ COUNTING_ROD_NUMERALS = 111, //!< [01D360-01D37F] Counting Rod Numerals.
+ SUNDANESE = 112, //!< [001B80-001BBF] Sundanese.
+ LEPCHA = 113, //!< [001C00-001C4F] Lepcha.
+ OL_CHIKI = 114, //!< [001C50-001C7F] Ol Chiki.
+ SAURASHTRA = 115, //!< [00A880-00A8DF] Saurashtra.
+ KAYAH_LI = 116, //!< [00A900-00A92F] Kayah Li.
+ REJANG = 117, //!< [00A930-00A95F] Rejang.
+ CHAM = 118, //!< [00AA00-00AA5F] Cham.
+ ANCIENT_SYMBOLS = 119, //!< [010190-0101CF] Ancient Symbols.
+ PHAISTOS_DISC = 120, //!< [0101D0-0101FF] Phaistos Disc.
+ CARIAN_LYCIAN_LYDIAN = 121, //!< [0102A0-0102DF] Carian.
+
+ //!< [010280-01029F] Lycian.
+ //!< [010920-01093F] Lydian.
+ DOMINO_AND_MAHJONG_TILES = 122, //!< [01F030-01F09F] Domino Tiles.
+
+ //!< [01F000-01F02F] Mahjong Tiles.
+ INTERNAL_USAGE_123 = 123, //!< Reserved for internal usage (123).
+ INTERNAL_USAGE_124 = 124, //!< Reserved for internal usage (124).
+ INTERNAL_USAGE_125 = 125, //!< Reserved for internal usage (125).
+ INTERNAL_USAGE_126 = 126, //!< Reserved for internal usage (126).
+ INTERNAL_USAGE_127 = 127, //!< Reserved for internal usage (127).
+
+ //! Maximum value of `BLFontCoverageGroup`.
+ MAX_VALUE = 127,
+ FORCE_UINT = 4294967295,
+}
+
+//! Text direction.
+TextDirection :: enum u32 {
+ //! Left-to-right direction.
+ LTR = 0,
+
+ //! Right-to-left direction.
+ RTL = 1,
+
+ //! Maximum value of `BLTextDirection`.
+ MAX_VALUE = 1,
+ FORCE_UINT = 4294967295,
+}
+
+//! Glyph id - a 32-bit unsigned integer.
+GlyphId :: u32
+
+//! Contains additional information associated with a glyph used by \ref BLGlyphBuffer.
+GlyphInfo :: struct {
+ //! \name Members
+ //! \{
+ cluster: u32,
+ reserved: u32,
+}
+
+//! Glyph placement.
+//!
+//! Provides information about glyph offset (x/y) and advance (x/y).
+GlyphPlacement :: struct {
+ //! \name Members
+ //! \{
+ placement: PointI,
+ advance: PointI,
+}
+
+//! Character to glyph mapping state.
+GlyphMappingState :: struct {
+ //! \name Members
+ //! \{
+
+ //! Number of glyphs or glyph-items on output.
+ glyph_count: c.size_t,
+
+ //! Index of the first undefined glyph (SIZE_MAX if none).
+ undefined_first: c.size_t,
+
+ //! Undefined glyph count (chars that have no mapping).
+ undefined_count: c.size_t,
+}
+
+//! Information passed to a \ref BLPathSinkFunc sink by \ref BLFont::get_glyph_outlines().
+GlyphOutlineSinkInfo :: struct {
+ glyph_index: c.size_t,
+ contour_count: c.size_t,
+}
+
+//! Font coverage information struct provides information about ranges of unicode characters supported by a font-face.
+//!
+//! \remarks The information is stored in "OS/2" table in TTF/OTF font. Blend2D reads this information and populates
+//! `BLFontCoverageInfo` struct from such data, however, there is no guarantee that what font describes is actually
+//! true.
+FontCoverageInfo :: struct {
+ //! \name Members
+ //! \{
+
+ //! Unicode coverage data as a bit array of 4 32-bit unsigned integers.
+ data: [4]u32,
+}
+
+//! Font PANOSE classification.
+FontPanoseInfo :: struct {
+ using _: struct #raw_union {
+ data: [10]u8,
+ family_kind: u8,
+
+ text: struct {
+ family_kind: u8,
+ serif_style: u8,
+ weight: u8,
+ proportion: u8,
+ contrast: u8,
+ stroke_variation: u8,
+ arm_style: u8,
+ letterform: u8,
+ midline: u8,
+ x_height: u8,
+ },
+
+ script: struct {
+ family_kind: u8,
+ tool_kind: u8,
+ weight: u8,
+ spacing: u8,
+ aspect_ratio: u8,
+ contrast: u8,
+ topology: u8,
+ form: u8,
+ finials: u8,
+ x_ascent: u8,
+ },
+
+ decorative: struct {
+ family_kind: u8,
+ decorative_class: u8,
+ weight: u8,
+ aspect: u8,
+ contrast: u8,
+ serif_variant: u8,
+ treatment: u8,
+ lining: u8,
+ topology: u8,
+ character_range: u8,
+ },
+
+ symbol: struct {
+ family_kind: u8,
+ symbol_kind: u8,
+ weight: u8,
+ spacing: u8,
+ aspect_ratio_and_contrast: u8,
+ aspect_ratio_94: u8,
+ aspect_ratio_119: u8,
+ aspect_ratio_157: u8,
+ aspect_ratio_163: u8,
+ aspect_ratio_211: u8,
+ },
+ },
+}
+
+//! 2x2 transformation matrix used by \ref BLFont. It's similar to \ref BLMatrix2D,
+//! however, it doesn't provide a translation part as it's assumed to be zero.
+FontMatrix :: struct {
+ using _: struct #raw_union {
+ m: [4]f64,
+
+ using _: struct {
+ m00: f64,
+ m01: f64,
+ m10: f64,
+ m11: f64,
+ },
+ },
+}
+
+//! Scaled \ref BLFontDesignMetrics based on font size and other properties.
+FontMetrics :: struct {
+ //! Font size.
+ size: f32,
+
+ using _: struct #raw_union {
+ using _: struct {
+ //! Font ascent (horizontal orientation).
+ ascent: f32,
+
+ //! Font ascent (vertical orientation).
+ v_ascent: f32,
+
+ //! Font descent (horizontal orientation).
+ descent: f32,
+
+ //! Font descent (vertical orientation).
+ v_descent: f32,
+ },
+
+ using _: struct {
+ ascent_by_orientation: [2]f32,
+ descent_by_orientation: [2]f32,
+ },
+ },
+
+ //! Line gap.
+ line_gap: f32,
+
+ //! Distance between the baseline and the mean line of lower-case letters.
+ x_height: f32,
+
+ //! Maximum height of a capital letter above the baseline.
+ cap_height: f32,
+
+ //! Minimum x, reported by the font.
+ x_min: f32,
+
+ //! Minimum y, reported by the font.
+ y_min: f32,
+
+ //! Maximum x, reported by the font.
+ x_max: f32,
+
+ //! Maximum y, reported by the font.
+ y_max: f32,
+
+ //! Text underline position.
+ underline_position: f32,
+
+ //! Text underline thickness.
+ underline_thickness: f32,
+
+ //! Text strikethrough position.
+ strikethrough_position: f32,
+
+ //! Text strikethrough thickness.
+ strikethrough_thickness: f32,
+}
+
+//! Design metrics of a font.
+//!
+//! Design metrics is information that \ref BLFontFace collected directly from the font data. It means that all
+//! fields are measured in font design units.
+//!
+//! When a new \ref BLFont instance is created a scaled metrics \ref BLFontMetrics is automatically calculated
+//! from \ref BLFontDesignMetrics including other members like transformation, etc...
+FontDesignMetrics :: struct {
+ //! Units per EM square.
+ units_per_em: i32,
+
+ //! Lowest readable size in pixels.
+ lowest_ppem: i32,
+
+ //! Line gap.
+ line_gap: i32,
+
+ //! Distance between the baseline and the mean line of lower-case letters.
+ x_height: i32,
+
+ //! Maximum height of a capital letter above the baseline.
+ cap_height: i32,
+
+ using _: struct #raw_union {
+ using _: struct {
+ //! Ascent (horizontal layout).
+ ascent: i32,
+
+ //! Ascent (vertical layout).
+ v_ascent: i32,
+
+ //! Descent (horizontal layout).
+ descent: i32,
+
+ //! Descent (vertical layout).
+ v_descent: i32,
+
+ //! Minimum leading-side bearing (horizontal layout).
+ h_min_lsb: i32,
+
+ //! Minimum leading-side bearing (vertical layout).
+ v_min_lsb: i32,
+
+ //! Minimum trailing-side bearing (horizontal layout).
+ h_min_tsb: i32,
+
+ //! Minimum trailing-side bearing (vertical layout).
+ v_min_tsb: i32,
+
+ //! Maximum advance (horizontal layout).
+ h_max_advance: i32,
+
+ //! Maximum advance (vertical layout).
+ v_max_advance: i32,
+ },
+
+ using _: struct {
+ //! Horizontal & vertical ascents.
+ ascent_by_orientation: [2]i32,
+
+ //! Horizontal & vertical descents.
+ descent_by_orientation: [2]i32,
+
+ //! Minimum leading-side bearing (horizontal and vertical).
+ min_lsb_by_orientation: [2]i32,
+
+ //! Minimum trailing-side bearing (horizontal and vertical)..
+ min_tsb_by_orientation: [2]i32,
+
+ //! Maximum advance width (horizontal) and height (vertical).
+ max_advance_by_orientation: [2]i32,
+ },
+ },
+
+ //! Aggregated bounding box of all glyphs in the font.
+ //!
+ //! \note This value is reported by the font data so it's not granted to be true.
+ glyph_bounding_box: BoxI,
+
+ //! Text underline position.
+ underline_position: i32,
+
+ //! Text underline thickness.
+ underline_thickness: i32,
+
+ //! Text strikethrough position.
+ strikethrough_position: i32,
+
+ //! Text strikethrough thickness.
+ strikethrough_thickness: i32,
+}
+
+//! Text metrics.
+TextMetrics :: struct {
+ advance: Point,
+ leading_bearing: Point,
+ trailing_bearing: Point,
+ bounding_box: Box,
+}
+
diff --git a/binding/fontface.odin b/binding/fontface.odin
@@ -0,0 +1,234 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Flags used by \ref BLFontFace (or \ref BLFontFaceCore)
+FontFaceFlags :: enum u32 {
+ //! No flags.
+ NO_FLAGS = 0,
+
+ //! Font uses typographic family and subfamily names.
+ FLAG_TYPOGRAPHIC_NAMES = 1,
+
+ //! Font uses typographic metrics.
+ FLAG_TYPOGRAPHIC_METRICS = 2,
+
+ //! Character to glyph mapping is available.
+ FLAG_CHAR_TO_GLYPH_MAPPING = 4,
+
+ //! Horizontal glyph metrics (advances, side bearings) is available.
+ FLAG_HORIZONTAL_METRICS = 16,
+
+ //! Vertical glyph metrics (advances, side bearings) is available.
+ FLAG_VERTICAL_METRICS = 32,
+
+ //! Legacy horizontal kerning feature ('kern' table with horizontal kerning data).
+ FLAG_HORIZONTAL_KERNING = 64,
+
+ //! Legacy vertical kerning feature ('kern' table with vertical kerning data).
+ FLAG_VERTICAL_KERNING = 128,
+
+ //! OpenType features (GDEF, GPOS, GSUB) are available.
+ FLAG_OPENTYPE_FEATURES = 256,
+
+ //! Panose classification is available.
+ FLAG_PANOSE_INFO = 512,
+
+ //! Unicode coverage information is available.
+ FLAG_COVERAGE_INFO = 1024,
+
+ //! Baseline for font at `y` equals 0.
+ FLAG_BASELINE_Y_EQUALS_0 = 4096,
+
+ //! Left sidebearing point at `x == 0` (TT only).
+ FLAG_LSB_POINT_X_EQUALS_0 = 8192,
+
+ //! Unicode variation sequences feature is available.
+ FLAG_VARIATION_SEQUENCES = 268435456,
+
+ //! OpenType Font Variations feature is available.
+ FLAG_OPENTYPE_VARIATIONS = 536870912,
+
+ //! This is a symbol font.
+ FLAG_SYMBOL_FONT = 1073741824,
+
+ //! This is a last resort font.
+ FLAG_LAST_RESORT_FONT = 2147483648,
+ FLAG_FORCE_UINT = 4294967295,
+}
+
+//! Diagnostic flags offered by \ref BLFontFace (or \ref BLFontFaceCore).
+FontFaceDiagFlags :: enum u32 {
+ //! No flags.
+ NO_FLAGS = 0,
+
+ //! Wrong data in 'name' table.
+ WRONG_NAME_DATA = 1,
+
+ //! Fixed data read from 'name' table and possibly fixed font family/subfamily name.
+ FIXED_NAME_DATA = 2,
+
+ //! Wrong data in 'kern' table [kerning disabled].
+ WRONG_KERN_DATA = 4,
+
+ //! Fixed data read from 'kern' table so it can be used.
+ FIXED_KERN_DATA = 8,
+
+ //! Wrong data in 'cmap' table.
+ WRONG_CMAP_DATA = 16,
+
+ //! Wrong format in 'cmap' (sub)table.
+ WRONG_CMAP_FORMAT = 32,
+ FORCE_UINT = 4294967295,
+}
+
+//! Format of an outline stored in a font.
+FontOutlineType :: enum u32 {
+ //! None.
+ NONE = 0,
+
+ //! Truetype outlines.
+ TRUETYPE = 1,
+
+ //! OpenType (CFF) outlines.
+ CFF = 2,
+
+ //! OpenType (CFF2) outlines with font variations support.
+ CFF2 = 3,
+
+ //! Maximum value of `BLFontOutlineType`.
+ MAX_VALUE = 3,
+ FORCE_UINT = 4294967295,
+}
+
+//! Information of \ref BLFontFace.
+FontFaceInfo :: struct {
+ //! \name Members
+ //! \{
+
+ //! Font face type, see \ref BLFontFaceType.
+ face_type: u8,
+
+ //! Type of outlines used by the font face, see \ref BLFontOutlineType.
+ outline_type: u8,
+
+ //! Reserved fields.
+ reserved8: [2]u8,
+
+ //! Number of glyphs provided by this font face.
+ glyph_count: u32,
+
+ //! Revision (read from 'head' table, represented as 16.16 fixed point).
+ revision: u32,
+
+ //! Face face index in a TTF/OTF collection or zero if not part of a collection.
+ face_index: u32,
+
+ //! Font face flags, see \ref BLFontFaceFlags
+ face_flags: u32,
+
+ //! Font face diagnostic flags, see \ref BLFontFaceDiagFlags.
+ diag_flags: u32,
+
+ //! Reserved for future use, set to zero.
+ reserved: [2]u32,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \name BLFontFace - C API
+ //! \{
+ font_face_init :: proc(self: ^FontFaceCore) -> Result ---
+ font_face_init_move :: proc(self: ^FontFaceCore, other: ^FontFaceCore) -> Result ---
+ font_face_init_weak :: proc(self: ^FontFaceCore, other: ^FontFaceCore) -> Result ---
+ font_face_destroy :: proc(self: ^FontFaceCore) -> Result ---
+ font_face_reset :: proc(self: ^FontFaceCore) -> Result ---
+ font_face_assign_move :: proc(self: ^FontFaceCore, other: ^FontFaceCore) -> Result ---
+ font_face_assign_weak :: proc(self: ^FontFaceCore, other: ^FontFaceCore) -> Result ---
+ font_face_equals :: proc(a: ^FontFaceCore, b: ^FontFaceCore) -> i32 ---
+ font_face_create_from_file :: proc(self: ^FontFaceCore, file_name: cstring, read_flags: FileReadFlags) -> Result ---
+ font_face_create_from_data :: proc(self: ^FontFaceCore, font_data: ^FontDataCore, face_index: u32) -> Result ---
+ font_face_get_full_name :: proc(self: ^FontFaceCore, out: ^StringCore) -> Result ---
+ font_face_get_family_name :: proc(self: ^FontFaceCore, out: ^StringCore) -> Result ---
+ font_face_get_subfamily_name :: proc(self: ^FontFaceCore, out: ^StringCore) -> Result ---
+ font_face_get_post_script_name :: proc(self: ^FontFaceCore, out: ^StringCore) -> Result ---
+ font_face_get_face_info :: proc(self: ^FontFaceCore, out: ^FontFaceInfo) -> Result ---
+ font_face_get_design_metrics :: proc(self: ^FontFaceCore, out: ^FontDesignMetrics) -> Result ---
+ font_face_get_coverage_info :: proc(self: ^FontFaceCore, out: ^FontCoverageInfo) -> Result ---
+ font_face_get_panose_info :: proc(self: ^FontFaceCore, out: ^FontPanoseInfo) -> Result ---
+ font_face_get_character_coverage :: proc(self: ^FontFaceCore, out: ^BitSetCore) -> Result ---
+ font_face_has_script_tag :: proc(self: ^FontFaceCore, script_tag: Tag) -> i32 ---
+ font_face_has_feature_tag :: proc(self: ^FontFaceCore, feature_tag: Tag) -> i32 ---
+ font_face_has_variation_tag :: proc(self: ^FontFaceCore, variation_tag: Tag) -> i32 ---
+ font_face_get_script_tags :: proc(self: ^FontFaceCore, out: ^ArrayCore) -> Result ---
+ font_face_get_feature_tags :: proc(self: ^FontFaceCore, out: ^ArrayCore) -> Result ---
+ font_face_get_variation_tags :: proc(self: ^FontFaceCore, out: ^ArrayCore) -> Result ---
+}
+
+//! Font face [C API].
+FontFaceCore :: struct {
+ _d: ObjectDetail,
+}
+
+//! \cond INTERNAL
+//! Font face [C API Virtual Function Table].
+FontFaceVirt :: struct {
+ base: ObjectVirtBase,
+}
+
+//! Font face [C API Impl].
+FontFaceImpl :: struct {
+ //! Virtual function table.
+ virt: ^FontFaceVirt,
+
+ //! Font face default weight (1..1000) [0 if font face is not initialized].
+ weight: u16,
+
+ //! Font face default stretch (1..9) [0 if font face is not initialized].
+ stretch: u8,
+
+ //! Font face default style.
+ style: u8,
+
+ //! Font face information.
+ face_info: FontFaceInfo,
+
+ //! Unique identifier assigned by Blend2D that can be used for caching.
+ unique_id: UniqueId,
+
+ //! Font data.
+ data: FontDataCore,
+
+ //! Full name.
+ full_name: StringCore,
+
+ //! Family name.
+ family_name: StringCore,
+
+ //! Subfamily name.
+ subfamily_name: StringCore,
+
+ //! PostScript name.
+ post_script_name: StringCore,
+
+ //! Font face metrics in design units.
+ design_metrics: FontDesignMetrics,
+
+ //! Font face unicode coverage information as specified in the "OS/2" header.
+ coverage_info: FontCoverageInfo,
+
+ //! Font face panose classification.
+ panose_info: FontPanoseInfo,
+}
+
diff --git a/binding/fontfeaturesettings.odin b/binding/fontfeaturesettings.odin
@@ -0,0 +1,100 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Font feature settings [C API].
+FontFeatureSettingsCore :: struct {
+ _d: ObjectDetail,
+}
+
+//! \cond INTERNAL
+//! Font feature settings [C API Impl].
+//!
+//! \note This Impl's layout is fully compatible with \ref BLArrayImpl.
+FontFeatureSettingsImpl :: struct {
+ //! Pointer to feature items.
+ data: ^FontFeatureItem,
+
+ //! Number of feature items in `data`.
+ size: c.size_t,
+
+ //! Capacity of `data`.
+ capacity: c.size_t,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \endcond
+ font_feature_settings_init :: proc(self: ^FontFeatureSettingsCore) -> Result ---
+ font_feature_settings_init_move :: proc(self: ^FontFeatureSettingsCore, other: ^FontFeatureSettingsCore) -> Result ---
+ font_feature_settings_init_weak :: proc(self: ^FontFeatureSettingsCore, other: ^FontFeatureSettingsCore) -> Result ---
+ font_feature_settings_destroy :: proc(self: ^FontFeatureSettingsCore) -> Result ---
+ font_feature_settings_reset :: proc(self: ^FontFeatureSettingsCore) -> Result ---
+ font_feature_settings_clear :: proc(self: ^FontFeatureSettingsCore) -> Result ---
+ font_feature_settings_shrink :: proc(self: ^FontFeatureSettingsCore) -> Result ---
+ font_feature_settings_assign_move :: proc(self: ^FontFeatureSettingsCore, other: ^FontFeatureSettingsCore) -> Result ---
+ font_feature_settings_assign_weak :: proc(self: ^FontFeatureSettingsCore, other: ^FontFeatureSettingsCore) -> Result ---
+ font_feature_settings_get_size :: proc(self: ^FontFeatureSettingsCore) -> c.size_t ---
+ font_feature_settings_get_capacity :: proc(self: ^FontFeatureSettingsCore) -> c.size_t ---
+ font_feature_settings_get_view :: proc(self: ^FontFeatureSettingsCore, out: ^FontFeatureSettingsView) -> Result ---
+ font_feature_settings_has_value :: proc(self: ^FontFeatureSettingsCore, feature_tag: Tag) -> i32 ---
+ font_feature_settings_get_value :: proc(self: ^FontFeatureSettingsCore, feature_tag: Tag) -> u32 ---
+ font_feature_settings_set_value :: proc(self: ^FontFeatureSettingsCore, feature_tag: Tag, value: u32) -> Result ---
+ font_feature_settings_remove_value :: proc(self: ^FontFeatureSettingsCore, feature_tag: Tag) -> Result ---
+ font_feature_settings_equals :: proc(a: ^FontFeatureSettingsCore, b: ^FontFeatureSettingsCore) -> i32 ---
+}
+
+//! Associates a font feature tag with a value. Tag describes the feature (as provided by the font) and `value`
+//! describes its value. Some features only allow boolean values 0 and 1 and some allow values up to 65535.
+//! Values above 65535 are invalid, however, only \ref BL_FONT_FEATURE_INVALID_VALUE should be used as invalid
+//! value in general.
+//!
+//! Registered OpenType features:
+//! - https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags
+//! - https://helpx.adobe.com/typekit/using/open-type-syntax.html
+FontFeatureItem :: struct {
+ //! \name Members
+ //! \{
+
+ //! Feature tag (32-bit).
+ tag: Tag,
+
+ //! Feature value.
+ //!
+ //! \note values greater than 65535 are invalid.
+ value: u32,
+}
+
+//! A view unifying the representation of an internal storage used by \ref BLFontFeatureSettings.
+FontFeatureSettingsView :: struct {
+ //! \name Members
+ //! \{
+
+ //! Pointer to font feature items, where each item describes a tag and its value.
+ //!
+ //! \note If the container is in SSO mode the `data` member will point to `sso_data`.
+ data: ^FontFeatureItem,
+
+ //! Count of items in `data.
+ size: c.size_t,
+
+ //! Unpacked SSO items into \ref BLFontFeatureItem array.
+ //!
+ //! \note This member won't be initialized or zeroed in case \ref BLFontFeatureSettings is not in SSO mode. And if the
+ //! container is in SSO mode only the number of items used will be overwritten by \ref BLFontFeatureSettings::get_view().
+ sso_data: [36]FontFeatureItem,
+}
+
diff --git a/binding/fontmanager.odin b/binding/fontmanager.odin
@@ -0,0 +1,72 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Font manager [C API].
+FontManagerCore :: struct {
+ _d: ObjectDetail,
+}
+
+//! \cond INTERNAL
+//! Font manager [C API Virtual Function Table].
+FontManagerVirt :: struct {
+ base: ObjectVirtBase,
+}
+
+//! Font manager [C API Impl].
+FontManagerImpl :: struct {
+ //! Virtual function table.
+ virt: ^FontManagerVirt,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \endcond
+ font_manager_init :: proc(self: ^FontManagerCore) -> Result ---
+ font_manager_init_move :: proc(self: ^FontManagerCore, other: ^FontManagerCore) -> Result ---
+ font_manager_init_weak :: proc(self: ^FontManagerCore, other: ^FontManagerCore) -> Result ---
+ font_manager_init_new :: proc(self: ^FontManagerCore) -> Result ---
+ font_manager_destroy :: proc(self: ^FontManagerCore) -> Result ---
+ font_manager_reset :: proc(self: ^FontManagerCore) -> Result ---
+ font_manager_assign_move :: proc(self: ^FontManagerCore, other: ^FontManagerCore) -> Result ---
+ font_manager_assign_weak :: proc(self: ^FontManagerCore, other: ^FontManagerCore) -> Result ---
+ font_manager_create :: proc(self: ^FontManagerCore) -> Result ---
+ font_manager_get_face_count :: proc(self: ^FontManagerCore) -> c.size_t ---
+ font_manager_get_family_count :: proc(self: ^FontManagerCore) -> c.size_t ---
+ font_manager_has_face :: proc(self: ^FontManagerCore, face: ^FontFaceCore) -> i32 ---
+ font_manager_add_face :: proc(self: ^FontManagerCore, face: ^FontFaceCore) -> Result ---
+ font_manager_query_face :: proc(self: ^FontManagerCore, name: cstring, name_size: c.size_t, properties: ^FontQueryProperties, out: ^FontFaceCore) -> Result ---
+ font_manager_query_faces_by_family_name :: proc(self: ^FontManagerCore, name: cstring, name_size: c.size_t, out: ^ArrayCore) -> Result ---
+ font_manager_equals :: proc(a: ^FontManagerCore, b: ^FontManagerCore) -> i32 ---
+}
+
+//! Properties that can be used to query \ref BLFont and \ref BLFontFace.
+//!
+//! \sa BLFontManager.
+FontQueryProperties :: struct {
+ //! \name Members
+ //! \{
+
+ //! Font style.
+ style: u32,
+
+ //! Font weight.
+ weight: u32,
+
+ //! Font stretch.
+ stretch: u32,
+}
+
diff --git a/binding/fontvariationsettings.odin b/binding/fontvariationsettings.odin
@@ -0,0 +1,91 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Font variation settings [C API].
+FontVariationSettingsCore :: struct {
+ _d: ObjectDetail,
+}
+
+//! \cond INTERNAL
+//! Font variation settings [C API Impl].
+//!
+//! \note This Impl's layout is fully compatible with \ref BLArrayImpl.
+FontVariationSettingsImpl :: struct {
+ //! Pointer to variation items.
+ data: ^FontVariationItem,
+
+ //! Number of variation items in `data`.
+ size: c.size_t,
+
+ //! Capacity of `data`.
+ capacity: c.size_t,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \endcond
+ font_variation_settings_init :: proc(self: ^FontVariationSettingsCore) -> Result ---
+ font_variation_settings_init_move :: proc(self: ^FontVariationSettingsCore, other: ^FontVariationSettingsCore) -> Result ---
+ font_variation_settings_init_weak :: proc(self: ^FontVariationSettingsCore, other: ^FontVariationSettingsCore) -> Result ---
+ font_variation_settings_destroy :: proc(self: ^FontVariationSettingsCore) -> Result ---
+ font_variation_settings_reset :: proc(self: ^FontVariationSettingsCore) -> Result ---
+ font_variation_settings_clear :: proc(self: ^FontVariationSettingsCore) -> Result ---
+ font_variation_settings_shrink :: proc(self: ^FontVariationSettingsCore) -> Result ---
+ font_variation_settings_assign_move :: proc(self: ^FontVariationSettingsCore, other: ^FontVariationSettingsCore) -> Result ---
+ font_variation_settings_assign_weak :: proc(self: ^FontVariationSettingsCore, other: ^FontVariationSettingsCore) -> Result ---
+ font_variation_settings_get_size :: proc(self: ^FontVariationSettingsCore) -> c.size_t ---
+ font_variation_settings_get_capacity :: proc(self: ^FontVariationSettingsCore) -> c.size_t ---
+ font_variation_settings_get_view :: proc(self: ^FontVariationSettingsCore, out: ^FontVariationSettingsView) -> Result ---
+ font_variation_settings_has_value :: proc(self: ^FontVariationSettingsCore, variation_tag: Tag) -> i32 ---
+ font_variation_settings_get_value :: proc(self: ^FontVariationSettingsCore, variation_tag: Tag) -> f32 ---
+ font_variation_settings_set_value :: proc(self: ^FontVariationSettingsCore, variation_tag: Tag, value: f32) -> Result ---
+ font_variation_settings_remove_value :: proc(self: ^FontVariationSettingsCore, variation_tag: Tag) -> Result ---
+ font_variation_settings_equals :: proc(a: ^FontVariationSettingsCore, b: ^FontVariationSettingsCore) -> i32 ---
+}
+
+//! Associates a font variation tag with a value.
+FontVariationItem :: struct {
+ //! \name Members
+ //! \{
+
+ //! Variation tag (32-bit).
+ tag: Tag,
+
+ //! Variation value.
+ //!
+ //! \note values outside of [0, 1] range are invalid.
+ value: f32,
+}
+
+//! A view unifying the representation of an internal storage used by \ref BLFontVariationSettings.
+FontVariationSettingsView :: struct {
+ //! Pointer to font variation items, where each item describes a variation tag and its value.
+ //!
+ //! \note If the container is in SSO mode the `data` member will point to `sso_data`.
+ data: ^FontVariationItem,
+
+ //! Count of items in `data.
+ size: c.size_t,
+
+ //! Unpacked SSO items into \ref BLFontVariationItem array.
+ //!
+ //! \note This member won't be initialized or zeroed in case \ref BLFontVariationSettings is not in
+ //! SSO mode. And if the container is in SSO mode only the number of items used will be overwritten
+ //! by \ref BLFontVariationSettings::get_view().
+ sso_data: [3]FontVariationItem,
+}
+
diff --git a/binding/format.odin b/binding/format.odin
@@ -0,0 +1,140 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Pixel format.
+//!
+//! Compatibility Table
+//! -------------------
+//!
+//! ```
+//! +---------------------+---------------------+-----------------------------+
+//! | Blend2D Format | Cairo Format | QImage::Format |
+//! +---------------------+---------------------+-----------------------------+
+//! | BL_FORMAT_PRGB32 | CAIRO_FORMAT_ARGB32 | Format_ARGB32_Premultiplied |
+//! | BL_FORMAT_XRGB32 | CAIRO_FORMAT_RGB24 | Format_RGB32 |
+//! | BL_FORMAT_A8 | CAIRO_FORMAT_A8 | n/a |
+//! +---------------------+---------------------+-----------------------------+
+//! ```
+Format :: enum u32 {
+ //! None or invalid pixel format.
+ NONE = 0,
+
+ //! 32-bit premultiplied ARGB pixel format (8-bit components).
+ PRGB32 = 1,
+
+ //! 32-bit (X)RGB pixel format (8-bit components, alpha ignored).
+ XRGB32 = 2,
+
+ //! 8-bit alpha-only pixel format.
+ A8 = 3,
+
+ // Maximum value of `BLFormat`.
+ MAX_VALUE = 3,
+ FORCE_UINT = 4294967295,
+}
+
+//! Pixel format flags.
+FormatFlags :: enum u32 {
+ //! No flags.
+ NO_FLAGS = 0,
+
+ //! Pixel format provides RGB components.
+ FLAG_RGB = 1,
+
+ //! Pixel format provides only alpha component.
+ FLAG_ALPHA = 2,
+
+ //! A combination of `BL_FORMAT_FLAG_RGB | BL_FORMAT_FLAG_ALPHA`.
+ FLAG_RGBA = 3,
+
+ //! Pixel format provides LUM component (and not RGB components).
+ FLAG_LUM = 4,
+
+ //! A combination of `BL_FORMAT_FLAG_LUM | BL_FORMAT_FLAG_ALPHA`.
+ FLAG_LUMA = 6,
+
+ //! Indexed pixel format the requires a palette (I/O only).
+ FLAG_INDEXED = 16,
+
+ //! RGB components are premultiplied by alpha component.
+ FLAG_PREMULTIPLIED = 256,
+
+ //! Pixel format doesn't use native byte-order (I/O only).
+ FLAG_BYTE_SWAP = 512,
+
+ // The following flags are only informative. They are part of `bl_format_info[]`, but don't have to be passed to
+ // `BLPixelConverter` as they will always be calculated automatically.
+
+ //! Pixel components are byte aligned (all 8bpp).
+ FLAG_BYTE_ALIGNED = 65536,
+
+ //! Pixel has some undefined bits that represent no information.
+ //!
+ //! For example a 32-bit XRGB pixel has 8 undefined bits that are usually set to all ones so the format can be
+ //! interpreted as premultiplied RGB as well. There are other formats like 16_0555 where the bit has no information
+ //! and is usually set to zero. Blend2D doesn't rely on the content of such bits.
+ FLAG_UNDEFINED_BITS = 131072,
+
+ //! Convenience flag that contains either zero or `BL_FORMAT_FLAG_BYTE_SWAP` depending on host byte order. Little
+ //! endian hosts have this flag set to zero and big endian hosts to `BL_FORMAT_FLAG_BYTE_SWAP`.
+ //!
+ //! \note This is not a real flag that you can test, it's only provided for convenience to define little endian
+ //! pixel formats.
+ FLAG_LE = 0,
+
+ //! Convenience flag that contains either zero or `BL_FORMAT_FLAG_BYTE_SWAP` depending on host byte order. Big
+ //! endian hosts have this flag set to zero and little endian hosts to `BL_FORMAT_FLAG_BYTE_SWAP`.
+ //!
+ //! \note This is not a real flag that you can test, it's only provided for convenience to define big endian
+ //! pixel formats.
+ FLAG_BE = 512,
+ FLAG_FORCE_UINT = 4294967295,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \name BLFormat - C API
+ //! \{
+ format_info_query :: proc(self: ^FormatInfo, format: Format) -> Result ---
+ format_info_sanitize :: proc(self: ^FormatInfo) -> Result ---
+}
+
+//! Provides a detailed information about a pixel format. Use \ref bl_format_info array to get an information of Blend2D
+//! native pixel formats.
+FormatInfo :: struct {
+ depth: u32,
+ flags: FormatFlags,
+
+ using _: struct #raw_union {
+ using _: struct {
+ sizes: [4]u8,
+ shifts: [4]u8,
+ },
+
+ using _: struct {
+ r_size: u8,
+ g_size: u8,
+ b_size: u8,
+ a_size: u8,
+ r_shift: u8,
+ g_shift: u8,
+ b_shift: u8,
+ a_shift: u8,
+ },
+
+ palette: ^Rgba32,
+ },
+}
+
diff --git a/binding/geometry.odin b/binding/geometry.odin
@@ -0,0 +1,244 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Direction of a geometry used by geometric primitives and paths.
+GeometryDirection :: enum u32 {
+ //! No direction specified.
+ NONE = 0,
+
+ //! Clockwise direction.
+ CW = 1,
+
+ //! Counter-clockwise direction.
+ CCW = 2,
+ FORCE_UINT = 4294967295,
+}
+
+//! Geometry type.
+//!
+//! Geometry describes a shape or path that can be either rendered or added to a BLPath container. Both \ref BLPath
+//! and \ref BLContext provide functionality to work with all geometry types. Please note that each type provided
+//! here requires to pass a matching struct or class to the function that consumes a `geometry_type` and `geometry_data`
+//! arguments.
+//!
+//! \cond INTERNAL
+//! \note Always modify `BL_GEOMETRY_TYPE_SIMPLE_LAST` and related functions when adding a new type to `BLGeometryType`
+//! enum. Some functions just pass the geometry type and data to another function, but the rendering context must copy
+//! simple types to a render job, which means that it must know which type is simple and also sizes of all simple
+//! types, see `geometry_p.h` for more details about handling simple types.
+//! \endcond
+GeometryType :: enum u32 {
+ //! No geometry provided.
+ NONE = 0,
+
+ //! BLBoxI struct.
+ BOXI = 1,
+
+ //! BLBox struct.
+ BOXD = 2,
+
+ //! BLRectI struct.
+ RECTI = 3,
+
+ //! BLRect struct.
+ RECTD = 4,
+
+ //! BLCircle struct.
+ CIRCLE = 5,
+
+ //! BLEllipse struct.
+ ELLIPSE = 6,
+
+ //! BLRoundRect struct.
+ ROUND_RECT = 7,
+
+ //! BLArc struct.
+ ARC = 8,
+
+ //! BLArc struct representing chord.
+ CHORD = 9,
+
+ //! BLArc struct representing pie.
+ PIE = 10,
+
+ //! BLLine struct.
+ LINE = 11,
+
+ //! BLTriangle struct.
+ TRIANGLE = 12,
+
+ //! BLArrayView<BLPointI> representing a polyline.
+ POLYLINEI = 13,
+
+ //! BLArrayView<BLPoint> representing a polyline.
+ POLYLINED = 14,
+
+ //! BLArrayView<BLPointI> representing a polygon.
+ POLYGONI = 15,
+
+ //! BLArrayView<BLPoint> representing a polygon.
+ POLYGOND = 16,
+
+ //! BLArrayView<BLBoxI> struct.
+ ARRAY_VIEW_BOXI = 17,
+
+ //! BLArrayView<BLBox> struct.
+ ARRAY_VIEW_BOXD = 18,
+
+ //! BLArrayView<BLRectI> struct.
+ ARRAY_VIEW_RECTI = 19,
+
+ //! BLArrayView<BLRect> struct.
+ ARRAY_VIEW_RECTD = 20,
+
+ //! BLPath (or BLPathCore).
+ PATH = 21,
+
+ //! Maximum value of `BLGeometryType`.
+ MAX_VALUE = 21,
+
+ //! \cond INTERNAL
+
+ //! The last simple type.
+ SIMPLE_LAST = 12,
+
+ //! \endcond
+ FORCE_UINT = 4294967295,
+}
+
+//! Fill rule.
+FillRule :: enum u32 {
+ //! Non-zero fill-rule.
+ NON_ZERO = 0,
+
+ //! Even-odd fill-rule.
+ EVEN_ODD = 1,
+
+ //! Maximum value of `BLFillRule`.
+ MAX_VALUE = 1,
+ FORCE_UINT = 4294967295,
+}
+
+//! Hit-test result.
+HitTest :: enum u32 {
+ //! Fully in.
+ IN = 0,
+
+ //! Partially in/out.
+ PART = 1,
+
+ //! Fully out.
+ OUT = 2,
+
+ //! Hit test failed (invalid argument, NaNs, etc).
+ INVALID = 4294967295,
+ FORCE_UINT = 4294967295,
+}
+
+//! Point specified as [x, y] using `int` as a storage type.
+PointI :: struct {
+ x: i32,
+ y: i32,
+}
+
+//! Size specified as [w, h] using `int` as a storage type.
+SizeI :: struct {
+ w: i32,
+ h: i32,
+}
+
+//! Box specified as [x0, y0, x1, y1] using `int` as a storage type.
+BoxI :: struct {
+ x0: i32,
+ y0: i32,
+ x1: i32,
+ y1: i32,
+}
+
+//! Rectangle specified as [x, y, w, h] using `int` as a storage type.
+RectI :: struct {
+ x: i32,
+ y: i32,
+ w: i32,
+ h: i32,
+}
+
+//! Point specified as [x, y] using `double` as a storage type.
+Point :: struct {
+ x: f64,
+ y: f64,
+}
+
+//! Size specified as [w, h] using `double` as a storage type.
+Size :: struct {
+ w: f64,
+ h: f64,
+}
+
+//! Box specified as [x0, y0, x1, y1] using `double` as a storage type.
+Box :: struct {
+ x0: f64,
+ y0: f64,
+ x1: f64,
+ y1: f64,
+}
+
+//! Rectangle specified as [x, y, w, h] using `double` as a storage type.
+Rect :: struct {
+ x: f64,
+ y: f64,
+ w: f64,
+ h: f64,
+}
+
+//! Line specified as [x0, y0, x1, y1] using `double` as a storage type.
+Line :: struct {
+ x0, y0: f64,
+ x1, y1: f64,
+}
+
+//! Triangle data specified as [x0, y0, x1, y1, x2, y2] using `double` as a storage type.
+Triangle :: struct {
+ x0, y0: f64,
+ x1, y1: f64,
+ x2, y2: f64,
+}
+
+//! Rounded rectangle specified as [x, y, w, h, rx, ry] using `double` as a storage type.
+RoundRect :: struct {
+ x, y, w, h: f64,
+ rx, ry: f64,
+}
+
+//! Circle specified as [cx, cy, r] using `double` as a storage type.
+Circle :: struct {
+ cx, cy: f64,
+ r: f64,
+}
+
+//! Ellipse specified as [cx, cy, rx, ry] using `double` as a storage type.
+Ellipse :: struct {
+ cx, cy: f64,
+ rx, ry: f64,
+}
+
+//! Arc specified as [cx, cy, rx, ry, start, sweep] using `double` as a storage type.
+Arc :: struct {
+ cx, cy: f64,
+ rx, ry: f64,
+ start: f64,
+ sweep: f64,
+}
+
diff --git a/binding/glyphbuffer.odin b/binding/glyphbuffer.odin
@@ -0,0 +1,77 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Glyph buffer [Impl].
+//!
+//! \note This is not a `BLObjectImpl` compatible Impl.
+GlyphBufferImpl :: struct {
+ using _: struct #raw_union {
+ using _: struct {
+ //! Text (UCS4 code-points) or glyph content.
+ content: ^u32,
+
+ //! Glyph placement data.
+ placement_data: ^GlyphPlacement,
+
+ //! Number of either code points or glyph indexes in the glyph-buffer.
+ size: c.size_t,
+
+ //! Reserved, used exclusively by BLGlyphRun.
+ reserved: u32,
+
+ //! Flags shared between BLGlyphRun and BLGlyphBuffer.
+ flags: u32,
+ },
+
+ //! Glyph run data that can be passed directly to the rendering context.
+ //!
+ //! Glyph run shares data with other members like `content`, `placement_data`, `size`, and `flags`. When working
+ //! with data it's better to access these members directly as they are typed, whereas \ref BLGlyphRun stores
+ //! pointers as `const void*` as it offers more flexibility, which \ref BLGlyphRun doesn't need.
+ glyph_run: GlyphRun,
+ },
+
+ //! Glyph info data - additional information of each code-point or glyph.
+ info_data: ^GlyphInfo,
+}
+
+//! Glyph buffer [C API].
+GlyphBufferCore :: struct {
+ impl: ^GlyphBufferImpl,
+ BL_DEFINE_OBJECT_DCAST: proc "c" () -> i32,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ glyph_buffer_init :: proc(self: ^GlyphBufferCore) -> Result ---
+ glyph_buffer_init_move :: proc(self: ^GlyphBufferCore, other: ^GlyphBufferCore) -> Result ---
+ glyph_buffer_destroy :: proc(self: ^GlyphBufferCore) -> Result ---
+ glyph_buffer_reset :: proc(self: ^GlyphBufferCore) -> Result ---
+ glyph_buffer_clear :: proc(self: ^GlyphBufferCore) -> Result ---
+ glyph_buffer_get_size :: proc(self: ^GlyphBufferCore) -> c.size_t ---
+ glyph_buffer_get_flags :: proc(self: ^GlyphBufferCore) -> u32 ---
+ glyph_buffer_get_glyph_run :: proc(self: ^GlyphBufferCore) -> ^GlyphRun ---
+ glyph_buffer_get_content :: proc(self: ^GlyphBufferCore) -> ^u32 ---
+ glyph_buffer_get_info_data :: proc(self: ^GlyphBufferCore) -> ^GlyphInfo ---
+ glyph_buffer_get_placement_data :: proc(self: ^GlyphBufferCore) -> ^GlyphPlacement ---
+ glyph_buffer_set_text :: proc(self: ^GlyphBufferCore, text_data: rawptr, size: c.size_t, encoding: TextEncoding) -> Result ---
+ glyph_buffer_set_glyphs :: proc(self: ^GlyphBufferCore, glyph_data: ^u32, size: c.size_t) -> Result ---
+ glyph_buffer_set_glyphs_from_struct :: proc(self: ^GlyphBufferCore, glyph_data: rawptr, size: c.size_t, glyph_id_size: c.size_t, glyph_id_advance: c.intptr_t) -> Result ---
+ glyph_buffer_set_debug_sink :: proc(self: ^GlyphBufferCore, sink: DebugMessageSinkFunc, user_data: rawptr) -> Result ---
+ glyph_buffer_reset_debug_sink :: proc(self: ^GlyphBufferCore) -> Result ---
+}
+
diff --git a/binding/glyphrun.odin b/binding/glyphrun.odin
@@ -0,0 +1,97 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Flags used by \ref BLGlyphRun.
+GlyphRunFlags :: enum u32 {
+ //! No flags.
+ NO_FLAGS = 0,
+
+ //! Glyph-run contains UCS-4 string and not glyphs (glyph-buffer only).
+ FLAG_UCS4_CONTENT = 268435456,
+
+ //! Glyph-run was created from text that was not a valid unicode.
+ FLAG_INVALID_TEXT = 536870912,
+
+ //! Not the whole text was mapped to glyphs (contains undefined glyphs).
+ FLAG_UNDEFINED_GLYPHS = 1073741824,
+
+ //! Encountered invalid font data during text / glyph processing.
+ FLAG_INVALID_FONT_DATA = 2147483648,
+ FLAG_FORCE_UINT = 4294967295,
+}
+
+//! Placement of glyphs stored in a \ref BLGlyphRun.
+GlyphPlacementType :: enum u32 {
+ //! No placement (custom handling by \ref BLPathSinkFunc).
+ NONE = 0,
+
+ //! Each glyph has a BLGlyphPlacement (advance + offset).
+ ADVANCE_OFFSET = 1,
+
+ //! Each glyph has a BLPoint offset in design-space units.
+ DESIGN_UNITS = 2,
+
+ //! Each glyph has a BLPoint offset in user-space units.
+ USER_UNITS = 3,
+
+ //! Each glyph has a BLPoint offset in absolute units.
+ ABSOLUTE_UNITS = 4,
+
+ //! Maximum value of `BLGlyphPlacementType`.
+ MAX_VALUE = 4,
+ FORCE_UINT = 4294967295,
+}
+
+//! BLGlyphRun describes a set of consecutive glyphs and their placements.
+//!
+//! BLGlyphRun should only be used to pass glyph IDs and their placements to the rendering context. The purpose of
+//! BLGlyphRun is to allow rendering glyphs, which could be shaped by various shaping engines (Blend2D, Harfbuzz, etc).
+//!
+//! BLGlyphRun allows to render glyphs that are stored as uint32_t[] array or part of a bigger structure (for example
+//! `hb_glyph_info_t` used by HarfBuzz). Glyph placements at the moment use Blend2D's \ref BLGlyphPlacement or \ref
+//! BLPoint, but it's possible to extend the data type in the future.
+//!
+//! See `BLGlyphRunPlacement` for placement modes provided by Blend2D.
+GlyphRun :: struct {
+ //! \name Members
+ //! \{
+
+ //! Glyph id data (abstract, incremented by `glyph_advance`).
+ glyph_data: rawptr,
+
+ //! Glyph placement data (abstract, incremented by `placement_advance`).
+ placement_data: rawptr,
+
+ //! Size of the glyph-run in glyph units.
+ size: c.size_t,
+
+ //! Reserved for future use, muse be zero.
+ reserved: u8,
+
+ //! Type of placement, see \ref BLGlyphPlacementType.
+ placement_type: u8,
+
+ //! Advance of `glyph_data` array.
+ glyph_advance: i8,
+
+ //! Advance of `placement_data` array.
+ placement_advance: i8,
+
+ //! Glyph-run flags.
+ flags: u32,
+}
+
diff --git a/binding/gradient.odin b/binding/gradient.odin
@@ -0,0 +1,188 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Gradient type.
+GradientType :: enum u32 {
+ //! Linear gradient type.
+ LINEAR = 0,
+
+ //! Radial gradient type.
+ RADIAL = 1,
+
+ //! Conic gradient type.
+ CONIC = 2,
+
+ //! Maximum value of `BLGradientType`.
+ MAX_VALUE = 2,
+ FORCE_UINT = 4294967295,
+}
+
+//! Gradient data index.
+GradientValue :: enum u32 {
+ //! x0 - start 'x' for a Linear gradient and `x` center for both Radial and Conic gradients.
+ COMMON_X0 = 0,
+
+ //! y0 - start 'y' for a Linear gradient and `y` center for both Radial and Conic gradients.
+ COMMON_Y0 = 1,
+
+ //! x1 - end 'x' for a Linear gradient and focal point `x` for a Radial gradient.
+ COMMON_X1 = 2,
+
+ //! y1 - end 'y' for a Linear/gradient and focal point `y` for a Radial gradient.
+ COMMON_Y1 = 3,
+
+ //! Radial gradient center radius.
+ RADIAL_R0 = 4,
+
+ //! Radial gradient focal radius.
+ RADIAL_R1 = 5,
+
+ //! Conic gradient angle.
+ CONIC_ANGLE = 2,
+
+ //! Conic gradient angle.
+ CONIC_REPEAT = 3,
+
+ //! Maximum value of `BLGradientValue`.
+ MAX_VALUE = 5,
+ FORCE_UINT = 4294967295,
+}
+
+//! Gradient rendering quality.
+GradientQuality :: enum u32 {
+ //! Nearest neighbor.
+ NEAREST = 0,
+
+ //! Use smoothing, if available (currently never available).
+ SMOOTH = 1,
+
+ //! The renderer will use an implementation-specific dithering algorithm to prevent banding.
+ DITHER = 2,
+
+ //! Maximum value of `BLGradientQuality`.
+ MAX_VALUE = 2,
+ FORCE_UINT = 4294967295,
+}
+
+//! Defines an `offset` and `rgba` color that us used by \ref BLGradient to define a linear transition between colors.
+GradientStop :: struct {
+ offset: f64,
+ rgba: Rgba64,
+}
+
+//! Linear gradient values packed into a structure.
+LinearGradientValues :: struct {
+ x0: f64,
+ y0: f64,
+ x1: f64,
+ y1: f64,
+}
+
+//! Radial gradient values packed into a structure.
+RadialGradientValues :: struct {
+ x0: f64,
+ y0: f64,
+ x1: f64,
+ y1: f64,
+ r0: f64,
+ r1: f64,
+}
+
+//! Conic gradient values packed into a structure.
+ConicGradientValues :: struct {
+ x0: f64,
+ y0: f64,
+ angle: f64,
+ repeat: f64,
+}
+
+//! Gradient [C API].
+GradientCore :: struct {
+ _d: ObjectDetail,
+}
+
+//! \cond INTERNAL
+//! Gradient [C API Impl].
+GradientImpl :: struct {
+ //! Gradient stop data.
+ stops: ^GradientStop,
+
+ //! Gradient stop count.
+ size: c.size_t,
+
+ //! Stop capacity.
+ capacity: c.size_t,
+
+ //! Gradient transformation matrix.
+ transform: Matrix2D,
+
+ using _: struct #raw_union {
+ //! Gradient values (coordinates, radius, angle).
+ values: [6]f64,
+
+ //! Linear parameters.
+ linear: LinearGradientValues,
+
+ //! Radial parameters.
+ radial: RadialGradientValues,
+
+ //! Conic parameters.
+ conic: ConicGradientValues,
+ },
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \endcond
+ gradient_init :: proc(self: ^GradientCore) -> Result ---
+ gradient_init_move :: proc(self: ^GradientCore, other: ^GradientCore) -> Result ---
+ gradient_init_weak :: proc(self: ^GradientCore, other: ^GradientCore) -> Result ---
+ gradient_init_as :: proc(self: ^GradientCore, type: GradientType, values: rawptr, extend_mode: ExtendMode, stops: ^GradientStop, n: c.size_t, transform: ^Matrix2D) -> Result ---
+ gradient_destroy :: proc(self: ^GradientCore) -> Result ---
+ gradient_reset :: proc(self: ^GradientCore) -> Result ---
+ gradient_assign_move :: proc(self: ^GradientCore, other: ^GradientCore) -> Result ---
+ gradient_assign_weak :: proc(self: ^GradientCore, other: ^GradientCore) -> Result ---
+ gradient_create :: proc(self: ^GradientCore, type: GradientType, values: rawptr, extend_mode: ExtendMode, stops: ^GradientStop, n: c.size_t, transform: ^Matrix2D) -> Result ---
+ gradient_shrink :: proc(self: ^GradientCore) -> Result ---
+ gradient_reserve :: proc(self: ^GradientCore, n: c.size_t) -> Result ---
+ gradient_get_type :: proc(self: ^GradientCore) -> GradientType ---
+ gradient_set_type :: proc(self: ^GradientCore, type: GradientType) -> Result ---
+ gradient_get_extend_mode :: proc(self: ^GradientCore) -> ExtendMode ---
+ gradient_set_extend_mode :: proc(self: ^GradientCore, extend_mode: ExtendMode) -> Result ---
+ gradient_get_value :: proc(self: ^GradientCore, index: c.size_t) -> f64 ---
+ gradient_set_value :: proc(self: ^GradientCore, index: c.size_t, value: f64) -> Result ---
+ gradient_set_values :: proc(self: ^GradientCore, index: c.size_t, values: ^f64, n: c.size_t) -> Result ---
+ gradient_get_size :: proc(self: ^GradientCore) -> c.size_t ---
+ gradient_get_capacity :: proc(self: ^GradientCore) -> c.size_t ---
+ gradient_get_stops :: proc(self: ^GradientCore) -> ^GradientStop ---
+ gradient_reset_stops :: proc(self: ^GradientCore) -> Result ---
+ gradient_assign_stops :: proc(self: ^GradientCore, stops: ^GradientStop, n: c.size_t) -> Result ---
+ gradient_add_stop_rgba32 :: proc(self: ^GradientCore, offset: f64, argb32: u32) -> Result ---
+ gradient_add_stop_rgba64 :: proc(self: ^GradientCore, offset: f64, argb64: u64) -> Result ---
+ gradient_remove_stop :: proc(self: ^GradientCore, index: c.size_t) -> Result ---
+ gradient_remove_stop_by_offset :: proc(self: ^GradientCore, offset: f64, all: u32) -> Result ---
+ gradient_remove_stops_by_index :: proc(self: ^GradientCore, r_start: c.size_t, r_end: c.size_t) -> Result ---
+ gradient_remove_stops_by_offset :: proc(self: ^GradientCore, offset_min: f64, offset_max: f64) -> Result ---
+ gradient_replace_stop_rgba32 :: proc(self: ^GradientCore, index: c.size_t, offset: f64, rgba32: u32) -> Result ---
+ gradient_replace_stop_rgba64 :: proc(self: ^GradientCore, index: c.size_t, offset: f64, rgba64: u64) -> Result ---
+ gradient_index_of_stop :: proc(self: ^GradientCore, offset: f64) -> c.size_t ---
+ gradient_get_transform :: proc(self: ^GradientCore, transform_out: ^Matrix2D) -> Result ---
+ gradient_get_transform_type :: proc(self: ^GradientCore) -> TransformType ---
+ gradient_apply_transform_op :: proc(self: ^GradientCore, op_type: TransformOp, op_data: rawptr) -> Result ---
+ gradient_equals :: proc(a: ^GradientCore, b: ^GradientCore) -> i32 ---
+}
+
diff --git a/binding/image.odin b/binding/image.odin
@@ -0,0 +1,157 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Flags used by `BLImageInfo`.
+ImageInfoFlags :: enum u32 {
+ //! No flags.
+ NO_FLAGS = 0,
+
+ //! Progressive mode.
+ PROGRESSIVE = 1,
+ FORCE_UINT = 4294967295,
+}
+
+//! Filter type used by `BLImage::scale()`.
+ImageScaleFilter :: enum u32 {
+ //! No filter or uninitialized.
+ NONE = 0,
+
+ //! Nearest neighbor filter (radius 1.0).
+ NEAREST = 1,
+
+ //! Bilinear filter (radius 1.0).
+ BILINEAR = 2,
+
+ //! Bicubic filter (radius 2.0).
+ BICUBIC = 3,
+
+ //! Lanczos filter (radius 2.0).
+ LANCZOS = 4,
+
+ //! Maximum value of `BLImageScaleFilter`.
+ MAX_VALUE = 4,
+ FORCE_UINT = 4294967295,
+}
+
+//! Data that describes a raster image. Used by \ref BLImage.
+ImageData :: struct {
+ //! Pixel data, starting at the top left corner of the image.
+ //!
+ //! \note If the stride is negative the image data would start at the bottom.
+ pixel_data: rawptr,
+
+ //! Stride (in bytes) of image data (positive when image data starts at top-left, negative when it starts at
+ //! bottom-left).
+ stride: c.intptr_t,
+
+ //! Size of the image.
+ size: SizeI,
+
+ //! Pixel format, see \ref BLFormat.
+ format: u32,
+ flags: u32,
+}
+
+//! Image information provided by image codecs.
+ImageInfo :: struct {
+ //! Image size.
+ size: SizeI,
+
+ //! Pixel density per one meter, can contain fractions.
+ density: Size,
+
+ //! Image flags.
+ flags: u32,
+
+ //! Image depth.
+ depth: u16,
+
+ //! Number of planes.
+ plane_count: u16,
+
+ //! Number of frames (0 = unknown/unspecified).
+ frame_count: u64,
+
+ //! Number of animation repeats (0 == infinite).
+ repeat_count: u32,
+
+ //! Reserved for future use.
+ reserved: [3]u32,
+
+ //! Image format (as understood by codec).
+ format: [16]i8,
+
+ //! Image compression (as understood by codec).
+ compression: [16]i8,
+}
+
+//! 2D raster image [C API].
+ImageCore :: struct {
+ _d: ObjectDetail,
+}
+
+//! \cond INTERNAL
+//! 2D raster image [C API Impl].
+ImageImpl :: struct {
+ //! Pixel data.
+ pixel_data: rawptr,
+
+ //! Image stride.
+ stride: c.intptr_t,
+
+ //! Image size.
+ size: SizeI,
+
+ //! Image format.
+ format: u8,
+
+ //! Image flags.
+ flags: u8,
+
+ //! Image depth (in bits).
+ depth: u16,
+
+ //! Reserved for future use, must be zero.
+ reserved: [4]u8,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \endcond
+ image_init :: proc(self: ^ImageCore) -> Result ---
+ image_init_move :: proc(self: ^ImageCore, other: ^ImageCore) -> Result ---
+ image_init_weak :: proc(self: ^ImageCore, other: ^ImageCore) -> Result ---
+ image_init_as :: proc(self: ^ImageCore, w: i32, h: i32, format: Format) -> Result ---
+ image_init_as_from_data :: proc(self: ^ImageCore, w: i32, h: i32, format: Format, pixel_data: rawptr, stride: c.intptr_t, access_flags: DataAccessFlags, destroy_func: DestroyExternalDataFunc, user_data: rawptr) -> Result ---
+ image_destroy :: proc(self: ^ImageCore) -> Result ---
+ image_reset :: proc(self: ^ImageCore) -> Result ---
+ image_assign_move :: proc(self: ^ImageCore, other: ^ImageCore) -> Result ---
+ image_assign_weak :: proc(self: ^ImageCore, other: ^ImageCore) -> Result ---
+ image_assign_deep :: proc(self: ^ImageCore, other: ^ImageCore) -> Result ---
+ image_create :: proc(self: ^ImageCore, w: i32, h: i32, format: Format) -> Result ---
+ image_create_from_data :: proc(self: ^ImageCore, w: i32, h: i32, format: Format, pixel_data: rawptr, stride: c.intptr_t, access_flags: DataAccessFlags, destroy_func: DestroyExternalDataFunc, user_data: rawptr) -> Result ---
+ image_get_data :: proc(self: ^ImageCore, data_out: ^ImageData) -> Result ---
+ image_make_mutable :: proc(self: ^ImageCore, data_out: ^ImageData) -> Result ---
+ image_convert :: proc(self: ^ImageCore, format: Format) -> Result ---
+ image_equals :: proc(a: ^ImageCore, b: ^ImageCore) -> i32 ---
+ image_scale :: proc(dst: ^ImageCore, src: ^ImageCore, size: ^SizeI, filter: ImageScaleFilter) -> Result ---
+ image_read_from_file :: proc(self: ^ImageCore, file_name: cstring, codecs: ^ArrayCore) -> Result ---
+ image_read_from_data :: proc(self: ^ImageCore, data: rawptr, size: c.size_t, codecs: ^ArrayCore) -> Result ---
+ image_write_to_file :: proc(self: ^ImageCore, file_name: cstring, codec: ^ImageCodecCore) -> Result ---
+ image_write_to_data :: proc(self: ^ImageCore, dst: ^ArrayCore, codec: ^ImageCodecCore) -> Result ---
+}
+
diff --git a/binding/imagecodec.odin b/binding/imagecodec.odin
@@ -0,0 +1,109 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Image codec [C API].
+ImageCodecCore :: struct {
+ _d: ObjectDetail,
+}
+
+//! \cond
+//! Image codec [C API Virtual Function Table].
+ImageCodecVirt :: struct {
+ base: ObjectVirtBase,
+ inspect_data: proc "c" (impl: ^ImageCodecImpl, data: ^u8, size: c.size_t) -> u32,
+ create_decoder: proc "c" (impl: ^ImageCodecImpl, dst: ^ImageDecoderCore) -> Result,
+ create_encoder: proc "c" (impl: ^ImageCodecImpl, dst: ^ImageEncoderCore) -> Result,
+}
+
+//! Image codec [C API Impl].
+ImageCodecImpl :: struct {
+ //! \name Members
+ //! \{
+
+ //! Virtual function table.
+ virt: ^ImageCodecVirt,
+
+ //! Image codec name like "PNG", "JPEG", etc...
+ name: StringCore,
+
+ //! Image codec vendor string, built-in codecs use "Blend2D" as a vendor string.
+ vendor: StringCore,
+
+ //! Mime types.
+ mime_type: StringCore,
+
+ //! Known file extensions used by this image codec separated by "|".
+ extensions: StringCore,
+
+ //! Image codec features.
+ features: u32,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \endcond
+ image_codec_init :: proc(self: ^ImageCodecCore) -> Result ---
+ image_codec_init_move :: proc(self: ^ImageCodecCore, other: ^ImageCodecCore) -> Result ---
+ image_codec_init_weak :: proc(self: ^ImageCodecCore, other: ^ImageCodecCore) -> Result ---
+ image_codec_init_by_name :: proc(self: ^ImageCodecCore, name: cstring, size: c.size_t, codecs: ^ArrayCore) -> Result ---
+ image_codec_destroy :: proc(self: ^ImageCodecCore) -> Result ---
+ image_codec_reset :: proc(self: ^ImageCodecCore) -> Result ---
+ image_codec_assign_move :: proc(self: ^ImageCodecCore, other: ^ImageCodecCore) -> Result ---
+ image_codec_assign_weak :: proc(self: ^ImageCodecCore, other: ^ImageCodecCore) -> Result ---
+ image_codec_find_by_name :: proc(self: ^ImageCodecCore, name: cstring, size: c.size_t, codecs: ^ArrayCore) -> Result ---
+ image_codec_find_by_extension :: proc(self: ^ImageCodecCore, name: cstring, size: c.size_t, codecs: ^ArrayCore) -> Result ---
+ image_codec_find_by_data :: proc(self: ^ImageCodecCore, data: rawptr, size: c.size_t, codecs: ^ArrayCore) -> Result ---
+ image_codec_inspect_data :: proc(self: ^ImageCodecCore, data: rawptr, size: c.size_t) -> u32 ---
+ image_codec_create_decoder :: proc(self: ^ImageCodecCore, dst: ^ImageDecoderCore) -> Result ---
+ image_codec_create_encoder :: proc(self: ^ImageCodecCore, dst: ^ImageEncoderCore) -> Result ---
+ image_codec_array_init_built_in_codecs :: proc(self: ^ArrayCore) -> Result ---
+ image_codec_array_assign_built_in_codecs :: proc(self: ^ArrayCore) -> Result ---
+ image_codec_add_to_built_in :: proc(codec: ^ImageCodecCore) -> Result ---
+ image_codec_remove_from_built_in :: proc(codec: ^ImageCodecCore) -> Result ---
+}
+
+//! Image codec feature bits.
+ImageCodecFeatures :: enum u32 {
+ //! No features.
+ NO_FEATURES = 0,
+
+ //! Image codec supports reading images (can create BLImageDecoder).
+ FEATURE_READ = 1,
+
+ //! Image codec supports writing images (can create BLImageEncoder).
+ FEATURE_WRITE = 2,
+
+ //! Image codec supports lossless compression.
+ FEATURE_LOSSLESS = 4,
+
+ //! Image codec supports loosy compression.
+ FEATURE_LOSSY = 8,
+
+ //! Image codec supports writing multiple frames (GIF).
+ FEATURE_MULTI_FRAME = 16,
+
+ //! Image codec supports IPTC metadata.
+ FEATURE_IPTC = 268435456,
+
+ //! Image codec supports EXIF metadata.
+ FEATURE_EXIF = 536870912,
+
+ //! Image codec supports XMP metadata.
+ FEATURE_XMP = 1073741824,
+ FEATURE_FORCE_UINT = 4294967295,
+}
+
diff --git a/binding/imagedecoder.odin b/binding/imagedecoder.odin
@@ -0,0 +1,70 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Image decoder [C API]
+ImageDecoderCore :: struct {
+ _d: ObjectDetail,
+}
+
+//! \cond INTERNAL
+//! Image decoder [C API Virtual Function Table].
+ImageDecoderVirt :: struct {
+ base: ObjectVirtBase,
+ restart: proc "c" (impl: ^ImageDecoderImpl) -> Result,
+ read_info: proc "c" (impl: ^ImageDecoderImpl, info_out: ^ImageInfo, data: ^u8, size: c.size_t) -> Result,
+ read_frame: proc "c" (impl: ^ImageDecoderImpl, image_out: ^ImageCore, data: ^u8, size: c.size_t) -> Result,
+}
+
+//! Image decoder [C API Impl].
+ImageDecoderImpl :: struct {
+ //! \name Members
+ //! \{
+
+ //! Virtual function table.
+ virt: ^ImageDecoderVirt,
+
+ //! Image codec that created this decoder.
+ codec: ImageCodecCore,
+
+ //! Last faulty result (if failed).
+ last_result: Result,
+
+ //! Handle in case that this decoder wraps a third-party library.
+ handle: rawptr,
+
+ //! Current frame index.
+ frame_index: u64,
+
+ //! Position in source buffer.
+ buffer_index: c.size_t,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \endcond
+ image_decoder_init :: proc(self: ^ImageDecoderCore) -> Result ---
+ image_decoder_init_move :: proc(self: ^ImageDecoderCore, other: ^ImageDecoderCore) -> Result ---
+ image_decoder_init_weak :: proc(self: ^ImageDecoderCore, other: ^ImageDecoderCore) -> Result ---
+ image_decoder_destroy :: proc(self: ^ImageDecoderCore) -> Result ---
+ image_decoder_reset :: proc(self: ^ImageDecoderCore) -> Result ---
+ image_decoder_assign_move :: proc(self: ^ImageDecoderCore, other: ^ImageDecoderCore) -> Result ---
+ image_decoder_assign_weak :: proc(self: ^ImageDecoderCore, other: ^ImageDecoderCore) -> Result ---
+ image_decoder_restart :: proc(self: ^ImageDecoderCore) -> Result ---
+ image_decoder_read_info :: proc(self: ^ImageDecoderCore, info_out: ^ImageInfo, data: ^u8, size: c.size_t) -> Result ---
+ image_decoder_read_frame :: proc(self: ^ImageDecoderCore, image_out: ^ImageCore, data: ^u8, size: c.size_t) -> Result ---
+}
+
diff --git a/binding/imageencoder.odin b/binding/imageencoder.odin
@@ -0,0 +1,68 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Image encoder [C API].
+ImageEncoderCore :: struct {
+ _d: ObjectDetail,
+}
+
+//! \cond INTERNAL
+//! Image encoder [Virtual Function Table].
+ImageEncoderVirt :: struct {
+ base: ObjectVirtBase,
+ restart: proc "c" (impl: ^ImageEncoderImpl) -> Result,
+ write_frame: proc "c" (impl: ^ImageEncoderImpl, dst: ^ArrayCore, image: ^ImageCore) -> Result,
+}
+
+//! Image encoder [Impl].
+ImageEncoderImpl :: struct {
+ //! \name Members
+ //! \{
+
+ //! Virtual function table.
+ virt: ^ImageEncoderVirt,
+
+ //! Image codec that created this encoder.
+ codec: ImageCodecCore,
+
+ //! Last faulty result (if failed).
+ last_result: Result,
+
+ //! Handle in case that this encoder wraps a third-party library.
+ handle: rawptr,
+
+ //! Current frame index.
+ frame_index: u64,
+
+ //! Position in source buffer.
+ buffer_index: c.size_t,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \endcond
+ image_encoder_init :: proc(self: ^ImageEncoderCore) -> Result ---
+ image_encoder_init_move :: proc(self: ^ImageEncoderCore, other: ^ImageEncoderCore) -> Result ---
+ image_encoder_init_weak :: proc(self: ^ImageEncoderCore, other: ^ImageEncoderCore) -> Result ---
+ image_encoder_destroy :: proc(self: ^ImageEncoderCore) -> Result ---
+ image_encoder_reset :: proc(self: ^ImageEncoderCore) -> Result ---
+ image_encoder_assign_move :: proc(self: ^ImageEncoderCore, other: ^ImageEncoderCore) -> Result ---
+ image_encoder_assign_weak :: proc(self: ^ImageEncoderCore, other: ^ImageEncoderCore) -> Result ---
+ image_encoder_restart :: proc(self: ^ImageEncoderCore) -> Result ---
+ image_encoder_write_frame :: proc(self: ^ImageEncoderCore, dst: ^ArrayCore, image: ^ImageCore) -> Result ---
+}
+
diff --git a/binding/matrix.odin b/binding/matrix.odin
@@ -0,0 +1,135 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Transformation matrix type that can be obtained by calling `BLMatrix2D::type()`.
+//!
+//! ```
+//! Identity Transl. Scale Swap Affine
+//! [1 0] [1 0] [. 0] [0 .] [. .]
+//! [0 1] [0 1] [0 .] [. 0] [. .]
+//! [0 0] [. .] [. .] [. .] [. .]
+//! ```
+TransformType :: enum u32 {
+ //! Identity matrix.
+ TRANSFORM_TYPE_IDENTITY = 0,
+
+ //! Has translation part (the rest is like identity).
+ TRANSFORM_TYPE_TRANSLATE = 1,
+
+ //! Has translation and scaling parts.
+ TRANSFORM_TYPE_SCALE = 2,
+
+ //! Has translation and scaling parts, however scaling swaps X/Y.
+ TRANSFORM_TYPE_SWAP = 3,
+
+ //! Generic affine matrix.
+ TRANSFORM_TYPE_AFFINE = 4,
+
+ //! Invalid/degenerate matrix not useful for transformations.
+ TRANSFORM_TYPE_INVALID = 5,
+
+ //! Maximum value of `BLTransformType`.
+ TRANSFORM_TYPE_MAX_VALUE = 5,
+ MATRIX2D_TYPE_FORCE_UINT = 4294967295,
+}
+
+//! Transformation matrix operation type.
+TransformOp :: enum u32 {
+ //! Reset matrix to identity (argument ignored, should be nullptr).
+ RESET = 0,
+
+ //! Assign (copy) the other matrix.
+ ASSIGN = 1,
+
+ //! Translate the matrix by [x, y].
+ TRANSLATE = 2,
+
+ //! Scale the matrix by [x, y].
+ SCALE = 3,
+
+ //! Skew the matrix by [x, y].
+ SKEW = 4,
+
+ //! Rotate the matrix by the given angle about [0, 0].
+ ROTATE = 5,
+
+ //! Rotate the matrix by the given angle about [x, y].
+ ROTATE_PT = 6,
+
+ //! Transform this matrix by other \ref BLMatrix2D.
+ TRANSFORM = 7,
+
+ //! Post-translate the matrix by [x, y].
+ POST_TRANSLATE = 8,
+
+ //! Post-scale the matrix by [x, y].
+ POST_SCALE = 9,
+
+ //! Post-skew the matrix by [x, y].
+ POST_SKEW = 10,
+
+ //! Post-rotate the matrix about [0, 0].
+ POST_ROTATE = 11,
+
+ //! Post-rotate the matrix about a reference BLPoint.
+ POST_ROTATE_PT = 12,
+
+ //! Post-transform this matrix by other \ref BLMatrix2D.
+ POST_TRANSFORM = 13,
+
+ //! Maximum value of `BLTransformOp`.
+ MAX_VALUE = 13,
+ FORCE_UINT = 4294967295,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \name BLMatrix2D - C API
+ //!
+ //! Functions that initialize and manipulate \ref BLMatrix2D content.
+ //!
+ //! \{
+ matrix2d_set_identity :: proc(self: ^Matrix2D) -> Result ---
+ matrix2d_set_translation :: proc(self: ^Matrix2D, x: f64, y: f64) -> Result ---
+ matrix2d_set_scaling :: proc(self: ^Matrix2D, x: f64, y: f64) -> Result ---
+ matrix2d_set_skewing :: proc(self: ^Matrix2D, x: f64, y: f64) -> Result ---
+ matrix2d_set_rotation :: proc(self: ^Matrix2D, angle: f64, cx: f64, cy: f64) -> Result ---
+ matrix2d_apply_op :: proc(self: ^Matrix2D, op_type: TransformOp, op_data: rawptr) -> Result ---
+ matrix2d_invert :: proc(dst: ^Matrix2D, src: ^Matrix2D) -> Result ---
+ matrix2d_get_type :: proc(self: ^Matrix2D) -> TransformType ---
+ matrix2d_map_pointd_array :: proc(self: ^Matrix2D, dst: ^Point, src: ^Point, count: c.size_t) -> Result ---
+}
+
+//! 2D matrix represents an affine transformation matrix that can be used to transform geometry and images.
+Matrix2D :: struct {
+ // TODO: Remove the union, keep only m[] array.
+ using _: struct #raw_union {
+ //! Matrix values stored in array.
+ m: [6]f64,
+
+ //! Matrix values that map `m` to named values that can be used directly.
+ using _: struct {
+ m00: f64,
+ m01: f64,
+ m10: f64,
+ m11: f64,
+ m20: f64,
+ m21: f64,
+ },
+ },
+}
+
diff --git a/binding/object.odin b/binding/object.odin
@@ -0,0 +1,336 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+ObjectImpl :: struct {}
+
+//! \cond INTERNAL
+//! Defines a start offset of each field or flag in object info - the shift can be then used to get/set value from/to
+//! info bits.
+ObjectInfoShift :: enum u32 {
+ P_SHIFT = 0,
+ Q_SHIFT = 8,
+ C_SHIFT = 8,
+ B_SHIFT = 12,
+ A_SHIFT = 16,
+ TYPE_SHIFT = 22,
+ R_SHIFT = 29,
+ D_SHIFT = 30,
+ M_SHIFT = 31,
+ SHIFT_FORCE_UINT = 4294967295,
+}
+
+//! Defines a mask of each field of the object info.
+//!
+//! \note This is part of the official documentation, however, users should not use these enumerations in any context.
+ObjectInfoBits :: enum u32 {
+ //! Mask describing 'P' payload (8 bits).
+ P_MASK = 255, // [........|........|........|pppppppp]
+
+ //! Mask describing 'Q' payload (8 bits aliased with 'bbbbcccc' bits).
+ Q_MASK = 65280, // [........|........|qqqqqqqq|........]
+
+ //! Mask describing 'C' payload (4 bits).
+ C_MASK = 3840, // [........|........|....cccc|........]
+
+ //! Mask describing 'B' payload (4 bits).
+ B_MASK = 61440, // [........|........|bbbb....|........]
+
+ //! Mask describing 'A' payload (6 bits).
+ A_MASK = 4128768, // [........|..aaaaaa|........|........]
+
+ //! Mask of all payload fields combined, except 'M', 'T', type identification, and 'R' (RefCounted marker).
+ FIELDS_MASK = 4194303,
+
+ //! Mask describing object type (8 bits), see \ref BLObjectType.
+ TYPE_MASK = 532676608, // [...ttttt|tt......|........|........]
+
+ //! Flag describing a ref-counted object (if set together with 'D' flag)
+ //!
+ //! \note This flag is free for use by SSO, it has no meaning when 'D' flag is not set).
+ R_FLAG = 536870912, // [..R.....|........|........|........]
+
+ //! Flag describing a dynamic object - if this flag is not set, it means the object is in SSO mode.
+ D_FLAG = 1073741824, // [.D......|........|........|........]
+
+ //! Flag describing a valid object compatible with \ref BLObjectCore interface (otherwise it's most likely \ref BLRgba).
+ M_FLAG = 2147483648, // [M.......|........|........|........]
+
+ //! A combination of `BL_OBJECT_INFO_M_FLAG` and `BL_OBJECT_INFO_D_FLAG` flags.
+ MD_FLAGS = 3221225472,
+
+ //! A combination of `BL_OBJECT_INFO_M_FLAG`, `BL_OBJECT_INFO_D_FLAG`, `BL_OBJECT_INFO_R_FLAG` flags.
+ MDR_FLAGS = 3758096384,
+ BITS_FORCE_UINT = 4294967295,
+}
+
+//! Object type identifier.
+ObjectType :: enum u32 {
+ //! Object represents a \ref BLRgba value stored as four 32-bit floating point components (can be used as Style).
+ RGBA = 0,
+
+ //! Object represents a \ref BLRgba32 value stored as 32-bit integer in `0xAARRGGBB` form.
+ RGBA32 = 1,
+
+ //! Object represents a \ref BLRgba64 value stored as 64-bit integer in `0xAAAARRRRGGGGBBBB` form.
+ RGBA64 = 2,
+
+ //! Object is `Null` (can be used as style).
+ NULL = 3,
+
+ //! Object is \ref BLPattern (can be used as style).
+ PATTERN = 4,
+
+ //! Object is \ref BLGradient (can be used as style).
+ GRADIENT = 5,
+
+ //! Object is \ref BLImage.
+ IMAGE = 9,
+
+ //! Object is \ref BLPath.
+ PATH = 10,
+
+ //! Object is \ref BLFont.
+ FONT = 16,
+
+ //! Object is \ref BLFontFeatureSettings.
+ FONT_FEATURE_SETTINGS = 17,
+
+ //! Object is \ref BLFontVariationSettings.
+ FONT_VARIATION_SETTINGS = 18,
+
+ //! Object is \ref BLBitArray.
+ BIT_ARRAY = 25,
+
+ //! Object is \ref BLBitSet.
+ BIT_SET = 26,
+
+ //! Object represents a boolean value.
+ BOOL = 28,
+
+ //! Object represents a 64-bit signed integer value.
+ INT64 = 29,
+
+ //! Object represents a 64-bit unsigned integer value.
+ UINT64 = 30,
+
+ //! Object represents a 64-bit floating point value.
+ DOUBLE = 31,
+
+ //! Object is \ref BLString.
+ STRING = 32,
+
+ //! Object is \ref BLArray<T> where `T` is a `BLObject` compatible type.
+ ARRAY_OBJECT = 33,
+
+ //! Object is \ref BLArray<T> where `T` matches 8-bit signed integral type.
+ ARRAY_INT8 = 34,
+
+ //! Object is \ref BLArray<T> where `T` matches 8-bit unsigned integral type.
+ ARRAY_UINT8 = 35,
+
+ //! Object is \ref BLArray<T> where `T` matches 16-bit signed integral type.
+ ARRAY_INT16 = 36,
+
+ //! Object is \ref BLArray<T> where `T` matches 16-bit unsigned integral type.
+ ARRAY_UINT16 = 37,
+
+ //! Object is \ref BLArray<T> where `T` matches 32-bit signed integral type.
+ ARRAY_INT32 = 38,
+
+ //! Object is \ref BLArray<T> where `T` matches 32-bit unsigned integral type.
+ ARRAY_UINT32 = 39,
+
+ //! Object is \ref BLArray<T> where `T` matches 64-bit signed integral type.
+ ARRAY_INT64 = 40,
+
+ //! Object is \ref BLArray<T> where `T` matches 64-bit unsigned integral type.
+ ARRAY_UINT64 = 41,
+
+ //! Object is \ref BLArray<T> where `T` matches 32-bit floating point type.
+ ARRAY_FLOAT32 = 42,
+
+ //! Object is \ref BLArray<T> where `T` matches 64-bit floating point type.
+ ARRAY_FLOAT64 = 43,
+
+ //! Object is \ref BLArray<T> where `T` is a struct of size 1.
+ ARRAY_STRUCT_1 = 44,
+
+ //! Object is \ref BLArray<T> where `T` is a struct of size 2.
+ ARRAY_STRUCT_2 = 45,
+
+ //! Object is \ref BLArray<T> where `T` is a struct of size 3.
+ ARRAY_STRUCT_3 = 46,
+
+ //! Object is \ref BLArray<T> where `T` is a struct of size 4.
+ ARRAY_STRUCT_4 = 47,
+
+ //! Object is \ref BLArray<T> where `T` is a struct of size 6.
+ ARRAY_STRUCT_6 = 48,
+
+ //! Object is \ref BLArray<T> where `T` is a struct of size 8.
+ ARRAY_STRUCT_8 = 49,
+
+ //! Object is \ref BLArray<T> where `T` is a struct of size 10.
+ ARRAY_STRUCT_10 = 50,
+
+ //! Object is \ref BLArray<T> where `T` is a struct of size 12.
+ ARRAY_STRUCT_12 = 51,
+
+ //! Object is \ref BLArray<T> where `T` is a struct of size 16.
+ ARRAY_STRUCT_16 = 52,
+
+ //! Object is \ref BLArray<T> where `T` is a struct of size 20.
+ ARRAY_STRUCT_20 = 53,
+
+ //! Object is \ref BLArray<T> where `T` is a struct of size 24.
+ ARRAY_STRUCT_24 = 54,
+
+ //! Object is \ref BLArray<T> where `T` is a struct of size 32.
+ ARRAY_STRUCT_32 = 55,
+
+ //! Object is \ref BLContext.
+ CONTEXT = 100,
+
+ //! Object is \ref BLImageCodec.
+ IMAGE_CODEC = 101,
+
+ //! Object is \ref BLImageDecoder.
+ IMAGE_DECODER = 102,
+
+ //! Object is \ref BLImageEncoder.
+ IMAGE_ENCODER = 103,
+
+ //! Object is \ref BLFontFace.
+ FONT_FACE = 104,
+
+ //! Object is \ref BLFontData.
+ FONT_DATA = 105,
+
+ //! Object is \ref BLFontManager.
+ FONT_MANAGER = 106,
+
+ //! Minimum object type of an array object.
+ MIN_ARRAY = 33,
+
+ //! Maximum object type of an array object.
+ MAX_ARRAY = 55,
+
+ //! Minimum object type identifier that can be used as a style.
+ MIN_STYLE = 0,
+
+ //! Maximum object type identifier that can be used as a style.
+ MAX_STYLE = 5,
+
+ //! Minimum object type of an object with virtual function table.
+ MIN_VIRTUAL = 100,
+
+ //! Maximum object type of an object with virtual function table.
+ MAX_VIRTUAL = 127,
+
+ //! Maximum possible value of an object type, including identifiers reserved for the future.
+ MAX_VALUE = 127,
+ FORCE_UINT = 4294967295,
+}
+
+//! Information bits used by \ref BLObjectCore and all Blend2D compatible objects inheriting it.
+ObjectInfo :: struct {
+ //! \name Members
+ //! \{
+
+ //! Stores all object info bits.
+ bits: u32,
+}
+
+//! Defines a BLObject layout that all objects must use.
+ObjectDetail :: struct #raw_union {
+ impl: ^ObjectImpl,
+ char_data: [16]i8,
+ i8_data: [16]i8,
+ u8_data: [16]u8,
+ i16_data: [8]i16,
+ u16_data: [8]u16,
+ i32_data: [4]i32,
+ u32_data: [4]u32,
+ i64_data: [2]i64,
+ u64_data: [2]u64,
+ f32_data: [4]f32,
+ f64_data: [2]f64,
+ rgba: Rgba,
+ rgba32: Rgba32,
+ rgba64: Rgba64,
+
+ using _: struct {
+ u32_data_overlap: [2]u32,
+ impl_payload: u32,
+ info: ObjectInfo,
+ },
+}
+
+//! A function callback that is called when an Impl that holds external data is going to be destroyed. It's
+//! often used as a notification that a data passed to a certain Impl is no longer in use by Blend2D.
+DestroyExternalDataFunc :: proc "c" (impl: rawptr, external_data: rawptr, user_data: rawptr)
+
+//! Base members of \ref BLObjectVirt.
+//!
+//! The reason for this struct is to make C API the same as C++ API in terms of struct members. In C++ mode we use
+//! inheritance so `Virt` structs actually inherit from \ref BLObjectVirt, but in every case all base members are
+//! provided by `base`.
+ObjectVirtBase :: struct {
+ destroy: proc "c" (impl: ^ObjectImpl) -> Result,
+ get_property: proc "c" (impl: ^ObjectImpl, name: cstring, name_size: c.size_t, value_out: ^VarCore) -> Result,
+ set_property: proc "c" (impl: ^ObjectImpl, name: cstring, name_size: c.size_t, value: ^VarCore) -> Result,
+}
+
+//! BLObject [Virtual Function Table].
+//!
+//! Virtual function table is only present when object type is greater than \ref BL_OBJECT_TYPE_MIN_VIRTUAL.
+//! Objects can extend the function table, but it has to always start with members defined by `BLObjectVirt`.
+ObjectVirt :: struct {
+ base: ObjectVirtBase,
+}
+
+//! Base class used by all Blend2D objects.
+ObjectCore :: struct {
+ _d: ObjectDetail,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ object_alloc_impl :: proc(self: ^ObjectCore, object_info: u32, impl_size: c.size_t) -> Result ---
+ object_alloc_impl_aligned :: proc(self: ^ObjectCore, object_info: u32, impl_size: c.size_t, impl_alignment: c.size_t) -> Result ---
+ object_alloc_impl_external :: proc(self: ^ObjectCore, object_info: u32, impl_size: c.size_t, immutable: i32, destroy_func: DestroyExternalDataFunc, user_data: rawptr) -> Result ---
+ object_free_impl :: proc(impl: ^ObjectImpl) -> Result ---
+ object_init_move :: proc(self: ^Unknown, other: ^Unknown) -> Result ---
+ object_init_weak :: proc(self: ^Unknown, other: ^Unknown) -> Result ---
+ object_reset :: proc(self: ^Unknown) -> Result ---
+ object_assign_move :: proc(self: ^Unknown, other: ^Unknown) -> Result ---
+ object_assign_weak :: proc(self: ^Unknown, other: ^Unknown) -> Result ---
+ object_get_property :: proc(self: ^Unknown, name: cstring, name_size: c.size_t, value_out: ^VarCore) -> Result ---
+ object_get_property_bool :: proc(self: ^Unknown, name: cstring, name_size: c.size_t, value_out: ^i32) -> Result ---
+ object_get_property_int32 :: proc(self: ^Unknown, name: cstring, name_size: c.size_t, value_out: ^i32) -> Result ---
+ object_get_property_int64 :: proc(self: ^Unknown, name: cstring, name_size: c.size_t, value_out: ^i64) -> Result ---
+ object_get_property_uint32 :: proc(self: ^Unknown, name: cstring, name_size: c.size_t, value_out: ^u32) -> Result ---
+ object_get_property_uint64 :: proc(self: ^Unknown, name: cstring, name_size: c.size_t, value_out: ^u64) -> Result ---
+ object_get_property_double :: proc(self: ^Unknown, name: cstring, name_size: c.size_t, value_out: ^f64) -> Result ---
+ object_set_property :: proc(self: ^Unknown, name: cstring, name_size: c.size_t, value: ^Unknown) -> Result ---
+ object_set_property_bool :: proc(self: ^Unknown, name: cstring, name_size: c.size_t, value: i32) -> Result ---
+ object_set_property_int32 :: proc(self: ^Unknown, name: cstring, name_size: c.size_t, value: i32) -> Result ---
+ object_set_property_int64 :: proc(self: ^Unknown, name: cstring, name_size: c.size_t, value: i64) -> Result ---
+ object_set_property_uint32 :: proc(self: ^Unknown, name: cstring, name_size: c.size_t, value: u32) -> Result ---
+ object_set_property_uint64 :: proc(self: ^Unknown, name: cstring, name_size: c.size_t, value: u64) -> Result ---
+ object_set_property_double :: proc(self: ^Unknown, name: cstring, name_size: c.size_t, value: f64) -> Result ---
+}
+
diff --git a/binding/path.odin b/binding/path.odin
@@ -0,0 +1,369 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Path command.
+PathCmd :: enum u32 {
+ //! Move-to command (starts a new figure).
+ MOVE = 0,
+
+ //! On-path command (interpreted as line-to or the end of a curve).
+ ON = 1,
+
+ //! Quad-to control point.
+ QUAD = 2,
+
+ //! Conic-to control point
+ CONIC = 3,
+
+ //! Cubic-to control point (always used as a pair of commands).
+ CUBIC = 4,
+
+ //! Close path.
+ CLOSE = 5,
+
+ //! Conic weight.
+ //!
+ //! \note This is not a point. This is a pair of values from which only the first (x) is used to represent weight
+ //! as used by conic curve. The other value (y) is always set to NaN by Blend2D, but can be arbitrary as it has
+ //! no meaning.
+ WEIGHT = 6,
+
+ //! Maximum value of `BLPathCmd`.
+ MAX_VALUE = 6,
+ FORCE_UINT = 4294967295,
+}
+
+//! Path command (never stored in path).
+PathCmdExtra :: enum u32 {
+ //! Used by `BLPath::set_vertex_at` to preserve the current command value.
+ BL_PATH_CMD_PRESERVE = 4294967295,
+}
+
+//! Path flags.
+PathFlags :: enum u32 {
+ //! No flags.
+ NO_FLAGS = 0,
+
+ //! Path is empty (no commands or close commands only).
+ FLAG_EMPTY = 1,
+
+ //! Path contains multiple figures.
+ FLAG_MULTIPLE = 2,
+
+ //! Path contains one or more quad curves.
+ FLAG_QUADS = 4,
+
+ //! Path contains one or more conic curves.
+ FLAG_CONICS = 8,
+
+ //! Path contains one or more cubic curves.
+ FLAG_CUBICS = 16,
+
+ //! Path is invalid.
+ FLAG_INVALID = 1073741824,
+
+ //! Flags are dirty (not reflecting the current status).
+ FLAG_DIRTY = 2147483648,
+ FLAG_FORCE_UINT = 4294967295,
+}
+
+//! Path reversal mode.
+PathReverseMode :: enum u32 {
+ //! Reverse each figure and their order as well (default).
+ COMPLETE = 0,
+
+ //! Reverse each figure separately (keeps their order).
+ SEPARATE = 1,
+
+ //! Maximum value of `BLPathReverseMode`.
+ MAX_VALUE = 1,
+ FORCE_UINT = 4294967295,
+}
+
+//! Stroke join type.
+StrokeJoin :: enum u32 {
+ //! Miter-join possibly clipped at `miter_limit` [default].
+ MITER_CLIP = 0,
+
+ //! Miter-join or bevel-join depending on miter_limit condition.
+ MITER_BEVEL = 1,
+
+ //! Miter-join or round-join depending on miter_limit condition.
+ MITER_ROUND = 2,
+
+ //! Bevel-join.
+ BEVEL = 3,
+
+ //! Round-join.
+ ROUND = 4,
+
+ //! Maximum value of `BLStrokeJoin`.
+ MAX_VALUE = 4,
+ FORCE_UINT = 4294967295,
+}
+
+//! Position of a stroke-cap.
+StrokeCapPosition :: enum u32 {
+ //! Start of the path.
+ START = 0,
+
+ //! End of the path.
+ END = 1,
+
+ //! Maximum value of `BLStrokeCapPosition`.
+ MAX_VALUE = 1,
+ FORCE_UINT = 4294967295,
+}
+
+//! A presentation attribute defining the shape to be used at the end of open sub-paths.
+StrokeCap :: enum u32 {
+ //! Butt cap [default].
+ BUTT = 0,
+
+ //! Square cap.
+ SQUARE = 1,
+
+ //! Round cap.
+ ROUND = 2,
+
+ //! Round cap reversed.
+ ROUND_REV = 3,
+
+ //! Triangle cap.
+ TRIANGLE = 4,
+
+ //! Triangle cap reversed.
+ TRIANGLE_REV = 5,
+
+ //! Maximum value of `BLStrokeCap`.
+ MAX_VALUE = 5,
+ FORCE_UINT = 4294967295,
+}
+
+//! Stroke transform order.
+StrokeTransformOrder :: enum u32 {
+ //! Transform after stroke => `Transform(Stroke(Input))` [default].
+ AFTER = 0,
+
+ //! Transform before stroke => `Stroke(Transform(Input))`.
+ BEFORE = 1,
+
+ //! Maximum value of `BLStrokeTransformOrder`.
+ MAX_VALUE = 1,
+ FORCE_UINT = 4294967295,
+}
+
+//! Mode that specifies how curves are approximated to line segments.
+FlattenMode :: enum u32 {
+ //! Use default mode (decided by Blend2D).
+ DEFAULT = 0,
+
+ //! Recursive subdivision flattening.
+ RECURSIVE = 1,
+
+ //! Maximum value of `BLFlattenMode`.
+ MAX_VALUE = 1,
+ FORCE_UINT = 4294967295,
+}
+
+//! Mode that specifies how to construct offset curves.
+OffsetMode :: enum u32 {
+ //! Use default mode (decided by Blend2D).
+ DEFAULT = 0,
+
+ //! Iterative offset construction.
+ ITERATIVE = 1,
+
+ //! Maximum value of `BLOffsetMode`.
+ MAX_VALUE = 1,
+ FORCE_UINT = 4294967295,
+}
+
+//! Options used to describe how geometry is approximated.
+//!
+//! This struct cannot be simply zeroed and then passed to functions that accept approximation options.
+//! Use `bl_default_approximation_options` to setup defaults and then alter values you want to change.
+//!
+//! Example of using `BLApproximationOptions`:
+//!
+//! ```
+//! // Initialize with defaults first.
+//! BLApproximationOptions approx = bl_default_approximation_options;
+//!
+//! // Override values you want to change.
+//! approx.simplify_tolerance = 0.02;
+//!
+//! // ... now safely use approximation options in your code ...
+//! ```
+ApproximationOptions :: struct {
+ //! Specifies how curves are flattened, see \ref BLFlattenMode.
+ flatten_mode: u8,
+
+ //! Specifies how curves are offsetted (used by stroking), see \ref BLOffsetMode.
+ offset_mode: u8,
+
+ //! Reserved for future use, must be zero.
+ reserved_flags: [6]u8,
+
+ //! Tolerance used to flatten curves.
+ flatten_tolerance: f64,
+
+ //! Tolerance used to approximate cubic curves with quadratic curves.
+ simplify_tolerance: f64,
+
+ //! Curve offsetting parameter, exact meaning depends on `offset_mode`.
+ offset_parameter: f64,
+}
+
+//! 2D vector path view provides pointers to vertex and command data along with their size.
+PathView :: struct {
+ command_data: ^u8,
+ vertex_data: ^Point,
+ size: c.size_t,
+}
+
+//! Optional callback that can be used to consume a path data.
+PathSinkFunc :: proc "c" (path: ^PathCore, info: rawptr, user_data: rawptr) -> Result
+
+//! This is a sink that is used by path offsetting. This sink consumes both `a` and `b` offsets of the path. The sink
+//! will be called for each figure and is responsible for joining these paths. If the paths are not closed then the
+//! sink must insert start cap, then join `b`, and then insert end cap.
+//!
+//! The sink must also clean up the paths as this is not done by the offsetter. The reason is that in case the `a` path
+//! is the output path you can just keep it and insert `b` path into it (clearing only `b` path after each call).
+PathStrokeSinkFunc :: proc "c" (a: ^PathCore, b: ^PathCore, _c: ^PathCore, input_start: c.size_t, input_end: c.size_t, user_data: rawptr) -> Result
+
+//! 2D vector path [C API].
+PathCore :: struct {
+ _d: ObjectDetail,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ path_init :: proc(self: ^PathCore) -> Result ---
+ path_init_move :: proc(self: ^PathCore, other: ^PathCore) -> Result ---
+ path_init_weak :: proc(self: ^PathCore, other: ^PathCore) -> Result ---
+ path_destroy :: proc(self: ^PathCore) -> Result ---
+ path_reset :: proc(self: ^PathCore) -> Result ---
+ path_get_size :: proc(self: ^PathCore) -> c.size_t ---
+ path_get_capacity :: proc(self: ^PathCore) -> c.size_t ---
+ path_get_command_data :: proc(self: ^PathCore) -> ^u8 ---
+ path_get_vertex_data :: proc(self: ^PathCore) -> ^Point ---
+ path_clear :: proc(self: ^PathCore) -> Result ---
+ path_shrink :: proc(self: ^PathCore) -> Result ---
+ path_reserve :: proc(self: ^PathCore, n: c.size_t) -> Result ---
+ path_modify_op :: proc(self: ^PathCore, op: ModifyOp, n: c.size_t, cmd_data_out: ^^u8, vtx_data_out: ^^Point) -> Result ---
+ path_assign_move :: proc(self: ^PathCore, other: ^PathCore) -> Result ---
+ path_assign_weak :: proc(self: ^PathCore, other: ^PathCore) -> Result ---
+ path_assign_deep :: proc(self: ^PathCore, other: ^PathCore) -> Result ---
+ path_set_vertex_at :: proc(self: ^PathCore, index: c.size_t, cmd: u32, x: f64, y: f64) -> Result ---
+ path_move_to :: proc(self: ^PathCore, x0: f64, y0: f64) -> Result ---
+ path_line_to :: proc(self: ^PathCore, x1: f64, y1: f64) -> Result ---
+ path_poly_to :: proc(self: ^PathCore, poly: ^Point, count: c.size_t) -> Result ---
+ path_quad_to :: proc(self: ^PathCore, x1: f64, y1: f64, x2: f64, y2: f64) -> Result ---
+ path_conic_to :: proc(self: ^PathCore, x1: f64, y1: f64, x2: f64, y2: f64, w: f64) -> Result ---
+ path_cubic_to :: proc(self: ^PathCore, x1: f64, y1: f64, x2: f64, y2: f64, x3: f64, y3: f64) -> Result ---
+ path_smooth_quad_to :: proc(self: ^PathCore, x2: f64, y2: f64) -> Result ---
+ path_smooth_cubic_to :: proc(self: ^PathCore, x2: f64, y2: f64, x3: f64, y3: f64) -> Result ---
+ path_arc_to :: proc(self: ^PathCore, x: f64, y: f64, rx: f64, ry: f64, start: f64, sweep: f64, force_move_to: i32) -> Result ---
+ path_arc_quadrant_to :: proc(self: ^PathCore, x1: f64, y1: f64, x2: f64, y2: f64) -> Result ---
+ path_elliptic_arc_to :: proc(self: ^PathCore, rx: f64, ry: f64, xAxisRotation: f64, large_arc_flag: i32, sweep_flag: i32, x1: f64, y1: f64) -> Result ---
+ path_close :: proc(self: ^PathCore) -> Result ---
+ path_add_geometry :: proc(self: ^PathCore, geometry_type: GeometryType, geometry_data: rawptr, m: ^Matrix2D, dir: GeometryDirection) -> Result ---
+ path_add_box_i :: proc(self: ^PathCore, box: ^BoxI, dir: GeometryDirection) -> Result ---
+ path_add_box_d :: proc(self: ^PathCore, box: ^Box, dir: GeometryDirection) -> Result ---
+ path_add_rect_i :: proc(self: ^PathCore, rect: ^RectI, dir: GeometryDirection) -> Result ---
+ path_add_rect_d :: proc(self: ^PathCore, rect: ^Rect, dir: GeometryDirection) -> Result ---
+ path_add_path :: proc(self: ^PathCore, other: ^PathCore, range: ^Range) -> Result ---
+ path_add_translated_path :: proc(self: ^PathCore, other: ^PathCore, range: ^Range, p: ^Point) -> Result ---
+ path_add_transformed_path :: proc(self: ^PathCore, other: ^PathCore, range: ^Range, m: ^Matrix2D) -> Result ---
+ path_add_reversed_path :: proc(self: ^PathCore, other: ^PathCore, range: ^Range, reverse_mode: PathReverseMode) -> Result ---
+ path_add_stroked_path :: proc(self: ^PathCore, other: ^PathCore, range: ^Range, options: ^StrokeOptionsCore, approx: ^ApproximationOptions) -> Result ---
+ path_remove_range :: proc(self: ^PathCore, range: ^Range) -> Result ---
+ path_translate :: proc(self: ^PathCore, range: ^Range, p: ^Point) -> Result ---
+ path_transform :: proc(self: ^PathCore, range: ^Range, m: ^Matrix2D) -> Result ---
+ path_fit_to :: proc(self: ^PathCore, range: ^Range, rect: ^Rect, fit_flags: u32) -> Result ---
+ path_equals :: proc(a: ^PathCore, b: ^PathCore) -> i32 ---
+ path_get_info_flags :: proc(self: ^PathCore, flags_out: ^u32) -> Result ---
+ path_get_control_box :: proc(self: ^PathCore, box_out: ^Box) -> Result ---
+ path_get_bounding_box :: proc(self: ^PathCore, box_out: ^Box) -> Result ---
+ path_get_figure_range :: proc(self: ^PathCore, index: c.size_t, range_out: ^Range) -> Result ---
+ path_get_last_vertex :: proc(self: ^PathCore, vtx_out: ^Point) -> Result ---
+ path_get_closest_vertex :: proc(self: ^PathCore, p: ^Point, max_distance: f64, index_out: ^c.size_t, distance_out: ^f64) -> Result ---
+ path_hit_test :: proc(self: ^PathCore, p: ^Point, fill_rule: FillRule) -> HitTest ---
+}
+
+//! Stroke options [C API].
+StrokeOptionsCore :: struct {
+ using _: struct #raw_union {
+ using _: struct {
+ start_cap: u8,
+ end_cap: u8,
+ join: u8,
+ transform_order: u8,
+ reserved: [4]u8,
+ },
+
+ caps: [2]u8,
+ hints: u64,
+ },
+
+ width: f64,
+ miter_limit: f64,
+ dash_offset: f64,
+ dash_array: ArrayCore,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ stroke_options_init :: proc(self: ^StrokeOptionsCore) -> Result ---
+ stroke_options_init_move :: proc(self: ^StrokeOptionsCore, other: ^StrokeOptionsCore) -> Result ---
+ stroke_options_init_weak :: proc(self: ^StrokeOptionsCore, other: ^StrokeOptionsCore) -> Result ---
+ stroke_options_destroy :: proc(self: ^StrokeOptionsCore) -> Result ---
+ stroke_options_reset :: proc(self: ^StrokeOptionsCore) -> Result ---
+ stroke_options_equals :: proc(a: ^StrokeOptionsCore, b: ^StrokeOptionsCore) -> i32 ---
+ stroke_options_assign_move :: proc(self: ^StrokeOptionsCore, other: ^StrokeOptionsCore) -> Result ---
+ stroke_options_assign_weak :: proc(self: ^StrokeOptionsCore, other: ^StrokeOptionsCore) -> Result ---
+ path_stroke_to_sink :: proc(self: ^PathCore, range: ^Range, stroke_options: ^StrokeOptionsCore, approximation_options: ^ApproximationOptions, a: ^PathCore, b: ^PathCore, _c: ^PathCore, sink: PathStrokeSinkFunc, user_data: rawptr) -> Result ---
+}
+
+//! 2D vector path [Impl].
+PathImpl :: struct {
+ //! Union of either raw path-data or their `view`.
+ using _: struct #raw_union {
+ using _: struct {
+ //! Command data
+ command_data: ^u8,
+
+ //! Vertex data.
+ vertex_data: ^Point,
+
+ //! Vertex/command count.
+ size: c.size_t,
+ },
+
+ //! Path data as view.
+ view: PathView,
+ },
+
+ //! Path vertex/command capacity.
+ capacity: c.size_t,
+
+ //! Path flags related to caching.
+ flags: u32,
+}
+
diff --git a/binding/pattern.odin b/binding/pattern.odin
@@ -0,0 +1,78 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Pattern quality.
+PatternQuality :: enum u32 {
+ //! Nearest neighbor interpolation.
+ NEAREST = 0,
+
+ //! Bilinear interpolation.
+ BILINEAR = 1,
+
+ //! Maximum value of `BLPatternQuality`.
+ MAX_VALUE = 1,
+ FORCE_UINT = 4294967295,
+}
+
+//! Pattern [C API].
+PatternCore :: struct {
+ _d: ObjectDetail,
+}
+
+//! \cond INTERNAL
+//! Pattern [C API Impl].
+//!
+//! The following properties are stored in BLObjectInfo:
+//!
+//! - Pattern extend mode is stored in BLObjectInfo's 'b' field.
+//! - Pattern matrix type is stored in BLObjectInfo's 'c' field.
+PatternImpl :: struct {
+ //! Image used by the pattern.
+ image: ImageCore,
+
+ //! Image area to use.
+ area: RectI,
+
+ //! Pattern transformation matrix.
+ transform: Matrix2D,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \endcond
+ pattern_init :: proc(self: ^PatternCore) -> Result ---
+ pattern_init_move :: proc(self: ^PatternCore, other: ^PatternCore) -> Result ---
+ pattern_init_weak :: proc(self: ^PatternCore, other: ^PatternCore) -> Result ---
+ pattern_init_as :: proc(self: ^PatternCore, image: ^ImageCore, area: ^RectI, extend_mode: ExtendMode, transform: ^Matrix2D) -> Result ---
+ pattern_destroy :: proc(self: ^PatternCore) -> Result ---
+ pattern_reset :: proc(self: ^PatternCore) -> Result ---
+ pattern_assign_move :: proc(self: ^PatternCore, other: ^PatternCore) -> Result ---
+ pattern_assign_weak :: proc(self: ^PatternCore, other: ^PatternCore) -> Result ---
+ pattern_assign_deep :: proc(self: ^PatternCore, other: ^PatternCore) -> Result ---
+ pattern_create :: proc(self: ^PatternCore, image: ^ImageCore, area: ^RectI, extend_mode: ExtendMode, transform: ^Matrix2D) -> Result ---
+ pattern_get_image :: proc(self: ^PatternCore, image: ^ImageCore) -> Result ---
+ pattern_set_image :: proc(self: ^PatternCore, image: ^ImageCore, area: ^RectI) -> Result ---
+ pattern_reset_image :: proc(self: ^PatternCore) -> Result ---
+ pattern_get_area :: proc(self: ^PatternCore, area_out: ^RectI) -> Result ---
+ pattern_set_area :: proc(self: ^PatternCore, area: ^RectI) -> Result ---
+ pattern_reset_area :: proc(self: ^PatternCore) -> Result ---
+ pattern_get_extend_mode :: proc(self: ^PatternCore) -> ExtendMode ---
+ pattern_set_extend_mode :: proc(self: ^PatternCore, extend_mode: ExtendMode) -> Result ---
+ pattern_get_transform :: proc(self: ^PatternCore, transform_out: ^Matrix2D) -> Result ---
+ pattern_get_transform_type :: proc(self: ^PatternCore) -> TransformType ---
+ pattern_apply_transform_op :: proc(self: ^PatternCore, op_type: TransformOp, op_data: rawptr) -> Result ---
+ pattern_equals :: proc(a: ^PatternCore, b: ^PatternCore) -> i32 ---
+}
+
diff --git a/binding/pixelconverter.odin b/binding/pixelconverter.odin
@@ -0,0 +1,80 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Pixel converter function.
+PixelConverterFunc :: proc "c" (self: ^PixelConverterCore, dst_data: ^u8, dst_stride: c.intptr_t, src_data: ^u8, src_stride: c.intptr_t, w: u32, h: u32, options: ^PixelConverterOptions) -> Result
+
+//! Flags used by `BLPixelConverter::create()` function.
+PixelConverterCreateFlags :: enum u32 {
+ //! No flags.
+ NO_FLAGS = 0,
+
+ //! Specifies that the source palette in `BLFormatInfo` doesn't have to by copied by `BLPixelConverter`. The caller
+ //! must ensure that the palette would stay valid until the pixel converter is destroyed.
+ FLAG_DONT_COPY_PALETTE = 1,
+
+ //! Specifies that the source palette in `BLFormatInfo` is alterable and the pixel converter can modify it when
+ //! preparing the conversion. The modification can be irreversible so only use this flag when you are sure that
+ //! the palette passed to `BLPixelConverter::create()` won't be needed outside of pixel conversion.
+ //!
+ //! \note The flag `BL_PIXEL_CONVERTER_CREATE_FLAG_DONT_COPY_PALETTE` must be set as well, otherwise this flag would
+ //! be ignored.
+ FLAG_ALTERABLE_PALETTE = 2,
+
+ //! When there is no built-in conversion between the given pixel formats it's possible to use an intermediate format
+ //! that is used during conversion. In such case the base pixel converter creates two more converters that are then
+ //! used internally.
+ //!
+ //! This option disables such feature - creating a pixel converter would fail with `BL_ERROR_NOT_IMPLEMENTED` error
+ //! if direct conversion is not possible.
+ FLAG_NO_MULTI_STEP = 4,
+ FLAG_FORCE_UINT = 4294967295,
+}
+
+//! Pixel conversion options.
+PixelConverterOptions :: struct {
+ origin: PointI,
+ gap: c.size_t,
+}
+
+//! Pixel converter [C API].
+PixelConverterCore :: struct {
+ using _: struct #raw_union {
+ using _: struct {
+ //! Converter function.
+ convert_func: PixelConverterFunc,
+
+ //! Internal flags used by the converter - non-zero value means initialized.
+ internal_flags: u8,
+ },
+
+ //! Internal data not exposed to users, aligned to sizeof(void*).
+ data: [80]u8,
+ },
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ pixel_converter_init :: proc(self: ^PixelConverterCore) -> Result ---
+ pixel_converter_init_weak :: proc(self: ^PixelConverterCore, other: ^PixelConverterCore) -> Result ---
+ pixel_converter_destroy :: proc(self: ^PixelConverterCore) -> Result ---
+ pixel_converter_reset :: proc(self: ^PixelConverterCore) -> Result ---
+ pixel_converter_assign :: proc(self: ^PixelConverterCore, other: ^PixelConverterCore) -> Result ---
+ pixel_converter_create :: proc(self: ^PixelConverterCore, dst_info: ^FormatInfo, src_info: ^FormatInfo, create_flags: PixelConverterCreateFlags) -> Result ---
+ pixel_converter_convert :: proc(self: ^PixelConverterCore, dst_data: rawptr, dst_stride: c.intptr_t, src_data: rawptr, src_stride: c.intptr_t, w: u32, h: u32, options: ^PixelConverterOptions) -> Result ---
+}
+
diff --git a/binding/random.odin b/binding/random.odin
@@ -0,0 +1,35 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \name BLRandom - C API
+ //! \{
+ random_reset :: proc(self: ^Random, seed: u64) -> Result ---
+ random_next_uint32 :: proc(self: ^Random) -> u32 ---
+ random_next_uint64 :: proc(self: ^Random) -> u64 ---
+ random_next_double :: proc(self: ^Random) -> f64 ---
+}
+
+//! Simple pseudo random number generator based on `XORSHIFT+`, which has 64-bit seed, 128 bits of state, and full
+//! period `2^128 - 1`.
+//!
+//! Based on a paper by Sebastiano Vigna:
+//! http://vigna.di.unimi.it/ftp/papers/xorshiftplus.pdf
+Random :: struct {
+ //! PRNG state.
+ data: [2]u64,
+}
+
diff --git a/binding/rgba.odin b/binding/rgba.odin
@@ -0,0 +1,42 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! 32-bit RGBA color (8-bit per component) stored as `0xAARRGGBB`.
+Rgba32 :: struct {
+ //! Packed 32-bit RGBA value.
+ value: u32,
+}
+
+//! 64-bit RGBA color (16-bit per component) stored as `0xAAAARRRRGGGGBBBB`.
+Rgba64 :: struct {
+ //! Packed 64-bit RGBA value.
+ value: u64,
+}
+
+//! 128-bit RGBA color stored as 4 32-bit floating point values in [RGBA] order.
+Rgba :: struct {
+ //! Red component.
+ r: f32,
+
+ //! Green component.
+ g: f32,
+
+ //! Blur component.
+ b: f32,
+
+ //! Alpha component.
+ a: f32,
+}
+
diff --git a/binding/runtime.odin b/binding/runtime.odin
@@ -0,0 +1,230 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Blend2D runtime limits.
+//!
+//! \note These constants are used across Blend2D, but they are not designed to be ABI stable. New versions of Blend2D
+//! can increase certain limits without notice. Use runtime to query the limits dynamically, see \ref BLRuntimeBuildInfo.
+RuntimeLimits :: enum u32 {
+ //! Maximum width and height of an image.
+ IMAGE_SIZE = 65535,
+
+ //! Maximum number of threads for asynchronous operations (including rendering).
+ THREAD_COUNT = 32,
+}
+
+//! Type of runtime information that can be queried through \ref bl_runtime_query_info().
+RuntimeInfoType :: enum u32 {
+ //! Blend2D build information.
+ BUILD = 0,
+
+ //! System information (includes CPU architecture, features, core count, etc...).
+ SYSTEM = 1,
+
+ //! Resources information (includes Blend2D memory consumption)
+ RESOURCE = 2,
+
+ //! Count of runtime information types.
+ MAX_VALUE = 2,
+ FORCE_UINT = 4294967295,
+}
+
+//! Blend2D runtime build type.
+RuntimeBuildType :: enum u32 {
+ //! Describes a Blend2D debug build.
+ DEBUG = 0,
+
+ //! Describes a Blend2D release build.
+ RELEASE = 1,
+ FORCE_UINT = 4294967295,
+}
+
+//! CPU architecture that can be queried by `BLRuntime::query_system_info()`.
+RuntimeCpuArch :: enum u32 {
+ //! Unknown architecture.
+ UNKNOWN = 0,
+
+ //! 32-bit or 64-bit X86 architecture.
+ X86 = 1,
+
+ //! 32-bit or 64-bit ARM architecture.
+ ARM = 2,
+
+ //! 32-bit or 64-bit MIPS architecture.
+ MIPS = 3,
+ FORCE_UINT = 4294967295,
+}
+
+//! CPU features Blend2D supports.
+RuntimeCpuFeatures :: enum u32 {
+ X86_SSE2 = 1,
+ X86_SSE3 = 2,
+ X86_SSSE3 = 4,
+ X86_SSE4_1 = 8,
+ X86_SSE4_2 = 16,
+ X86_AVX = 32,
+ X86_AVX2 = 64,
+ X86_AVX512 = 128,
+ ARM_ASIMD = 1,
+ ARM_CRC32 = 2,
+ ARM_PMULL = 4,
+ FORCE_UINT = 4294967295,
+}
+
+//! Runtime cleanup flags that can be used through `BLRuntime::cleanup()`.
+RuntimeCleanupFlags :: enum u32 {
+ //! No flags.
+ NO_FLAGS = 0,
+
+ //! Cleanup object memory pool.
+ OBJECT_POOL = 1,
+
+ //! Cleanup zeroed memory pool.
+ ZEROED_POOL = 2,
+
+ //! Cleanup thread pool (would join unused threads).
+ THREAD_POOL = 16,
+
+ //! Cleanup everything.
+ EVERYTHING = 4294967295,
+ FLAG_FORCE_UINT = 4294967295,
+}
+
+//! Blend2D build information.
+RuntimeBuildInfo :: struct {
+ //! Major version number.
+ major_version: u32,
+
+ //! Minor version number.
+ minor_version: u32,
+
+ //! Patch version number.
+ patch_version: u32,
+
+ //! Blend2D build type, see \ref BLRuntimeBuildType.
+ build_type: u32,
+
+ //! Baseline CPU features, see \ref BLRuntimeCpuFeatures.
+ //!
+ //! These features describe CPU features that were detected at compile-time. Baseline features are used to compile
+ //! all source files so they represent the minimum feature-set the target CPU must support to run Blend2D.
+ //!
+ //! Official Blend2D builds set baseline at SSE2 on X86 target and NEON on ARM target. Custom builds can set use
+ //! a different baseline, which can be read through `BLRuntimeBuildInfo`.
+ baseline_cpu_features: u32,
+
+ //! Supported CPU features, see \ref BLRuntimeCpuFeatures.
+ //!
+ //! These features do not represent the features that the host CPU must support, instead, they represent all features
+ //! that Blend2D can take advantage of in C++ code that uses instruction intrinsics. For example if AVX2 is part of
+ //! `supported_cpu_features` it means that Blend2D can take advantage of it if there is a specialized code-path.
+ supported_cpu_features: u32,
+
+ //! Maximum size of an image (both width and height).
+ max_image_size: u32,
+
+ //! Maximum number of threads for asynchronous operations, including rendering.
+ max_thread_count: u32,
+
+ //! Reserved, must be zero.
+ reserved: [2]u32,
+
+ //! Identification of the C++ compiler used to build Blend2D.
+ compiler_info: [32]i8,
+}
+
+//! System information queried by the runtime.
+RuntimeSystemInfo :: struct {
+ //! Host CPU architecture, see \ref BLRuntimeCpuArch.
+ cpu_arch: u32,
+
+ //! Host CPU features, see \ref BLRuntimeCpuFeatures.
+ cpu_features: u32,
+
+ //! Number of cores of the host CPU/CPUs.
+ core_count: u32,
+
+ //! Number of threads of the host CPU/CPUs.
+ thread_count: u32,
+
+ //! Minimum stack size of a worker thread used by Blend2D.
+ thread_stack_size: u32,
+
+ //! Removed field.
+ removed: u32,
+
+ //! Allocation granularity of virtual memory (includes thread's stack).
+ allocation_granularity: u32,
+
+ //! Reserved for future use.
+ reserved: [5]u32,
+
+ //! Host CPU vendor string such "AMD", "APPLE", "INTEL", "SAMSUNG", etc...
+ cpu_vendor: [16]i8,
+
+ //! Host CPU brand string or empty string if not detected properly.
+ cpu_brand: [64]i8,
+}
+
+//! Provides information about resources allocated by Blend2D.
+RuntimeResourceInfo :: struct {
+ //! Virtual memory used at this time.
+ vm_used: c.size_t,
+
+ //! Virtual memory reserved (allocated internally).
+ vm_reserved: c.size_t,
+
+ //! Overhead required to manage virtual memory allocations.
+ vm_overhead: c.size_t,
+
+ //! Number of blocks of virtual memory allocated.
+ vm_block_count: c.size_t,
+
+ //! Zeroed memory used at this time.
+ zm_used: c.size_t,
+
+ //! Zeroed memory reserved (allocated internally).
+ zm_reserved: c.size_t,
+
+ //! Overhead required to manage zeroed memory allocations.
+ zm_overhead: c.size_t,
+
+ //! Number of blocks of zeroed memory allocated.
+ zm_block_count: c.size_t,
+
+ //! Count of dynamic pipelines created and cached.
+ dynamic_pipeline_count: c.size_t,
+
+ //! Reserved for future use.
+ reserved: [7]c.size_t,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! Initialized Blend2D runtime
+ runtime_init :: proc() -> Result ---
+
+ //! Shuts down Blend2D runtime
+ runtime_shutdown :: proc() -> Result ---
+ runtime_cleanup :: proc(cleanup_flags: RuntimeCleanupFlags) -> Result ---
+ runtime_query_info :: proc(info_type: RuntimeInfoType, info_out: rawptr) -> Result ---
+ runtime_message_out :: proc(msg: cstring) -> Result ---
+ runtime_message_fmt :: proc(fmt: cstring, #c_vararg _: ..any) -> Result ---
+ runtime_message_vfmt :: proc(fmt: cstring, ap: i32) -> Result ---
+ result_from_posix_error :: proc(e: i32) -> Result ---
+}
+
diff --git a/binding/runtimescope.odin b/binding/runtimescope.odin
@@ -0,0 +1,27 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Blend2D runtime scope [C API].
+RuntimeScopeCore :: struct {
+ data: [2]u32,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ runtime_scope_begin :: proc(self: ^RuntimeScopeCore) -> Result ---
+ runtime_scope_end :: proc(self: ^RuntimeScopeCore) -> Result ---
+ runtime_scope_is_active :: proc(self: ^RuntimeScopeCore) -> i32 ---
+}
+
diff --git a/binding/string.odin b/binding/string.odin
@@ -0,0 +1,71 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Byte string [C API].
+StringCore :: struct {
+ _d: ObjectDetail,
+}
+
+//! \cond INTERNAL
+//! Byte string [Impl].
+StringImpl :: struct {
+ //! String size [in bytes].
+ size: c.size_t,
+
+ //! String data capacity [in bytes].
+ capacity: c.size_t,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ //! \endcond
+ string_init :: proc(self: ^StringCore) -> Result ---
+ string_init_move :: proc(self: ^StringCore, other: ^StringCore) -> Result ---
+ string_init_weak :: proc(self: ^StringCore, other: ^StringCore) -> Result ---
+ string_init_with_data :: proc(self: ^StringCore, str: cstring, size: c.size_t) -> Result ---
+ string_destroy :: proc(self: ^StringCore) -> Result ---
+ string_reset :: proc(self: ^StringCore) -> Result ---
+ string_get_data :: proc(self: ^StringCore) -> cstring ---
+ string_get_size :: proc(self: ^StringCore) -> c.size_t ---
+ string_get_capacity :: proc(self: ^StringCore) -> c.size_t ---
+ string_clear :: proc(self: ^StringCore) -> Result ---
+ string_shrink :: proc(self: ^StringCore) -> Result ---
+ string_reserve :: proc(self: ^StringCore, n: c.size_t) -> Result ---
+ string_resize :: proc(self: ^StringCore, n: c.size_t, fill: i8) -> Result ---
+ string_make_mutable :: proc(self: ^StringCore, data_out: ^cstring) -> Result ---
+ string_modify_op :: proc(self: ^StringCore, op: ModifyOp, n: c.size_t, data_out: ^cstring) -> Result ---
+ string_insert_op :: proc(self: ^StringCore, index: c.size_t, n: c.size_t, data_out: ^cstring) -> Result ---
+ string_assign_move :: proc(self: ^StringCore, other: ^StringCore) -> Result ---
+ string_assign_weak :: proc(self: ^StringCore, other: ^StringCore) -> Result ---
+ string_assign_deep :: proc(self: ^StringCore, other: ^StringCore) -> Result ---
+ string_assign_data :: proc(self: ^StringCore, str: cstring, n: c.size_t) -> Result ---
+ string_apply_op_char :: proc(self: ^StringCore, op: ModifyOp, _c: i8, n: c.size_t) -> Result ---
+ string_apply_op_data :: proc(self: ^StringCore, op: ModifyOp, str: cstring, n: c.size_t) -> Result ---
+ string_apply_op_string :: proc(self: ^StringCore, op: ModifyOp, other: ^StringCore) -> Result ---
+ string_apply_op_format :: proc(self: ^StringCore, op: ModifyOp, fmt: cstring, #c_vararg _: ..any) -> Result ---
+ string_apply_op_format_v :: proc(self: ^StringCore, op: ModifyOp, fmt: cstring, ap: i32) -> Result ---
+ string_insert_char :: proc(self: ^StringCore, index: c.size_t, _c: i8, n: c.size_t) -> Result ---
+ string_insert_data :: proc(self: ^StringCore, index: c.size_t, str: cstring, n: c.size_t) -> Result ---
+ string_insert_string :: proc(self: ^StringCore, index: c.size_t, other: ^StringCore) -> Result ---
+ string_remove_index :: proc(self: ^StringCore, index: c.size_t) -> Result ---
+ string_remove_range :: proc(self: ^StringCore, r_start: c.size_t, r_end: c.size_t) -> Result ---
+ string_equals :: proc(a: ^StringCore, b: ^StringCore) -> i32 ---
+ string_equals_data :: proc(self: ^StringCore, str: cstring, n: c.size_t) -> i32 ---
+ string_compare :: proc(a: ^StringCore, b: ^StringCore) -> i32 ---
+ string_compare_data :: proc(self: ^StringCore, str: cstring, n: c.size_t) -> i32 ---
+}
+
diff --git a/binding/var.odin b/binding/var.odin
@@ -0,0 +1,71 @@
+// This file is part of Blend2D project <https://blend2d.com>
+//
+// See blend2d.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+package blend2d
+
+when ODIN_OS == .Windows {
+ foreign import lib "blend2d.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "libblend2d.a"
+} else when ODIN_OS == .Linux {
+ foreign import lib "libblend2d.a"
+}
+
+
+//! Variant [C API].
+VarCore :: struct {
+ _d: ObjectDetail,
+}
+
+@(default_calling_convention="c", link_prefix="bl_")
+foreign lib {
+ var_init_type :: proc(self: ^Unknown, type: ObjectType) -> Result ---
+ var_init_null :: proc(self: ^Unknown) -> Result ---
+ var_init_bool :: proc(self: ^Unknown, value: i32) -> Result ---
+ var_init_int32 :: proc(self: ^Unknown, value: i32) -> Result ---
+ var_init_int64 :: proc(self: ^Unknown, value: i64) -> Result ---
+ var_init_uint32 :: proc(self: ^Unknown, value: u32) -> Result ---
+ var_init_uint64 :: proc(self: ^Unknown, value: u64) -> Result ---
+ var_init_double :: proc(self: ^Unknown, value: f64) -> Result ---
+ var_init_rgba :: proc(self: ^Unknown, rgba: ^Rgba) -> Result ---
+ var_init_rgba32 :: proc(self: ^Unknown, rgba32: u32) -> Result ---
+ var_init_rgba64 :: proc(self: ^Unknown, rgba64: u64) -> Result ---
+ var_init_move :: proc(self: ^Unknown, other: ^Unknown) -> Result ---
+ var_init_weak :: proc(self: ^Unknown, other: ^Unknown) -> Result ---
+ var_destroy :: proc(self: ^Unknown) -> Result ---
+ var_reset :: proc(self: ^Unknown) -> Result ---
+ var_assign_null :: proc(self: ^Unknown) -> Result ---
+ var_assign_bool :: proc(self: ^Unknown, value: i32) -> Result ---
+ var_assign_int32 :: proc(self: ^Unknown, value: i32) -> Result ---
+ var_assign_int64 :: proc(self: ^Unknown, value: i64) -> Result ---
+ var_assign_uint32 :: proc(self: ^Unknown, value: u32) -> Result ---
+ var_assign_uint64 :: proc(self: ^Unknown, value: u64) -> Result ---
+ var_assign_double :: proc(self: ^Unknown, value: f64) -> Result ---
+ var_assign_rgba :: proc(self: ^Unknown, rgba: ^Rgba) -> Result ---
+ var_assign_rgba32 :: proc(self: ^Unknown, rgba32: u32) -> Result ---
+ var_assign_rgba64 :: proc(self: ^Unknown, rgba64: u64) -> Result ---
+ var_assign_move :: proc(self: ^Unknown, other: ^Unknown) -> Result ---
+ var_assign_weak :: proc(self: ^Unknown, other: ^Unknown) -> Result ---
+ var_get_type :: proc(self: ^Unknown) -> ObjectType ---
+ var_to_bool :: proc(self: ^Unknown, out: ^i32) -> Result ---
+ var_to_int32 :: proc(self: ^Unknown, out: ^i32) -> Result ---
+ var_to_int64 :: proc(self: ^Unknown, out: ^i64) -> Result ---
+ var_to_uint32 :: proc(self: ^Unknown, out: ^u32) -> Result ---
+ var_to_uint64 :: proc(self: ^Unknown, out: ^u64) -> Result ---
+ var_to_double :: proc(self: ^Unknown, out: ^f64) -> Result ---
+ var_to_rgba :: proc(self: ^Unknown, out: ^Rgba) -> Result ---
+ var_to_rgba32 :: proc(self: ^Unknown, out: ^u32) -> Result ---
+ var_to_rgba64 :: proc(self: ^Unknown, out: ^u64) -> Result ---
+ var_equals :: proc(a: ^Unknown, b: ^Unknown) -> i32 ---
+ var_equals_null :: proc(self: ^Unknown) -> i32 ---
+ var_equals_bool :: proc(self: ^Unknown, value: i32) -> i32 ---
+ var_equals_int64 :: proc(self: ^Unknown, value: i64) -> i32 ---
+ var_equals_uint64 :: proc(self: ^Unknown, value: u64) -> i32 ---
+ var_equals_double :: proc(self: ^Unknown, value: f64) -> i32 ---
+ var_equals_rgba :: proc(self: ^Unknown, rgba: ^Rgba) -> i32 ---
+ var_equals_rgba32 :: proc(self: ^Unknown, rgba32: u32) -> i32 ---
+ var_equals_rgba64 :: proc(self: ^Unknown, rgba64: u64) -> i32 ---
+ var_strict_equals :: proc(a: ^Unknown, b: ^Unknown) -> i32 ---
+}
+