1600 lines
58 KiB
C
1600 lines
58 KiB
C
|
// 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
|
||
|
|
||
|
#ifndef BLEND2D_API_H_INCLUDED
|
||
|
#define BLEND2D_API_H_INCLUDED
|
||
|
|
||
|
// This header can only be included by either <blend2d.h> or by internal Blend2D headers. Prevent users including
|
||
|
// <blend2d/...> headers by accident and prevent not including "blend2d/api-build_p.h" during the Blend2D compilation.
|
||
|
#if !defined(BLEND2D_H_INCLUDED) && !defined(BLEND2D_API_BUILD_P_H_INCLUDED) && !defined(__INTELLISENSE__)
|
||
|
#pragma message("Include either <blend2d.h> or <blend2d-impl.h> to use Blend2D library")
|
||
|
#endif
|
||
|
|
||
|
#include <stdarg.h>
|
||
|
#include <stddef.h>
|
||
|
#include <stdint.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
#include <type_traits>
|
||
|
#else
|
||
|
#include <stdbool.h>
|
||
|
#endif
|
||
|
|
||
|
//! \mainpage API Reference
|
||
|
//!
|
||
|
//! Blend2D C/C++ API reference documentation generated by Doxygen.
|
||
|
//!
|
||
|
//! \section main_introduction Introduction
|
||
|
//!
|
||
|
//! Blend2D API consists of enumerations, functions, structs, and C++ classes. Common concepts like enumerations and
|
||
|
//! POD structs are shared between C and C++. Some structs contain extra functionality like `BLSomething::reset()`
|
||
|
//! that is only available to C++ users, however, such functionality is only provided for convenience and doesn't
|
||
|
//! affect how Blend2D can be used from C.
|
||
|
//!
|
||
|
//! Blend2D C++ API is in fact build on top of the C API and all C++ functions are inlines that call C API without any
|
||
|
//! overhead. It would require double effort to document both C and C++ APIs separately so we have decided to only
|
||
|
//! document C++ API and to only list \ref blend2d_api_c_functions "C API" for users that need it. The C API should be
|
||
|
//! straightforward and matches very well the C++ part.
|
||
|
//!
|
||
|
//! \section main_important Important
|
||
|
//!
|
||
|
//! Doxygen sorts struct members in anonymous structs and unions and we haven't figured out how to turn this off. This
|
||
|
//! means that the order of members in "Public Attributes" doesn't have to reflect the original struct packing. Always
|
||
|
//! double-check struct members in case you plan to use a brace initialization of simple structs.
|
||
|
//!
|
||
|
//! \section main_groups Groups
|
||
|
//!
|
||
|
//! The documentation is split into the following groups:
|
||
|
//!
|
||
|
//! $$DOCS_GROUP_OVERVIEW$$
|
||
|
|
||
|
//! \defgroup blend2d_api_globals Global API
|
||
|
//! \brief Global functions, constants, and classes used universally across
|
||
|
//! the library.
|
||
|
|
||
|
//! \defgroup blend2d_api_geometry Geometry API
|
||
|
//! \brief Geometries, paths, and transformations.
|
||
|
//!
|
||
|
//! Blend2D offers various geometry structures and objects that can be used with
|
||
|
//! either `BLPath` for path building or `BLContext` for rendering.
|
||
|
|
||
|
//! \defgroup blend2d_api_imaging Imaging API
|
||
|
//! \brief Images and image codecs.
|
||
|
|
||
|
//! \defgroup blend2d_api_styling Styling API
|
||
|
//! \brief Colors, gradients, and patterns.
|
||
|
|
||
|
//! \defgroup blend2d_api_text Text API
|
||
|
//! \brief Fonts & Text support.
|
||
|
|
||
|
//! \defgroup blend2d_api_rendering Rendering Context
|
||
|
//! \brief 2D rendering context API, structures, and constants.
|
||
|
|
||
|
//! \defgroup blend2d_api_runtime Runtime API
|
||
|
//! \brief Interaction with Blend2D runtime.
|
||
|
|
||
|
//! \defgroup blend2d_api_filesystem Filesystem API
|
||
|
//! \brief Filesystem utilities.
|
||
|
|
||
|
//! \defgroup blend2d_api_impl Impl API
|
||
|
//! \brief API required for extending Blend2D functionality.
|
||
|
//!
|
||
|
//! Everything that is part of this group requires `<blend2d-impl.h>` to be
|
||
|
//! included before the use as this API is only for users that extend Blend2D.
|
||
|
|
||
|
//! \defgroup blend2d_api_macros Macros
|
||
|
//! \brief Preprocessor macros and compile-time constants.
|
||
|
|
||
|
//! \defgroup blend2d_api_c_functions C API
|
||
|
//! \brief Global C API functions exported as `extern "C"` (C API).
|
||
|
//!
|
||
|
//! We do not document these functions as they are called from C++ wrappers, which are documented and should be used
|
||
|
//! as a reference. The most important thing in using C API is to understand how lifetime of objects is managed.
|
||
|
//!
|
||
|
//! Each type that requires initialization provides `Init`, 'Destroy', and `Reset` functions. Init/Destroy are called
|
||
|
//! by C++ constructors and destructors on C++ side and must be used the same way by C users. Although these functions
|
||
|
//! return `BLResult` it's guaranteed the result is always `BL_SUCCESS` - the return value is only provided for
|
||
|
//! consistency and possible tail calling.
|
||
|
//!
|
||
|
//! The following example should illustrate how `Init` and `Destroy` works:
|
||
|
//!
|
||
|
//! ```
|
||
|
//! BLImageCore img;
|
||
|
//!
|
||
|
//! // Initializes the BLImage object, always succeeds.
|
||
|
//! blImageInit(&img);
|
||
|
//!
|
||
|
//! // Creates image data, note how it's called on an already initialized object.
|
||
|
//! blImageCreate(&img, 128, 128, BL_FORMAT_PRGB32);
|
||
|
//!
|
||
|
//! // Destroys the BLImage object, always succeeds.
|
||
|
//! blImageDestroy(&img);
|
||
|
//! ```
|
||
|
//!
|
||
|
//! Some init functions may provide shortcuts for the most used scenarios that
|
||
|
//! merge initialization and resource allocation into a single function:
|
||
|
//!
|
||
|
//! ```
|
||
|
//! BLImageCore img;
|
||
|
//!
|
||
|
//! // Combines blImageInit() with blImageCreate().
|
||
|
//! blImageInitAs(&img, 128, 128, BL_FORMAT_PRGB32);
|
||
|
//!
|
||
|
//! // Destroys the data, doesn't have to be called if blImageInitAs() failed.
|
||
|
//! blImageDestroy(&img);
|
||
|
//! ```
|
||
|
//!
|
||
|
//! It's worth knowing that default initialization in Blend2D costs nothing and no resources are allocated, thus
|
||
|
//! initialization never fails and in theory default initialized objects don't have to be destroyed as they don't
|
||
|
//! hold any data that would have to be deallocated (however never do that in practice).
|
||
|
//!
|
||
|
//! There is a distinction between 'destroy()' and 'reset()' functionality. Destroy would destroy the object and
|
||
|
//! put it into a non-reusable state. Thus if the object is used by accident it should crash on null-pointer access.
|
||
|
//! On the contrary, resetting the object with 'reset()' explicitly states that the instance will be reused so
|
||
|
//! 'reset()' basically destroys the object and puts it into its default constructed state for further use. This
|
||
|
//! means that it's not needed to explicitly call 'destroy()' on instance that was reset, and it also is not needed
|
||
|
//! for a default constructed instance. However, we recommend to not count on this behavior and to always properly
|
||
|
//! initialize and destroy Blend2D objects.
|
||
|
//!
|
||
|
//! The following example should explain how init/reset can avoid destroy:
|
||
|
//!
|
||
|
//! ```
|
||
|
//! BLImageCore img;
|
||
|
//!
|
||
|
//! // Now image is default constructed/initialized. if you did just this and abandon it then no resources will
|
||
|
//! // be leaked as default construction is not allocating any resources nor increasing any reference counters.
|
||
|
//! blImageInit(&img);
|
||
|
//!
|
||
|
//! // Now image will have to dynamically allocate some memory to store pixel data. If this succeeds the image
|
||
|
//! // will have to be explicitly destroyed when it's no longer needed to release the associated data it holds.
|
||
|
//! BLResult result = blImageCreate(&img, 128, 128, BL_FORMAT_PRGB32);
|
||
|
//!
|
||
|
//! // If `blImageCreate()` failed it leaves the object in the state it was prior to the call. Most of API calls
|
||
|
//! // in Blend2D behave like this (it's transactional). This means that if the call failed the `img` would still
|
||
|
//! // be default constructed and the function can simply return without leaking any resources. In C++ API the
|
||
|
//! // compiler would emit a call to `blImageDestroy()` implicitly, but that's just how RAII works.
|
||
|
//! if (result != BL_SUCCESS)
|
||
|
//! return result;
|
||
|
//!
|
||
|
//! // Resetting image would destroy its data and make it default constructed.
|
||
|
//! blImageReset(&img);
|
||
|
//!
|
||
|
//! // The instance is valid after `reset()` - it's now a default constructed instance as created by `blImageInit()`.
|
||
|
//! printf("%p", img.impl);
|
||
|
//!
|
||
|
//! // Calling `blImageDestroy()` would make the instance invalid.
|
||
|
//! blImageDestroy(&img);
|
||
|
//!
|
||
|
//! // Calling any method except initialization such as `blImageInit()` on invalid instance is UNDEFINED BEHAVIOR!
|
||
|
//! blImageCreate(&img, 128, 128, BL_FORMAT_PRGB32); // Can crash, can corrupt memory, can succeed, never do that!
|
||
|
//! ```
|
||
|
|
||
|
//! \cond INTERNAL
|
||
|
|
||
|
//! \defgroup blend2d_internal Internal
|
||
|
//!
|
||
|
//! \brief Internal API.
|
||
|
|
||
|
//! \defgroup blend2d_codec_impl Codecs
|
||
|
//!
|
||
|
//! \brief Codecs implementation.
|
||
|
|
||
|
//! \defgroup blend2d_raster_engine_impl Raster
|
||
|
//!
|
||
|
//! \brief Raster rendering context.
|
||
|
|
||
|
//! \defgroup blend2d_pipeline_jit JIT pipeline compiler
|
||
|
//!
|
||
|
//! \brief JIT pipeline compiler.
|
||
|
|
||
|
//! \defgroup blend2d_pipeline_reference Reference pipeline implementation
|
||
|
//!
|
||
|
//! \brief Reference pipeline implementation.
|
||
|
|
||
|
//! \defgroup blend2d_opentype_impl OpenType
|
||
|
//!
|
||
|
//! \brief OpenType implementation.
|
||
|
|
||
|
//! \endcond
|
||
|
|
||
|
// Blend2D Version
|
||
|
// ===============
|
||
|
|
||
|
//! \addtogroup blend2d_api_macros
|
||
|
//! \{
|
||
|
|
||
|
//! \name Version Information
|
||
|
//! \{
|
||
|
|
||
|
//! Makes a version number representing a `MAJOR.MINOR.PATCH` combination.
|
||
|
#define BL_MAKE_VERSION(MAJOR, MINOR, PATCH) (((MAJOR) << 16) | ((MINOR) << 8) | (PATCH))
|
||
|
|
||
|
//! Blend2D library version.
|
||
|
#define BL_VERSION BL_MAKE_VERSION(0, 11, 4)
|
||
|
|
||
|
//! \}
|
||
|
//! \}
|
||
|
|
||
|
// Build Type
|
||
|
// ==========
|
||
|
|
||
|
//! \cond INTERNAL
|
||
|
|
||
|
// These definitions can be used to enable static library build. Embed is used when Blend2D's source code is embedded
|
||
|
// directly in another project, implies static build as well.
|
||
|
//
|
||
|
// #define BL_STATIC // Blend2D is a statically linked library.
|
||
|
|
||
|
// These definitions control the build mode and tracing support. The build mode should be auto-detected at compile
|
||
|
// time, but it's possible to override it in case that the auto-detection fails.
|
||
|
//
|
||
|
// Tracing is a feature that is never compiled by default and it's only used to debug Blend2D itself.
|
||
|
//
|
||
|
// #define BL_BUILD_DEBUG // Define to enable debug-mode.
|
||
|
// #define BL_BUILD_RELEASE // Define to enable release-mode.
|
||
|
|
||
|
// Detect BL_BUILD_DEBUG and BL_BUILD_RELEASE if not defined.
|
||
|
#if !defined(BL_BUILD_DEBUG) && !defined(BL_BUILD_RELEASE)
|
||
|
#ifndef NDEBUG
|
||
|
#define BL_BUILD_DEBUG
|
||
|
#else
|
||
|
#define BL_BUILD_RELEASE
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
//! \endcond
|
||
|
|
||
|
// Public Macros
|
||
|
// =============
|
||
|
|
||
|
//! \addtogroup blend2d_api_macros
|
||
|
//! \{
|
||
|
|
||
|
//! \name Target Information
|
||
|
//! \{
|
||
|
|
||
|
//! \def BL_BYTE_ORDER
|
||
|
//!
|
||
|
//! A compile-time constant (macro) that defines byte-order of the target. It can be either `1234` for little-endian
|
||
|
//! targets or `4321` for big-endian targets. Blend2D uses this macro internally, but it's also available to end
|
||
|
//! users as sometimes it could be important for deciding between pixel formats or other important details.
|
||
|
#if (defined(__ARMEB__)) || (defined(__MIPSEB__)) || \
|
||
|
(defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
|
||
|
#define BL_BYTE_ORDER 4321
|
||
|
#else
|
||
|
#define BL_BYTE_ORDER 1234
|
||
|
#endif
|
||
|
|
||
|
//! \}
|
||
|
|
||
|
//! \name Decorators
|
||
|
//! \{
|
||
|
|
||
|
//! \def BL_API
|
||
|
//!
|
||
|
//! A base API decorator that marks functions and variables exported by Blend2D.
|
||
|
#if !defined(BL_STATIC)
|
||
|
#if defined(_WIN32) && (defined(_MSC_VER) || defined(__MINGW32__))
|
||
|
#if defined(BL_BUILD_EXPORT)
|
||
|
#define BL_API __declspec(dllexport)
|
||
|
#else
|
||
|
#define BL_API __declspec(dllimport)
|
||
|
#endif
|
||
|
#elif defined(_WIN32) && defined(__GNUC__)
|
||
|
#if defined(BL_BUILD_EXPORT)
|
||
|
#define BL_API __attribute__((dllexport))
|
||
|
#else
|
||
|
#define BL_API __attribute__((dllimport))
|
||
|
#endif
|
||
|
#elif defined(__GNUC__)
|
||
|
#define BL_API __attribute__((__visibility__("default")))
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#ifndef BL_API
|
||
|
#define BL_API
|
||
|
#endif
|
||
|
|
||
|
//! \def BL_CDECL
|
||
|
//!
|
||
|
//! Calling convention used by all exported functions and function callbacks. If you pass callbacks to Blend2D it's
|
||
|
//! strongly advised to decorate the callback explicitly as some compilers provide a way of overriding a global
|
||
|
//! calling convention (like __vectorcall on Windows platform), which would break the use of such callbacks.
|
||
|
#if defined(__GNUC__) && defined(__i386__) && !defined(__x86_64__)
|
||
|
#define BL_CDECL __attribute__((__cdecl__))
|
||
|
#elif defined(_MSC_VER)
|
||
|
#define BL_CDECL __cdecl
|
||
|
#else
|
||
|
#define BL_CDECL
|
||
|
#endif
|
||
|
|
||
|
//! \def BL_INLINE
|
||
|
//!
|
||
|
//! Marks functions that should always be inlined.
|
||
|
#if defined(__GNUC__)
|
||
|
#define BL_INLINE inline __attribute__((__always_inline__))
|
||
|
#elif defined(_MSC_VER)
|
||
|
#define BL_INLINE __forceinline
|
||
|
#else
|
||
|
#define BL_INLINE inline
|
||
|
#endif
|
||
|
|
||
|
//! \def BL_INLINE_NODEBUG
|
||
|
//!
|
||
|
//! The same as `BL_INLINE` possibly combined with `__attribute__((artificial))` or `__attribute__((nodebug))` if
|
||
|
//! the compiler supports any of them.
|
||
|
//!
|
||
|
//! The purpose of this macro is to tell the compiler that the function should not need debugging, thus the debug
|
||
|
//! information can be omitted completely. Blend2D uses tris decorator to decorate C++ inline functions that either
|
||
|
//! call C API or that are trivial to improve debugging experience of some tiny abstractions.
|
||
|
#if defined(__clang__)
|
||
|
#define BL_INLINE_NODEBUG inline __attribute__((__always_inline__, __nodebug__))
|
||
|
#elif defined(__GNUC__)
|
||
|
#define BL_INLINE_NODEBUG inline __attribute__((__always_inline__, __artificial__))
|
||
|
#else
|
||
|
#define BL_INLINE_NODEBUG BL_INLINE
|
||
|
#endif
|
||
|
|
||
|
//! \def BL_NORETURN
|
||
|
//!
|
||
|
//! Function attribute used by functions that never return (that terminate the process). This attribute is used only
|
||
|
//! once by `blRuntimeAssertionFailure()` function, which is only used when assertions are enabled. This macro should
|
||
|
//! be considered internal and it's not designed for Blend2D users.
|
||
|
#if defined(__GNUC__)
|
||
|
#define BL_NORETURN __attribute__((__noreturn__))
|
||
|
#elif defined(_MSC_VER)
|
||
|
#define BL_NORETURN __declspec(noreturn)
|
||
|
#else
|
||
|
#define BL_NORETURN
|
||
|
#endif
|
||
|
|
||
|
//! \def BL_NODISCARD
|
||
|
//!
|
||
|
//! Tells the compiler to issue a warning in case that the return value of a function was not used.
|
||
|
#if defined(__cplusplus) && __cplusplus >= 201703L
|
||
|
#define BL_NODISCARD [[nodiscard]]
|
||
|
#elif defined(__clang__)
|
||
|
// GCC's behavior doesn't respect casting to void so we only support clang.
|
||
|
#define BL_NODISCARD __attribute__((__warn_unused_result__))
|
||
|
#else
|
||
|
#define BL_NODISCARD
|
||
|
#endif
|
||
|
|
||
|
//! \def BL_NOEXCEPT
|
||
|
//!
|
||
|
//! Defined to `noexcept` in C++17 mode an nothing in C mode. The reason this macro is provided is because Blend2D
|
||
|
//! C API doesn't use exceptions and is marked as such.
|
||
|
#if defined(__cplusplus) && __cplusplus >= 201703L
|
||
|
// Function typedefs are `noexcept`, however, it's not available until C++17.
|
||
|
#define BL_NOEXCEPT noexcept
|
||
|
#else
|
||
|
#define BL_NOEXCEPT
|
||
|
#endif
|
||
|
|
||
|
//! \def BL_CONSTEXPR
|
||
|
//!
|
||
|
//! Evaluates to constexpr in C++17 mode.
|
||
|
#if __cplusplus >= 201703L
|
||
|
#define BL_CONSTEXPR constexpr
|
||
|
#else
|
||
|
#define BL_CONSTEXPR
|
||
|
#endif
|
||
|
|
||
|
//! \def BL_NOEXCEPT_C
|
||
|
//!
|
||
|
//! Defined to `noexcept` in C++11 mode an nothing in C mode. This is used to mark Blend2D C API, which is `noexcept`
|
||
|
//! by design.
|
||
|
#if defined(__cplusplus)
|
||
|
#define BL_NOEXCEPT_C noexcept
|
||
|
#else
|
||
|
#define BL_NOEXCEPT_C
|
||
|
#endif
|
||
|
|
||
|
//! \def BL_PURE
|
||
|
//!
|
||
|
//! Function attribute that describes functions that have no side effects. The macro expands to
|
||
|
//! `__attribute__((__pure__))` when compiling with GCC or Clang if the attribute is supported, otherwise it expands
|
||
|
//! to nothing.
|
||
|
#if defined(__clang_major__) && __clang_major__ >= 6
|
||
|
#define BL_PURE __attribute__((__pure__))
|
||
|
#elif defined(__GNUC__) && __GNUC__ >= 6
|
||
|
#define BL_PURE __attribute__((__pure__))
|
||
|
#else
|
||
|
#define BL_PURE
|
||
|
#endif
|
||
|
|
||
|
//! \def BL_ALIGN_TYPE(TYPE, ALIGNMENT)
|
||
|
//!
|
||
|
//! Defines a type with a particular alignment, avoiding the use of alignas() as some compilers
|
||
|
//! have a buggy implementation and restrict alignas() more than a compiler specific attribute.
|
||
|
#if defined(__GNUC__)
|
||
|
#define BL_ALIGN_TYPE(TYPE, ALIGNMENT) __attribute__((__aligned__(ALIGNMENT))) TYPE
|
||
|
#elif defined(_MSC_VER)
|
||
|
#define BL_ALIGN_TYPE(TYPE, ALIGNMENT) __declspec(align(ALIGNMENT)) TYPE
|
||
|
#else
|
||
|
#define BL_ALIGN_TYPE(TYPE, ALIGNMENT) TYPE
|
||
|
#endif
|
||
|
|
||
|
//! \}
|
||
|
|
||
|
//! \name Assumptions
|
||
|
//! \{
|
||
|
|
||
|
//! \def BL_ASSUME(...)
|
||
|
//!
|
||
|
//! Macro that tells the C/C++ compiler that the expression `...` evaluates to true. This macro is only used by few
|
||
|
//! places and should be considered internal as you shouldn't need it when using Blend2D library.
|
||
|
#if defined(__clang__)
|
||
|
#define BL_ASSUME(...) __builtin_assume(__VA_ARGS__)
|
||
|
#elif defined(__GNUC__) && __GNUC__ >= 13
|
||
|
#define BL_ASSUME(...) __attribute__((__assume__(__VA_ARGS__)))
|
||
|
#elif defined(__GNUC__)
|
||
|
#define BL_ASSUME(...) do { if (!(__VA_ARGS__)) __builtin_unreachable(); } while (0)
|
||
|
#elif defined(_MSC_VER)
|
||
|
#define BL_ASSUME(...) __assume(__VA_ARGS__)
|
||
|
#else
|
||
|
#define BL_ASSUME(...) (void)0
|
||
|
#endif
|
||
|
|
||
|
//! \def BL_LIKELY(...)
|
||
|
//!
|
||
|
//! A condition is likely.
|
||
|
|
||
|
//! \def BL_UNLIKELY(...)
|
||
|
//!
|
||
|
//! A condition is unlikely.
|
||
|
|
||
|
#if defined(__GNUC__)
|
||
|
#define BL_LIKELY(...) __builtin_expect(!!(__VA_ARGS__), 1)
|
||
|
#define BL_UNLIKELY(...) __builtin_expect(!!(__VA_ARGS__), 0)
|
||
|
#else
|
||
|
#define BL_LIKELY(...) (__VA_ARGS__)
|
||
|
#define BL_UNLIKELY(...) (__VA_ARGS__)
|
||
|
#endif
|
||
|
|
||
|
//! \}
|
||
|
|
||
|
//! \name Debugging and Error Handling
|
||
|
//! \{
|
||
|
|
||
|
//! \def BL_ASSERT(EXP)
|
||
|
//!
|
||
|
//! Run-time assertion executed in debug builds.
|
||
|
#ifdef BL_BUILD_DEBUG
|
||
|
#define BL_ASSERT(EXP) \
|
||
|
do { \
|
||
|
if (BL_UNLIKELY(!(EXP))) \
|
||
|
blRuntimeAssertionFailure(__FILE__, __LINE__, #EXP); \
|
||
|
} while (0)
|
||
|
#else
|
||
|
#define BL_ASSERT(EXP) ((void)0)
|
||
|
#endif
|
||
|
|
||
|
//! Executes the code within the macro and returns if it returned any value other than `BL_SUCCESS`. This macro is
|
||
|
//! heavily used across the library for error handling.
|
||
|
#define BL_PROPAGATE(...) \
|
||
|
do { \
|
||
|
BLResult resultToPropagate = (__VA_ARGS__); \
|
||
|
if (BL_UNLIKELY(resultToPropagate)) \
|
||
|
return resultToPropagate; \
|
||
|
} while (0)
|
||
|
|
||
|
//! \}
|
||
|
|
||
|
//! \name Utilities
|
||
|
//! \{
|
||
|
|
||
|
//! Creates a 32-bit tag (uint32_t) from the given `A`, `B`, `C`, and `D` values.
|
||
|
#define BL_MAKE_TAG(A, B, C, D) ((BLTag)(((BLTag)(A) << 24) | ((BLTag)(B) << 16) | ((BLTag)(C) << 8) | ((BLTag)(D))))
|
||
|
|
||
|
//! \}
|
||
|
|
||
|
//! \cond INTERNAL
|
||
|
//! \name Internals
|
||
|
//! \{
|
||
|
|
||
|
//! \def BL_DEFINE_ENUM(NAME)
|
||
|
//!
|
||
|
//! Defines an enumeration used by Blend2D that is `uint32_t`.
|
||
|
|
||
|
//! \def BL_FORCE_ENUM_UINT32(ENUM_VALUE_PREFIX)
|
||
|
//!
|
||
|
//! Forces an enumeration to be represented as 32-bit unsigned integer.
|
||
|
//!
|
||
|
//! This must be used in public C API, because when compiled by a C compiler (not C++ compiler) the enums won't
|
||
|
//! have type information (it's a C++ feature). So this macro adds an additional enum value that would force the
|
||
|
//! C compiler to make the type unsigned and at 32-bit.
|
||
|
|
||
|
//! \}
|
||
|
//! \endcond
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
#define BL_DEFINE_CONST static constexpr
|
||
|
#define BL_DEFINE_ENUM(NAME) enum NAME : uint32_t
|
||
|
#define BL_FORCE_ENUM_UINT32(ENUM_VALUE_PREFIX)
|
||
|
#else
|
||
|
#define BL_DEFINE_CONST static const
|
||
|
#define BL_DEFINE_ENUM(NAME) typedef enum NAME NAME; enum NAME
|
||
|
#define BL_FORCE_ENUM_UINT32(ENUM_VALUE_PREFIX) ,ENUM_VALUE_PREFIX##_FORCE_UINT = 0xFFFFFFFFu
|
||
|
#endif
|
||
|
|
||
|
//! \cond INTERNAL
|
||
|
//! \name Internals
|
||
|
//! \{
|
||
|
|
||
|
//! \def BL_BEGIN_C_DECLS
|
||
|
//! Begins C declarations scope when compiling with a C++ compiler.
|
||
|
|
||
|
//! \def BL_END_C_DECLS
|
||
|
//! Ends C declarations scope when compiling with a C++ compiler.
|
||
|
|
||
|
//! \}
|
||
|
//! \endcond
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
#define BL_BEGIN_C_DECLS extern "C" {
|
||
|
#define BL_END_C_DECLS } /* {ExternC} */
|
||
|
#else
|
||
|
#define BL_BEGIN_C_DECLS
|
||
|
#define BL_END_C_DECLS
|
||
|
#endif
|
||
|
|
||
|
//! \cond INTERNAL
|
||
|
//! \name Compiler Diagnostics
|
||
|
//! \{
|
||
|
|
||
|
// Diagnostic warnings can be turned on/off by using pragmas, however, this is a compiler specific stuff we have to
|
||
|
// maintain for each compiler. Ideally we should have a clean code that would compiler without any warnings with all
|
||
|
// of them enabled by default, but since there is a lot of nitpicks we just disable some locally when needed (like
|
||
|
// unused parameter in null-impl functions, etc).
|
||
|
#if defined(__clang__)
|
||
|
#define BL_DIAGNOSTIC_PUSH(...) _Pragma("clang diagnostic push") __VA_ARGS__
|
||
|
#define BL_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
|
||
|
#define BL_DIAGNOSTIC_NO_UNUSED_FUNCTIONS _Pragma("clang diagnostic ignored \"-Wunused-function\"")
|
||
|
#define BL_DIAGNOSTIC_NO_UNUSED_PARAMETERS _Pragma("clang diagnostic ignored \"-Wunused-parameter\"")
|
||
|
#define BL_DIAGNOSTIC_NO_EXTRA_WARNINGS _Pragma("clang diagnostic ignored \"-Wextra\"")
|
||
|
#elif defined(__GNUC__)
|
||
|
#define BL_DIAGNOSTIC_PUSH(...) _Pragma("GCC diagnostic push") __VA_ARGS__
|
||
|
#define BL_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
|
||
|
#define BL_DIAGNOSTIC_NO_UNUSED_FUNCTIONS _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
|
||
|
#define BL_DIAGNOSTIC_NO_UNUSED_PARAMETERS _Pragma("GCC diagnostic ignored \"-Wunused-parameter\"")
|
||
|
#define BL_DIAGNOSTIC_NO_EXTRA_WARNINGS _Pragma("GCC diagnostic ignored \"-Wextra\"")
|
||
|
#elif defined(_MSC_VER)
|
||
|
#define BL_DIAGNOSTIC_PUSH(...) __pragma(warning(push)) __VA_ARGS__
|
||
|
#define BL_DIAGNOSTIC_POP __pragma(warning(pop))
|
||
|
#define BL_DIAGNOSTIC_NO_UNUSED_FUNCTIONS __pragma(warning(disable: 4505))
|
||
|
#define BL_DIAGNOSTIC_NO_UNUSED_PARAMETERS __pragma(warning(disable: 4100))
|
||
|
#define BL_DIAGNOSTIC_NO_EXTRA_WARNINGS
|
||
|
#endif
|
||
|
|
||
|
#if !defined(BL_DIAGNOSTIC_PUSH)
|
||
|
#define BL_DIAGNOSTIC_PUSH(...)
|
||
|
#define BL_DIAGNOSTIC_POP
|
||
|
#define BL_DIAGNOSTIC_NO_UNUSED_FUNCTIONS
|
||
|
#define BL_DIAGNOSTIC_NO_UNUSED_PARAMETERS
|
||
|
#define BL_DIAGNOSTIC_NO_EXTRA_WARNINGS
|
||
|
#endif
|
||
|
|
||
|
//! \}
|
||
|
//! \endcond
|
||
|
|
||
|
//! \}
|
||
|
|
||
|
// Forward Declarations
|
||
|
// ====================
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
#define BL_FORWARD_DECLARE_STRUCT(NAME) struct NAME
|
||
|
#else
|
||
|
#define BL_FORWARD_DECLARE_STRUCT(NAME) typedef struct NAME NAME
|
||
|
#endif
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
#define BL_FORWARD_DECLARE_UNION(NAME) union NAME
|
||
|
#else
|
||
|
#define BL_FORWARD_DECLARE_UNION(NAME) typedef union NAME NAME
|
||
|
#endif
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
#define BL_FORWARD_DECLARE_ENUM(NAME) enum NAME : uint32_t
|
||
|
#else
|
||
|
#define BL_FORWARD_DECLARE_ENUM(NAME) typedef enum NAME NAME
|
||
|
#endif
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLRange);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLRandom);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFileCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFileInfo);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLRuntimeScopeCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLRuntimeBuildInfo);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLRuntimeSystemInfo);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLRuntimeResourceInfo);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLRgba);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLRgba32);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLRgba64);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLPoint);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLPointI);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLSize);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLSizeI);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLBox);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLBoxI);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLRect);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLRectI);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLLine);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLTriangle);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLRoundRect);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLCircle);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLEllipse);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLArc);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLMatrix2D);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLApproximationOptions);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLStrokeOptionsCore);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFormatInfo);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLObjectCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLObjectImpl);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLObjectVirt);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLObjectVirtBase);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLObjectInfo);
|
||
|
BL_FORWARD_DECLARE_UNION(BLObjectDetail);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLArrayCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLArrayImpl);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLBitArrayCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLBitArrayImpl);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLBitSetCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLBitSetData);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLBitSetImpl);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLBitSetSegment);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLBitSetBuilderCore);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLStringCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLStringImpl);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLPathCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLPathImpl);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLPathView);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLImageData);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLImageInfo);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLImageCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLImageImpl);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLImageCodecCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLImageCodecImpl);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLImageCodecVirt);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLImageDecoderCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLImageDecoderImpl);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLImageDecoderVirt);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLImageEncoderCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLImageEncoderImpl);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLImageEncoderVirt);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLPixelConverterCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLPixelConverterOptions);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLGradientCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLGradientImpl);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLGradientStop);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLLinearGradientValues);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLRadialGradientValues);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLConicGradientValues);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLPatternCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLPatternImpl);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLContextCookie);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLContextCreateInfo);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLContextHints);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLContextState);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLContextCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLContextImpl);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLContextVirt);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLGlyphBufferCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLGlyphBufferImpl);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLGlyphInfo);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLGlyphMappingState);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLGlyphOutlineSinkInfo);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLGlyphPlacement);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLGlyphRun);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontUnicodeCoverage);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontFaceInfo);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontQueryProperties);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontFeatureItem);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontFeatureSettingsCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontFeatureSettingsImpl);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontFeatureSettingsView);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontDesignMetrics);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontMatrix);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontMetrics);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontPanose);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontTable);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontVariationItem);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontVariationSettingsCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontVariationSettingsImpl);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontVariationSettingsView);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLTextMetrics);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontImpl);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontDataCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontDataImpl);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontDataVirt);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontFaceCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontFaceImpl);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontFaceVirt);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontManagerCore);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontManagerImpl);
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLFontManagerVirt);
|
||
|
|
||
|
BL_FORWARD_DECLARE_STRUCT(BLVarCore);
|
||
|
|
||
|
#undef BL_FORWARD_DECLARE_ENUM
|
||
|
#undef BL_FORWARD_DECLARE_UNION
|
||
|
#undef BL_FORWARD_DECLARE_STRUCT
|
||
|
|
||
|
// C++ API.
|
||
|
#ifdef __cplusplus
|
||
|
class BLFile;
|
||
|
class BLRuntimeScope;
|
||
|
template<typename T> class BLArray;
|
||
|
class BLBitArray;
|
||
|
class BLBitSet;
|
||
|
template<uint32_t> class BLBitSetBuilderT;
|
||
|
class BLString;
|
||
|
class BLPath;
|
||
|
class BLStrokeOptions;
|
||
|
class BLImage;
|
||
|
class BLImageCodec;
|
||
|
class BLImageDecoder;
|
||
|
class BLImageEncoder;
|
||
|
class BLPattern;
|
||
|
class BLGradient;
|
||
|
class BLContext;
|
||
|
class BLPixelConverter;
|
||
|
class BLGlyphBuffer;
|
||
|
class BLGlyphRunIterator;
|
||
|
class BLFont;
|
||
|
class BLFontData;
|
||
|
class BLFontFace;
|
||
|
class BLFontFeatureSettings;
|
||
|
class BLFontManager;
|
||
|
class BLFontVariationSettings;
|
||
|
class BLVar;
|
||
|
#endif
|
||
|
|
||
|
// Public Types
|
||
|
// ============
|
||
|
|
||
|
//! \ingroup blend2d_api_globals
|
||
|
//!
|
||
|
//! Result code used by most Blend2D functions (32-bit unsigned integer).
|
||
|
//!
|
||
|
//! The `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 = doSomething();
|
||
|
//! if (result != BL_SUCCESS) {
|
||
|
//! // `doSomething()` failed...
|
||
|
//! }
|
||
|
//! ```
|
||
|
typedef uint32_t BLResult;
|
||
|
|
||
|
//! \ingroup blend2d_api_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 `BLTag` in public and internal APIs to distinguish between a regular `uint32_t` and tag.
|
||
|
typedef uint32_t BLTag;
|
||
|
|
||
|
//! \ingroup blend2d_api_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.
|
||
|
typedef uint64_t BLUniqueId;
|
||
|
|
||
|
//! \ingroup blend2d_api_globals
|
||
|
//!
|
||
|
//! BLUnknown is `void` - it's used in places that accept pointer to `BLVarCore` or any `BLObjectCore` compatible
|
||
|
//! object.
|
||
|
typedef void BLUnknown;
|
||
|
|
||
|
//! \ingroup blend2d_api_globals
|
||
|
//!
|
||
|
//! A sink that can be used to debug various parts of Blend2D.
|
||
|
typedef void (BL_CDECL* BLDebugMessageSinkFunc)(const char* message, size_t size, void* userData) BL_NOEXCEPT;
|
||
|
|
||
|
// Public Constants
|
||
|
// ================
|
||
|
|
||
|
//! \ingroup blend2d_api_globals
|
||
|
//!
|
||
|
//! Blend2D result code.
|
||
|
BL_DEFINE_ENUM(BLResultCode) {
|
||
|
//! Successful result code.
|
||
|
BL_SUCCESS = 0,
|
||
|
|
||
|
BL_ERROR_START_INDEX = 0x00010000u,
|
||
|
|
||
|
BL_ERROR_OUT_OF_MEMORY = 0x00010000u, //!< Out of memory [ENOMEM].
|
||
|
BL_ERROR_INVALID_VALUE, //!< Invalid value/argument [EINVAL].
|
||
|
BL_ERROR_INVALID_STATE, //!< Invalid state [EFAULT].
|
||
|
BL_ERROR_INVALID_HANDLE, //!< Invalid handle or file. [EBADF].
|
||
|
BL_ERROR_INVALID_CONVERSION, //!< Invalid conversion.
|
||
|
BL_ERROR_OVERFLOW, //!< Overflow or value too large [EOVERFLOW].
|
||
|
BL_ERROR_NOT_INITIALIZED, //!< Object not initialized.
|
||
|
BL_ERROR_NOT_IMPLEMENTED, //!< Not implemented [ENOSYS].
|
||
|
BL_ERROR_NOT_PERMITTED, //!< Operation not permitted [EPERM].
|
||
|
|
||
|
BL_ERROR_IO, //!< IO error [EIO].
|
||
|
BL_ERROR_BUSY, //!< Device or resource busy [EBUSY].
|
||
|
BL_ERROR_INTERRUPTED, //!< Operation interrupted [EINTR].
|
||
|
BL_ERROR_TRY_AGAIN, //!< Try again [EAGAIN].
|
||
|
BL_ERROR_TIMED_OUT, //!< Timed out [ETIMEDOUT].
|
||
|
BL_ERROR_BROKEN_PIPE, //!< Broken pipe [EPIPE].
|
||
|
BL_ERROR_INVALID_SEEK, //!< File is not seekable [ESPIPE].
|
||
|
BL_ERROR_SYMLINK_LOOP, //!< Too many levels of symlinks [ELOOP].
|
||
|
BL_ERROR_FILE_TOO_LARGE, //!< File is too large [EFBIG].
|
||
|
BL_ERROR_ALREADY_EXISTS, //!< File/directory already exists [EEXIST].
|
||
|
BL_ERROR_ACCESS_DENIED, //!< Access denied [EACCES].
|
||
|
BL_ERROR_MEDIA_CHANGED, //!< Media changed [Windows::ERROR_MEDIA_CHANGED].
|
||
|
BL_ERROR_READ_ONLY_FS, //!< The file/FS is read-only [EROFS].
|
||
|
BL_ERROR_NO_DEVICE, //!< Device doesn't exist [ENXIO].
|
||
|
BL_ERROR_NO_ENTRY, //!< Not found, no entry (fs) [ENOENT].
|
||
|
BL_ERROR_NO_MEDIA, //!< No media in drive/device [ENOMEDIUM].
|
||
|
BL_ERROR_NO_MORE_DATA, //!< No more data / end of file [ENODATA].
|
||
|
BL_ERROR_NO_MORE_FILES, //!< No more files [ENMFILE].
|
||
|
BL_ERROR_NO_SPACE_LEFT, //!< No space left on device [ENOSPC].
|
||
|
BL_ERROR_NOT_EMPTY, //!< Directory is not empty [ENOTEMPTY].
|
||
|
BL_ERROR_NOT_FILE, //!< Not a file [EISDIR].
|
||
|
BL_ERROR_NOT_DIRECTORY, //!< Not a directory [ENOTDIR].
|
||
|
BL_ERROR_NOT_SAME_DEVICE, //!< Not same device [EXDEV].
|
||
|
BL_ERROR_NOT_BLOCK_DEVICE, //!< Not a block device [ENOTBLK].
|
||
|
|
||
|
BL_ERROR_INVALID_FILE_NAME, //!< File/path name is invalid [n/a].
|
||
|
BL_ERROR_FILE_NAME_TOO_LONG, //!< File/path name is too long [ENAMETOOLONG].
|
||
|
|
||
|
BL_ERROR_TOO_MANY_OPEN_FILES, //!< Too many open files [EMFILE].
|
||
|
BL_ERROR_TOO_MANY_OPEN_FILES_BY_OS, //!< Too many open files by OS [ENFILE].
|
||
|
BL_ERROR_TOO_MANY_LINKS, //!< Too many symbolic links on FS [EMLINK].
|
||
|
BL_ERROR_TOO_MANY_THREADS, //!< Too many threads [EAGAIN].
|
||
|
BL_ERROR_THREAD_POOL_EXHAUSTED, //!< Thread pool is exhausted and couldn't acquire the requested thread count.
|
||
|
|
||
|
BL_ERROR_FILE_EMPTY, //!< File is empty (not specific to any OS error).
|
||
|
BL_ERROR_OPEN_FAILED, //!< File open failed [Windows::ERROR_OPEN_FAILED].
|
||
|
BL_ERROR_NOT_ROOT_DEVICE, //!< Not a root device/directory [Windows::ERROR_DIR_NOT_ROOT].
|
||
|
|
||
|
BL_ERROR_UNKNOWN_SYSTEM_ERROR, //!< Unknown system error that failed to translate to Blend2D result code.
|
||
|
|
||
|
BL_ERROR_INVALID_ALIGNMENT, //!< Invalid data alignment.
|
||
|
BL_ERROR_INVALID_SIGNATURE, //!< Invalid data signature or header.
|
||
|
BL_ERROR_INVALID_DATA, //!< Invalid or corrupted data.
|
||
|
BL_ERROR_INVALID_STRING, //!< Invalid string (invalid data of either UTF8, UTF16, or UTF32).
|
||
|
BL_ERROR_INVALID_KEY, //!< Invalid key or property.
|
||
|
BL_ERROR_DATA_TRUNCATED, //!< Truncated data (more data required than memory/stream provides).
|
||
|
BL_ERROR_DATA_TOO_LARGE, //!< Input data too large to be processed.
|
||
|
BL_ERROR_DECOMPRESSION_FAILED, //!< Decompression failed due to invalid data (RLE, Huffman, etc).
|
||
|
|
||
|
BL_ERROR_INVALID_GEOMETRY, //!< Invalid geometry (invalid path data or shape).
|
||
|
BL_ERROR_NO_MATCHING_VERTEX, //!< Returned when there is no matching vertex in path data.
|
||
|
|
||
|
BL_ERROR_INVALID_CREATE_FLAGS, //!< Invalid create flags (BLContext).
|
||
|
BL_ERROR_NO_MATCHING_COOKIE, //!< No matching cookie (BLContext).
|
||
|
BL_ERROR_NO_STATES_TO_RESTORE, //!< No states to restore (BLContext).
|
||
|
BL_ERROR_TOO_MANY_SAVED_STATES, //!< Cannot save state as the number of saved states reached the limit (BLContext).
|
||
|
|
||
|
BL_ERROR_IMAGE_TOO_LARGE, //!< The size of the image is too large.
|
||
|
BL_ERROR_IMAGE_NO_MATCHING_CODEC, //!< Image codec for a required format doesn't exist.
|
||
|
BL_ERROR_IMAGE_UNKNOWN_FILE_FORMAT, //!< Unknown or invalid file format that cannot be read.
|
||
|
BL_ERROR_IMAGE_DECODER_NOT_PROVIDED, //!< Image codec doesn't support reading the file format.
|
||
|
BL_ERROR_IMAGE_ENCODER_NOT_PROVIDED, //!< Image codec doesn't support writing the file format.
|
||
|
|
||
|
BL_ERROR_PNG_MULTIPLE_IHDR, //!< Multiple IHDR chunks are not allowed (PNG).
|
||
|
BL_ERROR_PNG_INVALID_IDAT, //!< Invalid IDAT chunk (PNG).
|
||
|
BL_ERROR_PNG_INVALID_IEND, //!< Invalid IEND chunk (PNG).
|
||
|
BL_ERROR_PNG_INVALID_PLTE, //!< Invalid PLTE chunk (PNG).
|
||
|
BL_ERROR_PNG_INVALID_TRNS, //!< Invalid tRNS chunk (PNG).
|
||
|
BL_ERROR_PNG_INVALID_FILTER, //!< Invalid filter type (PNG).
|
||
|
|
||
|
BL_ERROR_JPEG_UNSUPPORTED_FEATURE, //!< Unsupported feature (JPEG).
|
||
|
BL_ERROR_JPEG_INVALID_SOS, //!< Invalid SOS marker or header (JPEG).
|
||
|
BL_ERROR_JPEG_INVALID_SOF, //!< Invalid SOF marker (JPEG).
|
||
|
BL_ERROR_JPEG_MULTIPLE_SOF, //!< Multiple SOF markers (JPEG).
|
||
|
BL_ERROR_JPEG_UNSUPPORTED_SOF, //!< Unsupported SOF marker (JPEG).
|
||
|
|
||
|
BL_ERROR_FONT_NOT_INITIALIZED, //!< Font doesn't have any data as it's not initialized.
|
||
|
BL_ERROR_FONT_NO_MATCH, //!< Font or font face was not matched (BLFontManager).
|
||
|
BL_ERROR_FONT_NO_CHARACTER_MAPPING, //!< Font has no character to glyph mapping data.
|
||
|
BL_ERROR_FONT_MISSING_IMPORTANT_TABLE, //!< Font has missing an important table.
|
||
|
BL_ERROR_FONT_FEATURE_NOT_AVAILABLE, //!< Font feature is not available.
|
||
|
BL_ERROR_FONT_CFF_INVALID_DATA, //!< Font has an invalid CFF data.
|
||
|
BL_ERROR_FONT_PROGRAM_TERMINATED, //!< Font program terminated because the execution reached the limit.
|
||
|
BL_ERROR_GLYPH_SUBSTITUTION_TOO_LARGE, //!< Glyph substitution requires too much space and was terminated.
|
||
|
|
||
|
BL_ERROR_INVALID_GLYPH //!< Invalid glyph identifier.
|
||
|
|
||
|
BL_FORCE_ENUM_UINT32(BL_ERROR)
|
||
|
};
|
||
|
|
||
|
//! \ingroup blend2d_api_globals
|
||
|
//!
|
||
|
//! Byte order.
|
||
|
BL_DEFINE_ENUM(BLByteOrder) {
|
||
|
//! Little endian byte-order.
|
||
|
BL_BYTE_ORDER_LE = 0,
|
||
|
//! Big endian byte-order.
|
||
|
BL_BYTE_ORDER_BE = 1,
|
||
|
|
||
|
//! Native (host) byte-order.
|
||
|
BL_BYTE_ORDER_NATIVE = BL_BYTE_ORDER == 1234 ? BL_BYTE_ORDER_LE : BL_BYTE_ORDER_BE,
|
||
|
//! Swapped byte-order (BE if host is LE and vice versa).
|
||
|
BL_BYTE_ORDER_SWAPPED = BL_BYTE_ORDER == 1234 ? BL_BYTE_ORDER_BE : BL_BYTE_ORDER_LE
|
||
|
|
||
|
BL_FORCE_ENUM_UINT32(BL_BYTE_ORDER)
|
||
|
};
|
||
|
|
||
|
//! \ingroup blend2d_api_globals
|
||
|
//!
|
||
|
//! Data access flags.
|
||
|
BL_DEFINE_ENUM(BLDataAccessFlags) {
|
||
|
//! No data access flags.
|
||
|
BL_DATA_ACCESS_NO_FLAGS = 0x00u,
|
||
|
//! Read access.
|
||
|
BL_DATA_ACCESS_READ = 0x01u,
|
||
|
//! Write access.
|
||
|
BL_DATA_ACCESS_WRITE = 0x02u,
|
||
|
//! Read and write access.
|
||
|
BL_DATA_ACCESS_RW = 0x03u
|
||
|
|
||
|
BL_FORCE_ENUM_UINT32(BL_DATA_ACCESS)
|
||
|
};
|
||
|
|
||
|
//! \ingroup blend2d_api_globals
|
||
|
//!
|
||
|
//! Data source type.
|
||
|
BL_DEFINE_ENUM(BLDataSourceType) {
|
||
|
//! No data source.
|
||
|
BL_DATA_SOURCE_TYPE_NONE = 0,
|
||
|
//! Memory data source.
|
||
|
BL_DATA_SOURCE_TYPE_MEMORY = 1,
|
||
|
//! File data source.
|
||
|
BL_DATA_SOURCE_TYPE_FILE = 2,
|
||
|
//! Custom data source.
|
||
|
BL_DATA_SOURCE_TYPE_CUSTOM = 3,
|
||
|
|
||
|
//! Maximum value `BLDataSourceType`.
|
||
|
BL_DATA_SOURCE_TYPE_MAX_VALUE = 3
|
||
|
|
||
|
BL_FORCE_ENUM_UINT32(BL_DATA_SOURCE_TYPE)
|
||
|
};
|
||
|
|
||
|
//! \ingroup blend2d_api_globals
|
||
|
//!
|
||
|
//! Modification operation applied to Blend2D containers.
|
||
|
BL_DEFINE_ENUM(BLModifyOp) {
|
||
|
//! Assign operation, which reserves space only to fit the requested input.
|
||
|
BL_MODIFY_OP_ASSIGN_FIT = 0,
|
||
|
//! Assign operation, which takes into consideration successive appends.
|
||
|
BL_MODIFY_OP_ASSIGN_GROW = 1,
|
||
|
//! Append operation, which reserves space only to fit the current and appended content.
|
||
|
BL_MODIFY_OP_APPEND_FIT = 2,
|
||
|
//! Append operation, which takes into consideration successive appends.
|
||
|
BL_MODIFY_OP_APPEND_GROW = 3,
|
||
|
|
||
|
//! Maximum value of `BLModifyOp`.
|
||
|
BL_MODIFY_OP_MAX_VALUE = 3
|
||
|
|
||
|
BL_FORCE_ENUM_UINT32(BL_MODIFY_OP)
|
||
|
};
|
||
|
|
||
|
//! \ingroup blend2d_api_globals
|
||
|
//!
|
||
|
//! Boolean operator.
|
||
|
BL_DEFINE_ENUM(BLBooleanOp) {
|
||
|
//! Result = B.
|
||
|
BL_BOOLEAN_OP_COPY = 0,
|
||
|
//! Result = A & B.
|
||
|
BL_BOOLEAN_OP_AND = 1,
|
||
|
//! Result = A | B.
|
||
|
BL_BOOLEAN_OP_OR = 2,
|
||
|
//! Result = A ^ B.
|
||
|
BL_BOOLEAN_OP_XOR = 3,
|
||
|
//! Result = A & ~B.
|
||
|
BL_BOOLEAN_OP_AND_NOT = 4,
|
||
|
//! Result = ~A & B.
|
||
|
BL_BOOLEAN_OP_NOT_AND = 5,
|
||
|
|
||
|
//! Maximum value of `BLBooleanOp`.
|
||
|
BL_BOOLEAN_OP_MAX_VALUE = 5
|
||
|
|
||
|
BL_FORCE_ENUM_UINT32(BL_BOOLEAN_OP)
|
||
|
};
|
||
|
|
||
|
//! \ingroup blend2d_api_styling
|
||
|
//!
|
||
|
//! Extend mode.
|
||
|
BL_DEFINE_ENUM(BLExtendMode) {
|
||
|
//! Pad extend [default].
|
||
|
BL_EXTEND_MODE_PAD = 0,
|
||
|
//! Repeat extend.
|
||
|
BL_EXTEND_MODE_REPEAT = 1,
|
||
|
//! Reflect extend.
|
||
|
BL_EXTEND_MODE_REFLECT = 2,
|
||
|
|
||
|
//! Alias to `BL_EXTEND_MODE_PAD`.
|
||
|
BL_EXTEND_MODE_PAD_X_PAD_Y = 0,
|
||
|
//! Pad X and repeat Y.
|
||
|
BL_EXTEND_MODE_PAD_X_REPEAT_Y = 3,
|
||
|
//! Pad X and reflect Y.
|
||
|
BL_EXTEND_MODE_PAD_X_REFLECT_Y = 4,
|
||
|
|
||
|
//! Alias to `BL_EXTEND_MODE_REPEAT`.
|
||
|
BL_EXTEND_MODE_REPEAT_X_REPEAT_Y = 1,
|
||
|
//! Repeat X and pad Y.
|
||
|
BL_EXTEND_MODE_REPEAT_X_PAD_Y = 5,
|
||
|
//! Repeat X and reflect Y.
|
||
|
BL_EXTEND_MODE_REPEAT_X_REFLECT_Y = 6,
|
||
|
|
||
|
//! Alias to `BL_EXTEND_MODE_REFLECT`.
|
||
|
BL_EXTEND_MODE_REFLECT_X_REFLECT_Y = 2,
|
||
|
//! Reflect X and pad Y.
|
||
|
BL_EXTEND_MODE_REFLECT_X_PAD_Y = 7,
|
||
|
//! Reflect X and repeat Y.
|
||
|
BL_EXTEND_MODE_REFLECT_X_REPEAT_Y = 8,
|
||
|
|
||
|
//! Count of simple extend modes (that use the same value for X and Y).
|
||
|
BL_EXTEND_MODE_SIMPLE_MAX_VALUE = 2,
|
||
|
//! Count of complex extend modes (that can use independent values for X and Y).
|
||
|
BL_EXTEND_MODE_COMPLEX_MAX_VALUE = 8,
|
||
|
|
||
|
//! Maximum value of `BLExtendMode`.
|
||
|
BL_EXTEND_MODE_MAX_VALUE = 8
|
||
|
|
||
|
BL_FORCE_ENUM_UINT32(BL_EXTEND_MODE)
|
||
|
};
|
||
|
|
||
|
//! \ingroup blend2d_api_text
|
||
|
//!
|
||
|
//! Text encoding.
|
||
|
BL_DEFINE_ENUM(BLTextEncoding) {
|
||
|
//! UTF-8 encoding.
|
||
|
BL_TEXT_ENCODING_UTF8 = 0,
|
||
|
//! UTF-16 encoding (native endian).
|
||
|
BL_TEXT_ENCODING_UTF16 = 1,
|
||
|
//! UTF-32 encoding (native endian).
|
||
|
BL_TEXT_ENCODING_UTF32 = 2,
|
||
|
//! LATIN1 encoding (one byte per character).
|
||
|
BL_TEXT_ENCODING_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)`.
|
||
|
BL_TEXT_ENCODING_WCHAR
|
||
|
= sizeof(wchar_t) == 4 ? BL_TEXT_ENCODING_UTF32 :
|
||
|
sizeof(wchar_t) == 2 ? BL_TEXT_ENCODING_UTF16 : BL_TEXT_ENCODING_UTF8,
|
||
|
|
||
|
//! Maximum value of `BLTextEncoding`.
|
||
|
BL_TEXT_ENCODING_MAX_VALUE = 3
|
||
|
|
||
|
BL_FORCE_ENUM_UINT32(BL_TEXT_ENCODING)
|
||
|
};
|
||
|
|
||
|
// Internal API
|
||
|
// ============
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
//! \cond INTERNAL
|
||
|
|
||
|
//! \ingroup blend2d_internal
|
||
|
//!
|
||
|
//! Internal namespace that should never be used by Blend2D users.
|
||
|
//!
|
||
|
//! This namespace provides functionality that is internally used by the public C++ API in public headers.
|
||
|
//! There should never be functionality that is not used by public headers, that should always be hidden.
|
||
|
namespace BLInternal {
|
||
|
|
||
|
template<typename T>
|
||
|
BL_INLINE_NODEBUG typename std::remove_reference<T>::type&& move(T&& v) noexcept { return static_cast<typename std::remove_reference<T>::type&&>(v); }
|
||
|
|
||
|
template<typename T>
|
||
|
BL_INLINE_NODEBUG T&& forward(typename std::remove_reference<T>::type& v) noexcept { return static_cast<T&&>(v); }
|
||
|
|
||
|
template<typename T>
|
||
|
BL_INLINE_NODEBUG T&& forward(typename std::remove_reference<T>::type&& v) noexcept { return static_cast<T&&>(v); }
|
||
|
|
||
|
template<typename T>
|
||
|
BL_INLINE void swap(T& t1, T& t2) noexcept {
|
||
|
T temp(move(t1));
|
||
|
t1 = move(t2);
|
||
|
t2 = move(temp);
|
||
|
}
|
||
|
|
||
|
//! StdIntT provides a signed integer type as defined by <stdint.h> by size.
|
||
|
template<size_t kSize, bool kUnsigned = false> struct StdIntT;
|
||
|
|
||
|
template<> struct StdIntT<1, false> { typedef int8_t Type; };
|
||
|
template<> struct StdIntT<2, false> { typedef int16_t Type; };
|
||
|
template<> struct StdIntT<4, false> { typedef int32_t Type; };
|
||
|
template<> struct StdIntT<8, false> { typedef int64_t Type; };
|
||
|
template<> struct StdIntT<1, true> { typedef uint8_t Type; };
|
||
|
template<> struct StdIntT<2, true> { typedef uint16_t Type; };
|
||
|
template<> struct StdIntT<4, true> { typedef uint32_t Type; };
|
||
|
template<> struct StdIntT<8, true> { typedef uint64_t Type; };
|
||
|
|
||
|
template<size_t kSize, bool kUnsigned = false>
|
||
|
using IntBySize = typename StdIntT<kSize, kUnsigned>::Type;
|
||
|
|
||
|
template<size_t kSize>
|
||
|
using UIntBySize = typename StdIntT<kSize, true>::Type;
|
||
|
|
||
|
template<typename T, bool kUnsigned = false>
|
||
|
using IntByType = typename StdIntT<sizeof(T), kUnsigned>::Type;
|
||
|
|
||
|
template<typename T>
|
||
|
using UIntByType = typename StdIntT<sizeof(T), 1>::Type;
|
||
|
|
||
|
template<uint64_t kInput>
|
||
|
struct ConstCTZ {
|
||
|
enum : uint32_t {
|
||
|
kValue = (kInput & (uint64_t(1) << 0)) ? 0 : (kInput & (uint64_t(1) << 1)) ? 1 :
|
||
|
(kInput & (uint64_t(1) << 2)) ? 2 : (kInput & (uint64_t(1) << 3)) ? 3 :
|
||
|
(kInput & (uint64_t(1) << 4)) ? 4 : (kInput & (uint64_t(1) << 5)) ? 5 :
|
||
|
(kInput & (uint64_t(1) << 6)) ? 6 : (kInput & (uint64_t(1) << 7)) ? 7 :
|
||
|
(kInput & (uint64_t(1) << 8)) ? 8 : (kInput & (uint64_t(1) << 9)) ? 9 :
|
||
|
(kInput & (uint64_t(1) << 10)) ? 10 : (kInput & (uint64_t(1) << 11)) ? 11 :
|
||
|
(kInput & (uint64_t(1) << 12)) ? 12 : (kInput & (uint64_t(1) << 13)) ? 13 :
|
||
|
(kInput & (uint64_t(1) << 14)) ? 14 : (kInput & (uint64_t(1) << 15)) ? 15 :
|
||
|
(kInput & (uint64_t(1) << 16)) ? 16 : (kInput & (uint64_t(1) << 17)) ? 17 :
|
||
|
(kInput & (uint64_t(1) << 18)) ? 18 : (kInput & (uint64_t(1) << 19)) ? 19 :
|
||
|
(kInput & (uint64_t(1) << 20)) ? 20 : (kInput & (uint64_t(1) << 21)) ? 21 :
|
||
|
(kInput & (uint64_t(1) << 22)) ? 22 : (kInput & (uint64_t(1) << 23)) ? 23 :
|
||
|
(kInput & (uint64_t(1) << 24)) ? 24 : (kInput & (uint64_t(1) << 25)) ? 25 :
|
||
|
(kInput & (uint64_t(1) << 26)) ? 26 : (kInput & (uint64_t(1) << 27)) ? 27 :
|
||
|
(kInput & (uint64_t(1) << 28)) ? 28 : (kInput & (uint64_t(1) << 29)) ? 29 :
|
||
|
(kInput & (uint64_t(1) << 30)) ? 30 : (kInput & (uint64_t(1) << 31)) ? 31 :
|
||
|
(kInput & (uint64_t(1) << 32)) ? 32 : (kInput & (uint64_t(1) << 33)) ? 33 :
|
||
|
(kInput & (uint64_t(1) << 34)) ? 34 : (kInput & (uint64_t(1) << 35)) ? 35 :
|
||
|
(kInput & (uint64_t(1) << 36)) ? 36 : (kInput & (uint64_t(1) << 37)) ? 37 :
|
||
|
(kInput & (uint64_t(1) << 38)) ? 38 : (kInput & (uint64_t(1) << 39)) ? 39 :
|
||
|
(kInput & (uint64_t(1) << 40)) ? 40 : (kInput & (uint64_t(1) << 41)) ? 41 :
|
||
|
(kInput & (uint64_t(1) << 42)) ? 42 : (kInput & (uint64_t(1) << 43)) ? 43 :
|
||
|
(kInput & (uint64_t(1) << 44)) ? 44 : (kInput & (uint64_t(1) << 45)) ? 45 :
|
||
|
(kInput & (uint64_t(1) << 46)) ? 46 : (kInput & (uint64_t(1) << 47)) ? 47 :
|
||
|
(kInput & (uint64_t(1) << 48)) ? 48 : (kInput & (uint64_t(1) << 49)) ? 49 :
|
||
|
(kInput & (uint64_t(1) << 50)) ? 50 : (kInput & (uint64_t(1) << 51)) ? 51 :
|
||
|
(kInput & (uint64_t(1) << 52)) ? 52 : (kInput & (uint64_t(1) << 53)) ? 53 :
|
||
|
(kInput & (uint64_t(1) << 54)) ? 54 : (kInput & (uint64_t(1) << 55)) ? 55 :
|
||
|
(kInput & (uint64_t(1) << 56)) ? 56 : (kInput & (uint64_t(1) << 57)) ? 57 :
|
||
|
(kInput & (uint64_t(1) << 58)) ? 58 : (kInput & (uint64_t(1) << 59)) ? 59 :
|
||
|
(kInput & (uint64_t(1) << 60)) ? 60 : (kInput & (uint64_t(1) << 61)) ? 61 :
|
||
|
(kInput & (uint64_t(1) << 62)) ? 62 : (kInput & (uint64_t(1) << 63)) ? 63 : 64
|
||
|
};
|
||
|
};
|
||
|
|
||
|
//! Type category.
|
||
|
//!
|
||
|
//! Provides type categorization for compile-time type reflection that can be used by templates.
|
||
|
enum TypeCategory : uint32_t {
|
||
|
//! Type is unknown.
|
||
|
kTypeCategoryUnknown = 0,
|
||
|
//! Type is a boolean (`bool`).
|
||
|
kTypeCategoryBool = 1,
|
||
|
//! Type is integral.
|
||
|
kTypeCategoryInt = 2,
|
||
|
//! Type is a floating point.
|
||
|
kTypeCategoryFloat = 3,
|
||
|
//! Type is a pointer.
|
||
|
kTypeCategoryPtr = 4,
|
||
|
//! Type is a structure.
|
||
|
kTypeCategoryStruct = 5,
|
||
|
//! Type is BLObject compatible.
|
||
|
kTypeCategoryObject = 6
|
||
|
};
|
||
|
|
||
|
//! Type flags.
|
||
|
//!
|
||
|
//! Provides details about a categorized type.
|
||
|
enum TypeFlags : uint32_t {
|
||
|
//! Type has no flags.
|
||
|
kTypeNoFlags = 0x0000u,
|
||
|
//! Type is primitive (either bool, integer, or floating point).
|
||
|
kTypeFlagPrimitive = 0x0001u,
|
||
|
//! Type is `BLArrayCore` or `BLArray<T>`.
|
||
|
kTypeFlagArray = 0x0002u,
|
||
|
//! Type is `BLVarCore` or `BLVar`
|
||
|
kTypeFlagVar = 0x0004u,
|
||
|
//! Type is `BLxxxCore` - C API type.
|
||
|
kTypeFlagCore = 0x0008u,
|
||
|
|
||
|
//! Type is `BLRgba`.
|
||
|
kTypeFlagRgba = 0x0010u,
|
||
|
//! Type is `BLRgba32`.
|
||
|
kTypeFlagRgba32 = 0x0020u,
|
||
|
//! Type is `BLRgba64`.
|
||
|
kTypeFlagRgba64 = 0x0040u,
|
||
|
//! Type is `BLGradient[Core]` or `BLPattern[Core]`.
|
||
|
kTypeFlagStyle = 0x0080u
|
||
|
};
|
||
|
|
||
|
template<typename T>
|
||
|
struct TypeTraits {
|
||
|
enum : uint32_t {
|
||
|
kCategory = std::is_pointer<T>::value ? kTypeCategoryPtr :
|
||
|
std::is_integral<T>::value ? kTypeCategoryInt :
|
||
|
std::is_floating_point<T>::value ? kTypeCategoryFloat : kTypeCategoryStruct,
|
||
|
kFlags = std::is_pointer<T>::value ? kTypeFlagPrimitive :
|
||
|
std::is_integral<T>::value ? kTypeFlagPrimitive :
|
||
|
std::is_floating_point<T>::value ? kTypeFlagPrimitive : kTypeNoFlags
|
||
|
};
|
||
|
};
|
||
|
|
||
|
template<>
|
||
|
struct TypeTraits<bool> {
|
||
|
enum : uint32_t {
|
||
|
kCategory = kTypeCategoryBool,
|
||
|
kFlags = kTypeFlagPrimitive
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// BLArrayCore and BLArray<T> specialization.
|
||
|
template<>
|
||
|
struct TypeTraits<BLArrayCore> {
|
||
|
enum : uint32_t {
|
||
|
kCategory = kTypeCategoryObject,
|
||
|
kFlags = kTypeFlagArray | kTypeFlagCore
|
||
|
};
|
||
|
};
|
||
|
|
||
|
template<typename T>
|
||
|
struct TypeTraits<BLArray<T>> {
|
||
|
enum : uint32_t {
|
||
|
kCategory = kTypeCategoryObject,
|
||
|
kFlags = kTypeFlagArray
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// Other types compatible with BLObjectCore.
|
||
|
#define BL_DEFINE_OBJECT_TRAITS(T, Flags) \
|
||
|
template<> \
|
||
|
struct TypeTraits<T##Core> { \
|
||
|
enum : uint32_t { \
|
||
|
kCategory = kTypeCategoryObject, \
|
||
|
kFlags = Flags | kTypeFlagCore \
|
||
|
}; \
|
||
|
}; \
|
||
|
\
|
||
|
template<> \
|
||
|
struct TypeTraits<T> { \
|
||
|
enum : uint32_t { \
|
||
|
kCategory = kTypeCategoryObject, \
|
||
|
kFlags = Flags \
|
||
|
}; \
|
||
|
};
|
||
|
|
||
|
BL_DEFINE_OBJECT_TRAITS(BLBitArray , kTypeNoFlags)
|
||
|
BL_DEFINE_OBJECT_TRAITS(BLBitSet , kTypeNoFlags)
|
||
|
BL_DEFINE_OBJECT_TRAITS(BLContext , kTypeNoFlags)
|
||
|
BL_DEFINE_OBJECT_TRAITS(BLFont , kTypeNoFlags)
|
||
|
BL_DEFINE_OBJECT_TRAITS(BLFontData , kTypeNoFlags)
|
||
|
BL_DEFINE_OBJECT_TRAITS(BLFontFace , kTypeNoFlags)
|
||
|
BL_DEFINE_OBJECT_TRAITS(BLFontFeatureSettings , kTypeNoFlags)
|
||
|
BL_DEFINE_OBJECT_TRAITS(BLFontManager , kTypeNoFlags)
|
||
|
BL_DEFINE_OBJECT_TRAITS(BLFontVariationSettings, kTypeNoFlags)
|
||
|
BL_DEFINE_OBJECT_TRAITS(BLGradient , kTypeFlagStyle)
|
||
|
BL_DEFINE_OBJECT_TRAITS(BLImage , kTypeNoFlags)
|
||
|
BL_DEFINE_OBJECT_TRAITS(BLImageCodec , kTypeNoFlags)
|
||
|
BL_DEFINE_OBJECT_TRAITS(BLImageDecoder , kTypeNoFlags)
|
||
|
BL_DEFINE_OBJECT_TRAITS(BLImageEncoder , kTypeNoFlags)
|
||
|
BL_DEFINE_OBJECT_TRAITS(BLPath , kTypeNoFlags)
|
||
|
BL_DEFINE_OBJECT_TRAITS(BLPattern , kTypeFlagStyle)
|
||
|
BL_DEFINE_OBJECT_TRAITS(BLString , kTypeNoFlags)
|
||
|
BL_DEFINE_OBJECT_TRAITS(BLVar , kTypeFlagVar)
|
||
|
|
||
|
#undef BL_DEFINE_OBJECT_TRAITS
|
||
|
|
||
|
//! Helper to implement placement new/delete without relying on `<new>` header.
|
||
|
struct PlacementNew { void* ptr; };
|
||
|
|
||
|
} // {BLInternal}
|
||
|
|
||
|
//! Implementation of a placement new so we don't have to depend on `<new>`.
|
||
|
BL_INLINE_NODEBUG void* operator new(size_t, const BLInternal::PlacementNew& p) {
|
||
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||
|
BL_ASSUME(p.ptr != nullptr); // Otherwise MSVC would emit a nullptr check.
|
||
|
#endif
|
||
|
return p.ptr;
|
||
|
}
|
||
|
|
||
|
BL_INLINE_NODEBUG void operator delete(void*, const BLInternal::PlacementNew&) noexcept {}
|
||
|
|
||
|
//! \endcond
|
||
|
#endif
|
||
|
|
||
|
// Public API - TraceError
|
||
|
// =======================
|
||
|
|
||
|
//! \addtogroup blend2d_api_globals
|
||
|
//! \{
|
||
|
|
||
|
//! \name Debugging Functionality
|
||
|
//! \{
|
||
|
|
||
|
//! Returns the `result` passed.
|
||
|
//!
|
||
|
//! Provided for debugging purposes. Putting a breakpoint inside `blTraceError()` can help with tracing an origin
|
||
|
//! of errors reported / returned by Blend2D as each error goes through this function.
|
||
|
//!
|
||
|
//! It's a zero-cost solution that doesn't affect release builds in any way.
|
||
|
BL_NODISCARD
|
||
|
static inline BLResult blTraceError(BLResult result) BL_NOEXCEPT_C { return result; }
|
||
|
|
||
|
BL_BEGIN_C_DECLS
|
||
|
BL_API BL_NORETURN void BL_CDECL blRuntimeAssertionFailure(const char* file, int line, const char* msg) BL_NOEXCEPT_C;
|
||
|
BL_END_C_DECLS
|
||
|
|
||
|
//! \}
|
||
|
//! \}
|
||
|
|
||
|
// Public API - Templates
|
||
|
// ======================
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
// These are the only global functions provided in C++ mode. They are needed by C++ API wrappers and can be used
|
||
|
// freely by Blend2D users as these templates have specializations for some geometry types. For example `blMin(a, b)`
|
||
|
// works with numbers as well as with `BLPoint`.
|
||
|
|
||
|
//! \addtogroup blend2d_api_globals
|
||
|
//! \{
|
||
|
|
||
|
//! \name Explicit Construction & Destruction.
|
||
|
//!
|
||
|
//! These should be only necessary when extending Blend2D.
|
||
|
//!
|
||
|
//! \{
|
||
|
|
||
|
//! Constructs an instance in place (calls its constructor) with optional `args`.
|
||
|
template<typename T, typename... Args>
|
||
|
static BL_INLINE void blCallCtor(T& instance, Args&&... args) noexcept {
|
||
|
// Only needed by MSVC as otherwise it could generate null-pointer check before calling the constructor. If the
|
||
|
// assumption is used with GCC or Clang it would emit a "-Wtautological-undefined-compare" warning so we really
|
||
|
// have to only enable this for compilers that don't have the necessary diagnostics to remove the nullptr check.
|
||
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||
|
BL_ASSUME(&instance != nullptr);
|
||
|
#endif
|
||
|
|
||
|
new(BLInternal::PlacementNew{&instance}) T(BLInternal::forward<Args>(args)...);
|
||
|
}
|
||
|
|
||
|
//! Destroys an instance in place (calls its destructor).
|
||
|
template<typename T>
|
||
|
static BL_INLINE void blCallDtor(T& instance) noexcept {
|
||
|
// Only needed by MSVC as otherwise it could generate null-pointer check before calling the destructor. If the
|
||
|
// assumption is used with GCC or Clang it would emit a "-Wtautological-undefined-compare" warning so we really
|
||
|
// have to only enable this for compilers that don't have the necessary diagnostics to remove the nullptr check.
|
||
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||
|
BL_ASSUME(&instance != nullptr);
|
||
|
#endif
|
||
|
|
||
|
instance.~T();
|
||
|
}
|
||
|
|
||
|
//! \}
|
||
|
|
||
|
//! \name Global C++ Functions
|
||
|
//! \{
|
||
|
|
||
|
//! Bit-cast `x` of `In` type to the given `Out` type.
|
||
|
//!
|
||
|
//! Useful to bit-cast between integers and floating points. The size of `Out` and `In` must be the same otherwise the
|
||
|
//! compilation would fail. Bit casting is used by `blEquals` to implement bit equality for floating point types.
|
||
|
template<typename Out, typename In>
|
||
|
BL_NODISCARD
|
||
|
static BL_INLINE_NODEBUG Out blBitCast(const In& x) noexcept {
|
||
|
static_assert(sizeof(Out) == sizeof(In),
|
||
|
"The size of 'In' and 'Out' types must match");
|
||
|
union { In in; Out out; } u = { x };
|
||
|
return u.out;
|
||
|
}
|
||
|
|
||
|
//! Returns an absolute value of `a`.
|
||
|
template<typename T>
|
||
|
BL_NODISCARD
|
||
|
BL_INLINE_NODEBUG constexpr T blAbs(const T& a) noexcept { return T(a < T(0) ? -a : a); }
|
||
|
|
||
|
//! Returns a minimum value of `a` and `b`.
|
||
|
template<typename T>
|
||
|
BL_NODISCARD
|
||
|
BL_INLINE_NODEBUG constexpr T blMin(const T& a, const T& b) noexcept { return T(b < a ? b : a); }
|
||
|
|
||
|
//! Returns a maximum value of `a` and `b`.
|
||
|
template<typename T>
|
||
|
BL_NODISCARD
|
||
|
BL_INLINE_NODEBUG constexpr T blMax(const T& a, const T& b) noexcept { return T(a < b ? b : a); }
|
||
|
|
||
|
//! Clamps `a` to a range defined as `[b, c]`.
|
||
|
template<typename T>
|
||
|
BL_NODISCARD
|
||
|
BL_INLINE_NODEBUG constexpr T blClamp(const T& a, const T& b, const T& c) noexcept { return blMin(c, blMax(b, a)); }
|
||
|
|
||
|
//! Returns a minimum value of all arguments passed.
|
||
|
template<typename T, typename... Args>
|
||
|
BL_NODISCARD
|
||
|
BL_INLINE_NODEBUG constexpr T blMin(const T& a, const T& b, Args&&... args) noexcept { return blMin(blMin(a, b), BLInternal::forward<Args>(args)...); }
|
||
|
|
||
|
//! Returns a maximum value of all arguments passed.
|
||
|
template<typename T, typename... Args>
|
||
|
BL_NODISCARD
|
||
|
BL_INLINE_NODEBUG constexpr T blMax(const T& a, const T& b, Args&&... args) noexcept { return blMax(blMax(a, b), BLInternal::forward<Args>(args)...); }
|
||
|
|
||
|
//! Returns `true` if `a` and `b` equals at binary level.
|
||
|
//!
|
||
|
//! For example `blEquals(NaN, NaN) == true`.
|
||
|
template<typename T>
|
||
|
BL_NODISCARD
|
||
|
BL_INLINE_NODEBUG bool blEquals(const T& a, const T& b) noexcept { return a == b; }
|
||
|
|
||
|
//! \cond NEVER
|
||
|
template<>
|
||
|
BL_NODISCARD
|
||
|
BL_INLINE_NODEBUG bool blEquals(const float& a, const float& b) noexcept {
|
||
|
return blBitCast<uint32_t>(a) == blBitCast<uint32_t>(b);
|
||
|
}
|
||
|
|
||
|
template<>
|
||
|
BL_NODISCARD
|
||
|
BL_INLINE_NODEBUG bool blEquals(const double& a, const double& b) noexcept {
|
||
|
return blBitCast<uint64_t>(a) == blBitCast<uint64_t>(b);
|
||
|
}
|
||
|
//! \endcond
|
||
|
|
||
|
//! \}
|
||
|
//! \}
|
||
|
#endif
|
||
|
|
||
|
//! \addtogroup blend2d_api_globals
|
||
|
//! \{
|
||
|
|
||
|
//! 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 `BLString`, `BLArray`, `BLGradient`, `BLPath`, etc...
|
||
|
struct BLRange {
|
||
|
size_t start;
|
||
|
size_t end;
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
//! \name Construction & Destruction
|
||
|
//! \{
|
||
|
|
||
|
BL_NODISCARD
|
||
|
static BL_INLINE_NODEBUG constexpr BLRange everything() noexcept { return BLRange{0, SIZE_MAX}; }
|
||
|
|
||
|
//! \}
|
||
|
|
||
|
//! \name Overloaded Operators
|
||
|
//! \{
|
||
|
|
||
|
BL_NODISCARD
|
||
|
BL_INLINE_NODEBUG bool operator==(const BLRange& other) const noexcept { return equals(other); }
|
||
|
|
||
|
BL_NODISCARD
|
||
|
BL_INLINE_NODEBUG bool operator!=(const BLRange& other) const noexcept { return !equals(other); }
|
||
|
|
||
|
//! \}
|
||
|
|
||
|
//! \name Common Functionality
|
||
|
//! \{
|
||
|
|
||
|
//! Reset the range to [0, 0).
|
||
|
BL_INLINE_NODEBUG void reset() noexcept { *this = BLRange{}; }
|
||
|
|
||
|
//! Reset the range to [start, end).
|
||
|
BL_INLINE_NODEBUG void reset(size_t rStart, size_t rEnd) noexcept { *this = BLRange{rStart, rEnd}; }
|
||
|
|
||
|
//! \}
|
||
|
|
||
|
//! \name Equality & Comparison
|
||
|
//! \{
|
||
|
|
||
|
BL_NODISCARD
|
||
|
BL_INLINE_NODEBUG bool equals(const BLRange& other) const noexcept {
|
||
|
return bool(unsigned(blEquals(start, other.start)) &
|
||
|
unsigned(blEquals(end, other.end)));
|
||
|
}
|
||
|
|
||
|
//! \}
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
|
||
|
//! Array view of `T`.
|
||
|
//!
|
||
|
//! \note In C mode the type of data used by `BLArrayView` is `const void*`, thus it has to be retyped to a real
|
||
|
//! type this view points to. There are only few specializations like `BLStringView` that point to a real type.
|
||
|
template<typename T>
|
||
|
struct BLArrayView {
|
||
|
const T* data;
|
||
|
size_t size;
|
||
|
|
||
|
BL_INLINE_NODEBUG void reset() noexcept { *this = BLArrayView{}; }
|
||
|
|
||
|
BL_INLINE_NODEBUG void reset(const T* dataIn, size_t sizeIn) noexcept {
|
||
|
data = dataIn;
|
||
|
size = sizeIn;
|
||
|
}
|
||
|
|
||
|
BL_INLINE const T& operator[](size_t index) noexcept {
|
||
|
BL_ASSERT(index < size);
|
||
|
return data[index];
|
||
|
}
|
||
|
|
||
|
BL_INLINE_NODEBUG const T* begin() const noexcept { return data; }
|
||
|
BL_INLINE_NODEBUG const T* end() const noexcept { return data + size; }
|
||
|
|
||
|
BL_INLINE_NODEBUG const T* cbegin() const noexcept { return data; }
|
||
|
BL_INLINE_NODEBUG const T* cend() const noexcept { return data + size; }
|
||
|
};
|
||
|
|
||
|
// In C++ mode these are just typedefs of `BLArrayView<Type>`.
|
||
|
|
||
|
//! View of char[] data used by String.
|
||
|
typedef BLArrayView<char> BLStringView;
|
||
|
|
||
|
//! View of untyped data.
|
||
|
typedef BLArrayView<uint8_t> BLDataView;
|
||
|
|
||
|
#else
|
||
|
|
||
|
#define BL_DEFINE_ARRAY_VIEW(NAME, TYPE) \
|
||
|
typedef struct { \
|
||
|
const TYPE* data; \
|
||
|
size_t size; \
|
||
|
} NAME
|
||
|
|
||
|
BL_DEFINE_ARRAY_VIEW(BLArrayView, void);
|
||
|
BL_DEFINE_ARRAY_VIEW(BLStringView, char);
|
||
|
|
||
|
typedef BLArrayView BLDataView;
|
||
|
|
||
|
#undef BL_DEFINE_ARRAY_VIEW
|
||
|
|
||
|
#endif
|
||
|
|
||
|
//! \}
|
||
|
|
||
|
#endif // BLEND2D_API_H_INCLUDED
|