odin-blend2d

Odin bindings to Blend2D
Log | Files | Refs | README | LICENSE

api.h (75949B)


      1 // This file is part of Blend2D project <https://blend2d.com>
      2 //
      3 // See blend2d.h or LICENSE.md for license and copyright information
      4 // SPDX-License-Identifier: Zlib
      5 
      6 #ifndef BLEND2D_API_H_INCLUDED
      7 #define BLEND2D_API_H_INCLUDED
      8 
      9 // This header can only be included by either <blend2d.h> or by internal Blend2D headers. Prevent users including
     10 // <blend2d/...> headers by accident and prevent not including "blend2d/api-build_p.h" during the Blend2D compilation.
     11 #if !defined(BLEND2D_H_INCLUDED) && !defined(BLEND2D_API_BUILD_P_H_INCLUDED) && !defined(__INTELLISENSE__)
     12   #pragma message("Include either <blend2d.h> or <blend2d-impl.h> to use Blend2D library")
     13 #endif
     14 
     15 #include <stdarg.h>
     16 #include <stddef.h>
     17 #include <stdint.h>
     18 #include <string.h>
     19 
     20 #ifdef __cplusplus
     21   #include <type_traits>
     22 #else
     23   #include <stdbool.h>
     24 #endif
     25 
     26 //! \mainpage Documentation Index
     27 //!
     28 //! Blend2D C and C++ API reference documentation generated by Doxygen.
     29 //! \section main_topics Topics
     30 //!
     31 //! If you are new to Blend2D please checkout out the following links:
     32 //!
     33 //!   - <a href="getting-started.html">Getting Started</a> - introduction to Blend2D with code samples and outputs
     34 //!   - <a href="build-instructions.html">Build Instructions</a> - instructions to build Blend2D with or without cmake
     35 //!   - <a href="multithreaded-rendering.html">Multithreaded Rendering</a> - introduction to multi-threaded rendering
     36 //!
     37 //! \section main_overview Overview
     38 //!
     39 //! Blend2D API consists of enumerations, functions, structs, and C++ classes. Common concepts like enumerations and
     40 //! POD structs are shared between C and C++. Some structs contain extra functionality like `BLSomething::reset()`
     41 //! that is only available to C++ users, however, such functionality is only provided for convenience and doesn't
     42 //! affect how Blend2D can be used from C.
     43 //!
     44 //! Blend2D C++ API is in fact build on top of the C API and all C++ functions are inlines that call C API without
     45 //! any overhead. It would require double effort to document both C and C++ APIs separately so we have decided to
     46 //! only document C++ API and to only list \ref bl_c_api "C API" for users that need it. The C API should be
     47 //! straightforward and matches very well the C++ part.
     48 //!
     49 //!
     50 //! \section main_groups Groups
     51 //!
     52 //! The documentation is split into the following groups:
     53 //!
     54 //! $$DOCS_GROUP_OVERVIEW$$
     55 //!
     56 //! \section main_important Important
     57 //!
     58 //! Doxygen has its limits, for example it sorts struct members in anonymous structs and unions and we haven't figured
     59 //! out how to turn this feature off. This means that the order of members doesn't have to reflect the original struct
     60 //! layout. Always double-check struct layout in case you plan to use a brace initialization of simple structs or in
     61 //! case you are creating bindings.
     62 
     63 
     64 //! \defgroup bl_globals Globals
     65 //! \brief Global functions, constants, and classes used universally across the library.
     66 //!
     67 //! ### Result / Status Code
     68 //!
     69 //!   - \ref BLResult - a `uint32_t` typedef that represents a result returned by most C API and C++ API functions
     70 //!   - \ref BLResultCode - an actual enumeration that describes known values that can be used by \ref BLResult
     71 //!   - \ref BL_PROPAGATE() - macro that is used to propagate (return) a non-successful result from a function
     72 //!
     73 //! ### Types
     74 //!
     75 //!   - \ref BLTag - tag is a 32-bit value representing 4 ASCII characters, used by PNG and OpenType at the moment
     76 //!   - \ref BLUniqueId - unique identifier is a 64-bit value, which must be unique for each domain where used
     77 //!   - \ref BLUnknown - a `void` type, used in few special places
     78 //!
     79 //! ### Function Types
     80 //!
     81 //!   - \ref BLDebugMessageSinkFunc - a debug sink, can be used for logging purposes
     82 //!
     83 //! ### Constants
     84 //!
     85 //!   - \ref BLByteOrder - byte order
     86 //!   - \ref BLDataAccessFlags - provides a type of data access (read, write, or both)
     87 //!   - \ref BLDataSourceType - provides a type of a data source (memory, file, etc...)
     88 //!   - \ref BLModifyOp - modification operation
     89 //!   - \ref BLBooleanOp - boolean operation
     90 
     91 
     92 //! \defgroup bl_containers Containers
     93 //! \brief Containers and views used by Blend2D.
     94 //!
     95 //! Blend2D needs certain containers to function, but it cannot use containers from a C++ standard library because it
     96 //! provides both C-API and C-ABI. In addition, the underlying representation of all classes that inherit from \ref
     97 //! BLObjectCore need to provide reference counting, even for containers, so they can be shared across threads without
     98 //! requiring to do any extra work by Blend2D users.
     99 //!
    100 //! In addition, Blend2D embraces small data optimization (often described as SSO - small string optimization), which
    101 //! is utilized by \ref BLString, \ref BLArray, \ref BLBitArray, and other specialized containers.
    102 //!
    103 //! ### Views & Common Types
    104 //!
    105 //!   - \ref BLArrayView<T> - read-only view of an array (any array, not just \ref BLArray<T>)
    106 //!   - \ref BLStringView - read-only view of a string, the view doesn't have to be null terminated
    107 //!   - \ref BLRange - start/end range, which can be used with sequential containers
    108 //!
    109 //! ### Sequential Containers
    110 //!
    111 //!   - \ref BLArray<T> - growable array of T elements. Can hold both primitive types and Blend2D objects
    112 //!     - \ref BLArrayCore - C API type representing \ref BLArray<T>
    113 //!
    114 //!   - \ref BLString - 8-bit null terminated string, usually UTF-8 encoded, but it's not a requirement
    115 //!     - \ref BLStringCore - C API type representing \ref BLString
    116 //!
    117 //! ### Bit Containers
    118 //!
    119 //!   - \ref BLBitArray - a dense bit-array (stores bits starting from 0 to size, sequentially)
    120 //!     - \ref BLBitArrayCore - C API type representing \ref BLBitArray
    121 //!
    122 //!   - \ref BLBitSet - a sparse bit array that can represent sparse/dense bits and range of bits (will be deprecated)
    123 //!     - \ref BLBitSetCore - C API type representing \ref BLBitSet
    124 //!     - \ref BLBitSetSegment - segment used by \ref BLBitSet
    125 //!     - \ref BLBitSetData - data view used by \ref BLBitSet
    126 
    127 
    128 //! \defgroup bl_geometry Geometries
    129 //! \brief Geometries, paths, and transformations.
    130 //!
    131 //! Blend2D offers various geometry structures and objects that can be used with either \ref BLPath for path building or
    132 //! \ref BLContext for rendering. In general there are two categories - \ref BLPath, which specifies a 2D path composed
    133 //! of path segments, and lightweight geometries such as \ref BLRect, \ref BLRoundRect, etc... which are only described
    134 //! by a trivial C/C++ struct.
    135 //!
    136 //! ### Paths
    137 //!
    138 //!   - \ref BLPath - path container
    139 //!     - \ref BLPathCore - C API type representing \ref BLPath
    140 //!     - \ref BLPathCmd - path command specifies the type of a path segment withing \ref BLPath
    141 //!     - \ref BLPathFlags - flags associated with \ref BLPath
    142 //!     - \ref BLPathReverseMode - reverse mode accepted by  \ref BLPath::add_reversed_path()
    143 //!     - \ref BLPathView - view providing all necessary variables to inspect and iterate a \ref BLPath
    144 //!
    145 //! ### Path Operations
    146 //!
    147 //!   - \ref BLStrokeOptions - holds stroking options
    148 //!     - \ref BLStrokeOptionsCore - C API type representing \ref BLStrokeOptions
    149 //!   - \ref BLOffsetMode - path offsetting mode
    150 //!   - \ref BLFlattenMode - path flattening mode
    151 //!   - \ref BLStrokeCap - stroke cap option
    152 //!   - \ref BLStrokeCapPosition - stroke cap position (can be specified separately)
    153 //!   - \ref BLStrokeJoin - stroke join option
    154 //!   - \ref BLStrokeTransformOrder - the order of a transformation when rendering a stroked path or geometry
    155 //!
    156 //! ### Lightweight Geometries and Structs
    157 //!
    158 //!   - \ref BLPoint - 2D point composed of `[x, y]` values (64-bit floats)
    159 //!   - \ref BLPointI - 2D point composed of `[x, y]` values (32-bit integers)
    160 //!   - \ref BLSize - 2D size composed of `[w, h]` values (64-bit floats)
    161 //!   - \ref BLSizeI - 2D size composed of `[w, h]` values (32-bit integers)
    162 //!   - \ref BLBox - 2D rectangular area composed of `[x0, y0, x1, y1]` values (64-bit floats)
    163 //!   - \ref BLBoxI - 2D rectangular area composed of `[x0, y0, x1, y1]` values (32-bit integers)
    164 //!   - \ref BLRect - 2D rectangular area composed of `[x, y, w, h]` values (64-bit floats)
    165 //!   - \ref BLRectI - 2D rectangular area composed of `[x, y, w, h]` values (32-bit integers)
    166 //!   - \ref BLRoundRect - rounded rectangle within `[x, y, w, h]` with radius `[rx, ry]` (64-bit floats)
    167 //!   - \ref BLCircle - circle at `[cx, cy]` with radius `r` (64-bit floats)
    168 //!   - \ref BLEllipse - ellipse at `[cx, cy]` with radius `[rx, ry]` (64-bit floats)
    169 //!   - \ref BLArc - arc at `[cx, cy]` with radius `[rx, ry]` and `start` + `sweep` values  (64-bit floats)
    170 //!   - \ref BLLine - line segment from `[x0, y0]` to `[x1, y1]` (64-bit floats)
    171 //!   - \ref BLTriangle - triangle having `[x0, y0]`, `[x1, y1]`, and `[x2, y2]` vertices (64-bit floats)
    172 //!
    173 //! ### Geometry Constants
    174 //!
    175 //!   - \ref BLGeometryDirection - specifies a direction
    176 //!   - \ref BLGeometryType - specifies a type of a geometry argument (low-level)
    177 //!   - \ref BLFillRule - specifies a fill rule (used by both \ref BLPath and \ref BLContext)
    178 //!   - \ref BLHitTest - specifies a result of hit-testing
    179 //!
    180 //! ### Transformations
    181 //!
    182 //!   - \ref BLMatrix2D - 2D transformation matrix (affine)
    183 //!     - \ref BLTransformOp - transformation operation (low-level)
    184 //!     - \ref BLTransformType - transformation type
    185 
    186 
    187 //! \defgroup bl_imaging Imaging
    188 //! \brief Images and image codecs.
    189 //!
    190 //! Provides image container (\ref BLImage), image codecs (\ref BLImageCodec), and pixel conversion (\ref BLPixelConverter).
    191 //!
    192 //! ### Images
    193 //!
    194 //!   - \ref BLImage - image container that holds pixel data
    195 //!     - \ref BLImageCore - C API type representing \ref BLImage
    196 //!     - \ref BLImageData - pixel data and additional attributes
    197 //!     - \ref BLImageInfo - image information data
    198 //!     - \ref BLImageInfoFlags - image information flags
    199 //!     - \ref BLImageScaleFilter - image scaling filters
    200 //!
    201 //! ### Image Codecs
    202 //!
    203 //!   - \ref BLImageCodec - image codec
    204 //!     - \ref BLImageCodecCore - C API type representing \ref BLImageCodec
    205 //!     - \ref BLImageCodecFeatures - image codec feature flags
    206 //!
    207 //!   - \ref BLImageDecoder - image decoder
    208 //!     - \ref BLImageDecoderCore - C API type representing \ref BLImageDecoder
    209 //!
    210 //!   - \ref BLImageEncoder - image encoder
    211 //!     - \ref BLImageEncoderCore - C API type representing \ref BLImageEncoder
    212 //!
    213 //! ### Pixel Format
    214 //!
    215 //!   - \ref BLFormat - pixel format
    216 //!   - \ref BLFormatFlags - pixel format flags
    217 //!   - \ref BLFormatInfo - pixel format information
    218 //!
    219 //!
    220 //! ### Pixel Conversion
    221 //!
    222 //!   - \ref BLPixelConverter - pixel converter
    223 //!     - \ref BLPixelConverterCore - C API type representing \ref BLPixelConverter
    224 //!     - \ref BLPixelConverterCreateFlags - flags that can be used when creating a pixel converter
    225 //!     - \ref BLPixelConverterOptions - pixel conversion options
    226 
    227 
    228 //! \defgroup bl_styling Styling
    229 //! \brief Colors, gradients, and patterns.
    230 //!
    231 //! Styling provides various classes that represent colors, gradients, and patterns. While colors are used universally
    232 //! across the library (not just as styles), gradients and patterns are always used as fill or stroke styles.
    233 //!
    234 //! ### Colors
    235 //!
    236 //!   - \ref BLRgba - RGBA color specified as 32-bit floating point value per channel
    237 //!   - \ref BLRgba32 - RGBA color specified as 8-bit value per channel as `0xAARRGGBB`
    238 //!   - \ref BLRgba64 - RGBA color specified as 16-bit value per channel as `0xAAAARRRRGGGGBBBB`
    239 //!   - (please note that the order if bytes in \ref BLRgba32 and \ref BLRgba64 is ARGB (from MSB to LSB) for
    240 //!     compatibility with other libraries and common representations)
    241 //!
    242 //! ### Gradients
    243 //!
    244 //!   - \ref BLGradient - container that holds gradient values and stops
    245 //!     - \ref BLGradientCore - C API type representing \ref BLGradient
    246 //!     - \ref BLGradientStop - associates a color with offset (from 0.0 to 1.0)
    247 //!     - \ref BLGradientType - describes a gradient type
    248 //!     - \ref BLGradientValue - index of a gradient value (overlaps between various gradient types)
    249 //!     - \ref BLGradientQuality - describes a gradient quality
    250 //!     - \ref BLExtendMode - specifies a gradient extend mode (only simple extend modes can be used with gradients)
    251 //!     - \ref BLLinearGradientValues - values describing a linear gradient
    252 //!     - \ref BLRadialGradientValues - values describing a radial gradient
    253 //!     - \ref BLConicGradientValues - values describing a conic gradient
    254 //!
    255 //! ### Patterns
    256 //!
    257 //!   - \ref BLPattern - represents a pattern
    258 //!     - \ref BLPatternCore - C API type representing \ref BLPattern
    259 //!     - \ref BLPatternQuality - describes a pattern quality
    260 //!     - \ref BLExtendMode - specifies a pattern extend mode (all extend modes can be used with patterns)
    261 //!
    262 //! ### Variant
    263 //!
    264 //!   - \ref BLVar - variant type can be used to hold any style and then passed to the rendering context
    265 
    266 
    267 //! \defgroup bl_text Text
    268 //! \brief Fonts & Text support.
    269 //!
    270 //! ### Glyph Containers & Processing
    271 //!
    272 //!   - \ref BLGlyphBuffer - holds glyphs and additional metadata
    273 //!     - \ref BLGlyphBufferCore - C API type representing \ref BLGlyphBuffer
    274 //!     - \ref BLGlyphBufferImpl - underlying representation of \ref BLGlyphBuffer
    275 //!
    276 //!   - \ref BLGlyphRun - provides a glyph run data
    277 //!     - \ref BLGlyphRunFlags - flags used by \ref BLGlyphRun
    278 //!     - \ref BLGlyphRunIterator - iterates a \ref BLGlyphRun
    279 //!
    280 //!   - \ref BLGlyphId - a type representing a single glyph (32-bit value)
    281 //!   - \ref BLGlyphInfo - glyph information used by \ref BLGlyphBuffer and \ref BLGlyphRun
    282 //!   - \ref BLGlyphMappingState - information accumulated during mapping characters to glyphs
    283 //!   - \ref BLGlyphPlacement - glyph placement used by \ref BLGlyphBuffer and \ref BLGlyphRun
    284 //!   - \ref BLGlyphPlacementType - glyph placement used \ref BLGlyphBuffer and \ref BLGlyphRun
    285 //!   - \ref BLGlyphOutlineSinkInfo - additional information passed to a callback by \ref BLFont::get_glyph_outlines()
    286 //!     and \ref BLFont::get_glyph_run_outlines()
    287 //!
    288 //! ### Fonts
    289 //!
    290 //!   - \ref BLFont - represents a displayable font (having size, font properties, and variations configured)
    291 //!     - \ref BLFontCore - C API type representing \ref BLFont
    292 //!     - \ref BLFontMatrix - a simple matrix that can be used to transform a font, used by \ref BLFont
    293 //!     - \ref BLFontMetrics - font metrics, used by \ref BLFont
    294 //!     - \ref BLFontStretch - font stretch property, used by \ref BLFont
    295 //!     - \ref BLFontStyle - font style property, used by \ref BLFont
    296 //!     - \ref BLFontWeight - font weight property, used by \ref BLFont
    297 //!
    298 //!   - \ref BLFontData - provides font data that can be used by \ref BLFont and \ref BLFontFace
    299 //!     - \ref BLFontDataCore - C API type representing \ref BLFontData
    300 //!     - \ref BLFontDataFlags - Flags used by \ref BLFontData
    301 //!     - \ref BLFontTable - represents a TrueType/OpenType table identified by a \ref BLTag
    302 //!
    303 //!   - \ref BLFontFace - represents a font face (OpenType file loaded from file or memory)
    304 //!     - \ref BLFontFaceCore - C API type representing \ref BLFontFace
    305 //!     - \ref BLFontFaceInfo - font face information, used by \ref BLFontFace
    306 //!     - \ref BLFontFaceFlags - flags used by \ref BLFontFace
    307 //!     - \ref BLFontFaceDiagFlags - diagnostic flags used by \ref BLFontFace
    308 //!     - \ref BLFontFaceType - type of a font face, provided by \ref BLFontFace
    309 //!     - \ref BLFontDesignMetrics - design font metrics, used by \ref BLFontFace
    310 //!     - \ref BLFontOutlineType - type of outlines used by a font, used by \ref BLFontFace
    311 //!     - \ref BLFontPanoseInfo - panose information, provided by \ref BLFontFace
    312 //!     - \ref BLFontStringId - identifier of a string stored in a font face, used by \ref BLFontFace
    313 //!     - \ref BLFontCoverageInfo - unicode coverage bits, provided by \ref BLFontFace
    314 //!     - \ref BLFontCoverageGroup - meaning of unicode coverage bits of \ref BLFontCoverageInfo
    315 //!
    316 //!   - \ref BLFontFeatureSettings - provides feature settings of a \ref BLFont
    317 //!     - \ref BLFontFeatureSettingsCore - C API type representing \ref BLFontFeatureSettings
    318 //!     - \ref BLFontFeatureSettingsView - view of \ref BLFontFeatureSettings
    319 //!     - \ref BLFontFeatureItem - associates a font feature tag (\ref BLTag) with a value
    320 //!
    321 //!   - \ref BLFontVariationSettings - provides variation settings of a \ref BLFont
    322 //!     - \ref BLFontVariationSettingsCore - C API type representing \ref BLFontVariationSettings
    323 //!     - \ref BLFontVariationSettingsView - view of \ref BLFontVariationSettings
    324 //!     - \ref BLFontVariationItem - associates a font variation tag (\ref BLTag) with a value
    325 //!
    326 //! ### Font Management
    327 //!
    328 //!   - \ref BLFontManager - simple font management that can store and query \ref BLFontFace instances
    329 //!     - \ref BLFontManagerCore - C API type representing \ref BLFontManager
    330 //!     - \ref BLFontQueryProperties - font query properties, used by \ref BLFontManager
    331 //!
    332 //! ### Text
    333 //!
    334 //!   - \ref BLOrientation - text or glyph run orientation
    335 //!   - \ref BLTextDirection - specifies text direction
    336 //!   - \ref BLTextEncoding - specifies text encoding
    337 //!   - \ref BLTextMetrics - metrics of a whole text run
    338 
    339 //! \defgroup bl_rendering Rendering
    340 //! \brief 2D rendering context API, structures, and constants.
    341 //!
    342 //! ### Rendering Context
    343 //!
    344 //!   - \ref BLContext - a 2D rendering context
    345 //!     - \ref BLContextCore - C API type representing \ref BLContext
    346 //!     - \ref BLContextType - rendering context type
    347 //!     - \ref BLContextCookie - cookie can be used with \ref BLContext::save() and \ref BLContext::restore()
    348 //!     - \ref BLContextCreateInfo - additional options that can be used when creating a rendering context
    349 //!     - \ref BLContextCreateFlags - flags that can be used by \ref BLContextCreateInfo
    350 //!     - \ref BLContextErrorFlags - accumulated error flags during the lifetime of a rendering context
    351 //!     - \ref BLContextFlushFlags - flags that can be passed to \ref BLContext::flush()
    352 //!     - \ref BLContextHint - rendering hint
    353 //!     - \ref BLContextHints - all rendering hints in a single struct
    354 //!     - \ref BLContextStyleSlot - style slot (either fill or stroke)
    355 //!     - \ref BLContextStyleSwapMode - style swap mode (how to swap a fill and stroke styles)
    356 //!     - \ref BLContextStyleTransformMode - style transform mode (how to combine with existing transform)
    357 //!     - \ref BLContextRenderTextOp - type of a text rendering operation (low-level)
    358 //!
    359 //!     - \ref BLClipMode - clip mode
    360 //!     - \ref BLCompOp - composition operator
    361 //!     - \ref BLRenderingQuality - rendering quality (aliased rendering or the quality of anti-aliasing)
    362 
    363 
    364 //! \defgroup bl_runtime Runtime
    365 //! \brief Interaction with Blend2D runtime.
    366 
    367 
    368 //! \defgroup bl_filesystem Filesystem
    369 //! \brief Filesystem utilities.
    370 //!
    371 //! Blend2D doesn't do much with filesystem, however, since the library provides API for loading and saving raster
    372 //! images and for loading font files, it internally needs a lightweight filesystem access. The API is also provided
    373 //! for users that would like to use a very simple API to access a filesystem.
    374 //!
    375 //! ### File
    376 //!
    377 //!   - \ref BLFile - a lightweight non-shareable file API that uses a system file descriptor API where possible.
    378 //!     - \ref BLFileCore - C API type representing \ref BLFile
    379 //!     - \ref BLFileOpenFlags - flags used by \ref BLFile::open() function
    380 //!     - \ref BLFileReadFlags - flags used when reading whole files by \ref BLFileSystem::read_file()
    381 //!     - \ref BLFileSeekType - flags used by \ref BLFile::seek() function
    382 //!
    383 //! ### Filesystem
    384 //!
    385 //!   - \ref BLFileSystem - filesystem utilities
    386 //!     - \ref BLFileInfo - file information (retrieved either by calling `stat()` or a similar function under Windows)
    387 //!     - \ref BLFileInfoFlags - flags used by \ref BLFileInfo
    388 
    389 
    390 //! \defgroup bl_miscellaneous Miscellaneous
    391 //! \brief Miscellaneous and uncategorized API.
    392 //!
    393 //! ### Random
    394 //!
    395 //!   - \ref BLRandom - pseudo random number generator
    396 
    397 //! \defgroup bl_impl Impl API
    398 //! \brief API required for extending Blend2D functionality.
    399 //!
    400 //! Everything that is part of this group requires `<blend2d-impl.h>` to be
    401 //! included before the use as this API is only for users that extend Blend2D.
    402 
    403 
    404 //! \defgroup bl_macros Macros
    405 //! \brief Preprocessor macros and compile-time constants.
    406 
    407 
    408 //! \defgroup bl_c_api C API
    409 //! \brief Blend2D C API structs and functions exported as `extern "C"` (C API).
    410 //!
    411 //! We do not document most C API functions as they are called from C++ wrappers, which are documented and should be
    412 //! used as a reference. The most important thing in using C API is to understand how lifetime of instances is managed.
    413 //!
    414 //! Each type that requires initialization provides `bl[...]Init`, 'bl[...]Destroy', and `bl[...]Reset` C API functions.
    415 //! Init/Destroy are called by C++ constructors and destructors on C++ side and must be used the same way by C users.
    416 //! Although these functions return \ref BLResult it's guaranteed the result is always \ref BL_SUCCESS - the return
    417 //! value is only provided for consistency and possible tail calling.
    418 //!
    419 //! The following example should illustrate how `Init` and `Destroy` works:
    420 //!
    421 //! ```
    422 //! BLImageCore img;
    423 //!
    424 //! // Initializes the BLImage object, always succeeds.
    425 //! bl_image_init(&img);
    426 //!
    427 //! // Creates image data, note how it's called on an already initialized object.
    428 //! bl_image_create(&img, 128, 128, BL_FORMAT_PRGB32);
    429 //!
    430 //! // Destroys the BLImage object, always succeeds.
    431 //! bl_image_destroy(&img);
    432 //! ```
    433 //!
    434 //! Some init functions may provide shortcuts for the most used scenarios that
    435 //! merge initialization and resource allocation into a single function:
    436 //!
    437 //! ```
    438 //! BLImageCore img;
    439 //!
    440 //! // Combines bl_image_init() with bl_image_create().
    441 //! bl_image_init_as(&img, 128, 128, BL_FORMAT_PRGB32);
    442 //!
    443 //! // Destroys the data, doesn't have to be called if bl_image_init_as() failed.
    444 //! bl_image_destroy(&img);
    445 //! ```
    446 //!
    447 //! It's worth knowing that default initialization in Blend2D costs nothing and no resources are allocated, thus
    448 //! initialization never fails and in theory default initialized objects don't have to be destroyed as they don't
    449 //! hold any data that would have to be deallocated (however never do that in practice).
    450 //!
    451 //! There is a distinction between 'destroy()' and 'reset()' functionality. Destroy would destroy the object and
    452 //! put it into a non-reusable state. Thus if the object is used by accident it should crash on null-pointer access.
    453 //! On the contrary, resetting the object with 'reset()' explicitly states that the instance will be reused so
    454 //! 'reset()' basically destroys the object and puts it into its default constructed state for further use. This
    455 //! means that it's not needed to explicitly call 'destroy()' on instance that was reset, and it also is not needed
    456 //! for a default constructed instance. However, we recommend to not count on this behavior and to always properly
    457 //! initialize and destroy Blend2D objects.
    458 //!
    459 //! The following example should explain how init/reset can avoid destroy:
    460 //!
    461 //! ```
    462 //! BLImageCore img;
    463 //!
    464 //! // Now image is default constructed/initialized. if you did just this and abandon it then no resources will
    465 //! // be leaked as default construction is not allocating any resources nor increasing any reference counters.
    466 //! bl_image_init(&img);
    467 //!
    468 //! // Now image will have to dynamically allocate some memory to store pixel data. If this succeeds the image
    469 //! // will have to be explicitly destroyed when it's no longer needed to release the associated data it holds.
    470 //! BLResult result = bl_image_create(&img, 128, 128, BL_FORMAT_PRGB32);
    471 //!
    472 //! // If `bl_image_create()` failed it leaves the object in the state it was prior to the call. Most of API calls
    473 //! // in Blend2D behave like this (it's transactional). This means that if the call failed the `img` would still
    474 //! // be default constructed and the function can simply return without leaking any resources. In C++ API the
    475 //! // compiler would emit a call to `bl_image_destroy()` implicitly, but that's just how RAII works.
    476 //! if (result != BL_SUCCESS)
    477 //!   return result;
    478 //!
    479 //! // Resetting image would destroy its data and make it default constructed.
    480 //! bl_image_reset(&img);
    481 //!
    482 //! // The instance is valid after `reset()` - it's now a default constructed instance as created by `bl_image_init()`.
    483 //! printf("%p", img.impl);
    484 //!
    485 //! // Calling `bl_image_destroy()` would make the instance invalid.
    486 //! bl_image_destroy(&img);
    487 //!
    488 //! // Calling any method except initialization such as `bl_image_init()` on invalid instance is UNDEFINED BEHAVIOR!
    489 //! bl_image_create(&img, 128, 128, BL_FORMAT_PRGB32); // Can crash, can corrupt memory, can succeed, never do that!
    490 //! ```
    491 
    492 
    493 //! \cond INTERNAL
    494 
    495 //! \defgroup blend2d_internal Internal
    496 //!
    497 //! \brief Internal API.
    498 
    499 
    500 //! \defgroup blend2d_codec_impl Codecs
    501 //!
    502 //! \brief Codecs implementation.
    503 
    504 
    505 //! \defgroup blend2d_raster_engine_impl Raster
    506 //!
    507 //! \brief Raster rendering context.
    508 
    509 
    510 //! \defgroup blend2d_pipeline_jit JIT pipeline compiler
    511 //!
    512 //! \brief JIT pipeline compiler.
    513 
    514 
    515 //! \defgroup blend2d_pipeline_reference Reference pipeline implementation
    516 //!
    517 //! \brief Reference pipeline implementation.
    518 
    519 
    520 //! \defgroup blend2d_opentype_impl OpenType
    521 //!
    522 //! \brief OpenType implementation.
    523 
    524 //! \endcond
    525 
    526 // Blend2D Version
    527 // ===============
    528 
    529 //! \addtogroup bl_macros
    530 //! \{
    531 
    532 //! \name Version Information
    533 //! \{
    534 
    535 //! Makes a version number representing a `MAJOR.MINOR.PATCH` combination.
    536 #define BL_MAKE_VERSION(MAJOR, MINOR, PATCH) (((MAJOR) << 16) | ((MINOR) << 8) | (PATCH))
    537 
    538 //! Blend2D library version.
    539 #define BL_VERSION BL_MAKE_VERSION(0, 21, 1)
    540 
    541 //! \}
    542 //! \}
    543 
    544 // Build Type
    545 // ==========
    546 
    547 //! \cond INTERNAL
    548 
    549 // These definitions can be used to enable static library build. Embed is used when Blend2D's source code is embedded
    550 // directly in another project, implies static build as well.
    551 //
    552 // #define BL_STATIC                // Blend2D is a statically linked library.
    553 
    554 // These definitions control the build mode and tracing support. The build mode should be auto-detected at compile
    555 // time, but it's possible to override it in case that the auto-detection fails.
    556 //
    557 // Tracing is a feature that is never compiled by default and it's only used to debug Blend2D itself.
    558 //
    559 // #define BL_BUILD_DEBUG           // Define to enable debug-mode.
    560 // #define BL_BUILD_RELEASE         // Define to enable release-mode.
    561 
    562 // Detect BL_BUILD_DEBUG and BL_BUILD_RELEASE if not defined.
    563 #if !defined(BL_BUILD_DEBUG) && !defined(BL_BUILD_RELEASE)
    564   #ifndef NDEBUG
    565     #define BL_BUILD_DEBUG
    566   #else
    567     #define BL_BUILD_RELEASE
    568   #endif
    569 #endif
    570 
    571 //! \endcond
    572 
    573 // Public Macros
    574 // =============
    575 
    576 //! \addtogroup bl_macros
    577 //! \{
    578 
    579 //! \name Target Information
    580 //! \{
    581 
    582 //! \def BL_BYTE_ORDER
    583 //!
    584 //! A compile-time constant (macro) that defines byte-order of the target. It can be either `1234` for little-endian
    585 //! targets or `4321` for big-endian targets. Blend2D uses this macro internally, but it's also available to end
    586 //! users as sometimes it could be important for deciding between pixel formats or other important details.
    587 #if (defined(__ARMEB__)) || (defined(__MIPSEB__)) || \
    588     (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
    589   #define BL_BYTE_ORDER 4321
    590 #else
    591   #define BL_BYTE_ORDER 1234
    592 #endif
    593 
    594 //! \}
    595 
    596 //! \name Decorators
    597 //! \{
    598 
    599 //! \def BL_API
    600 //!
    601 //! A base API decorator that marks functions and variables exported by Blend2D.
    602 #if !defined(BL_STATIC)
    603   #if defined(_WIN32) && (defined(_MSC_VER) || defined(__MINGW32__))
    604     #if defined(BL_BUILD_EXPORT)
    605       #define BL_API __declspec(dllexport)
    606     #else
    607       #define BL_API __declspec(dllimport)
    608     #endif
    609   #elif defined(_WIN32) && defined(__GNUC__)
    610     #if defined(BL_BUILD_EXPORT)
    611       #define BL_API __attribute__((dllexport))
    612     #else
    613       #define BL_API __attribute__((dllimport))
    614     #endif
    615   #elif defined(__GNUC__)
    616     #define BL_API __attribute__((__visibility__("default")))
    617   #endif
    618 #endif
    619 
    620 #ifndef BL_API
    621   #define BL_API
    622 #endif
    623 
    624 //! \def BL_CDECL
    625 //!
    626 //! Calling convention used by all exported functions and function callbacks. If you pass callbacks to Blend2D it's
    627 //! strongly advised to decorate the callback explicitly as some compilers provide a way of overriding a global
    628 //! calling convention (like __vectorcall on Windows platform), which would break the use of such callbacks.
    629 #if defined(__GNUC__) && defined(__i386__) && !defined(__x86_64__)
    630   #define BL_CDECL __attribute__((__cdecl__))
    631 #elif defined(_MSC_VER)
    632   #define BL_CDECL __cdecl
    633 #else
    634   #define BL_CDECL
    635 #endif
    636 
    637 //! \def BL_INLINE
    638 //!
    639 //! Marks functions that should always be inlined.
    640 #if defined(__GNUC__)
    641   #define BL_INLINE inline __attribute__((__always_inline__))
    642 #elif defined(_MSC_VER)
    643   #define BL_INLINE __forceinline
    644 #else
    645   #define BL_INLINE inline
    646 #endif
    647 
    648 //! \def BL_INLINE_NODEBUG
    649 //!
    650 //! The same as \ref BL_INLINE possibly combined with `__attribute__((artificial))` or `__attribute__((nodebug))`
    651 //! if the compiler supports any of them.
    652 //!
    653 //! The purpose of this macro is to tell the compiler that the function should not need debugging, thus the debug
    654 //! information can be omitted completely. Blend2D uses tris decorator to decorate C++ inline functions that either
    655 //! call C API or that are trivial to improve debugging experience of some tiny abstractions.
    656 #if defined(__clang__)
    657   #define BL_INLINE_NODEBUG inline __attribute__((__always_inline__, __nodebug__))
    658 #elif defined(__GNUC__)
    659   #define BL_INLINE_NODEBUG inline __attribute__((__always_inline__, __artificial__))
    660 #else
    661   #define BL_INLINE_NODEBUG BL_INLINE
    662 #endif
    663 
    664 #define BL_INLINE_CONSTEXPR constexpr BL_INLINE_NODEBUG
    665 
    666 //! \def BL_NORETURN
    667 //!
    668 //! Function attribute used by functions that never return (that terminate the process). This attribute is used
    669 //! only once by \ref bl_runtime_assertion_failure() function, which is only used when assertions are enabled. This
    670 //! macro should be considered internal and it's not designed for Blend2D users.
    671 #if defined(__GNUC__)
    672   #define BL_NORETURN __attribute__((__noreturn__))
    673 #elif defined(_MSC_VER)
    674   #define BL_NORETURN __declspec(noreturn)
    675 #else
    676   #define BL_NORETURN
    677 #endif
    678 
    679 //! \def BL_NOEXCEPT_C
    680 //!
    681 //! Defined to `noexcept` in C++ mode and nothing in C mode. This is used to mark Blend2D C API, which is `noexcept`
    682 //! by design.
    683 #if defined(__cplusplus)
    684   #define BL_NOEXCEPT_C noexcept
    685 #else
    686   #define BL_NOEXCEPT_C
    687 #endif
    688 
    689 //! \def BL_PURE
    690 //!
    691 //! Function attribute that describes functions that have no side effects. The macro expands to
    692 //! `__attribute__((__pure__))` when compiling with GCC or Clang, otherwise it expands to nothing.
    693 #if defined(__GNUC__)
    694   #define BL_PURE __attribute__((__pure__))
    695 #else
    696   #define BL_PURE
    697 #endif
    698 
    699 //! \def BL_ALIGN_TYPE(TYPE, ALIGNMENT)
    700 //!
    701 //! Defines a type with a particular alignment, avoiding the use of alignas() as some compilers
    702 //! have a buggy implementation and restrict alignas() more than a compiler specific attribute.
    703 #if defined(__GNUC__)
    704   #define BL_ALIGN_TYPE(TYPE, ALIGNMENT) __attribute__((__aligned__(ALIGNMENT))) TYPE
    705 #elif defined(_MSC_VER)
    706   #define BL_ALIGN_TYPE(TYPE, ALIGNMENT) __declspec(align(ALIGNMENT)) TYPE
    707 #else
    708   #define BL_ALIGN_TYPE(TYPE, ALIGNMENT) TYPE
    709 #endif
    710 
    711 //! \}
    712 
    713 //! \name Assumptions
    714 //! \{
    715 
    716 //! \def BL_ASSUME(...)
    717 //!
    718 //! Macro that tells the C/C++ compiler that the expression `...` evaluates to true. This macro is only used by few
    719 //! places and should be considered internal as you shouldn't need it when using Blend2D library.
    720 #if defined(__clang__)
    721   #define BL_ASSUME(...) __builtin_assume(__VA_ARGS__)
    722 #elif defined(__GNUC__) && __GNUC__ >= 13
    723   #define BL_ASSUME(...) __attribute__((__assume__(__VA_ARGS__)))
    724 #elif defined(__GNUC__)
    725   #define BL_ASSUME(...) do { if (!(__VA_ARGS__)) __builtin_unreachable(); } while (0)
    726 #elif defined(_MSC_VER)
    727   #define BL_ASSUME(...) __assume(__VA_ARGS__)
    728 #else
    729   #define BL_ASSUME(...) (void)0
    730 #endif
    731 
    732 //! \def BL_LIKELY(...)
    733 //!
    734 //! A condition is likely.
    735 
    736 //! \def BL_UNLIKELY(...)
    737 //!
    738 //! A condition is unlikely.
    739 
    740 #if defined(__GNUC__)
    741   #define BL_LIKELY(...) __builtin_expect(!!(__VA_ARGS__), 1)
    742   #define BL_UNLIKELY(...) __builtin_expect(!!(__VA_ARGS__), 0)
    743 #else
    744   #define BL_LIKELY(...) (__VA_ARGS__)
    745   #define BL_UNLIKELY(...) (__VA_ARGS__)
    746 #endif
    747 
    748 //! \}
    749 
    750 //! \name Debugging and Error Handling
    751 //! \{
    752 
    753 //! \def BL_ASSERT(EXP)
    754 //!
    755 //! Run-time assertion executed in debug builds.
    756 #ifdef BL_BUILD_DEBUG
    757   #define BL_ASSERT(EXP)                                                      \
    758     do {                                                                      \
    759       if (BL_UNLIKELY(!(EXP))) {                                              \
    760         bl_runtime_assertion_failure(__FILE__, __LINE__, #EXP);                  \
    761       }                                                                       \
    762     } while (0)
    763 #else
    764   #define BL_ASSERT(EXP) ((void)0)
    765 #endif
    766 
    767 //! Executes the code within the macro, which is expected to provide a \ref BLResult, which is returned in case that it
    768 //! is not successful (not equal to \ref BL_SUCCESS). This macro is heavily used across the library for error handling
    769 //! and it's also exposed to end users in case they find comfortable using the same error handling technique to handle
    770 //! errors returned by Blend2D or user code returning \ref BLResult.
    771 #define BL_PROPAGATE(...)                                                     \
    772   do {                                                                        \
    773     BLResult result_to_propagate = (__VA_ARGS__);                               \
    774     if (BL_UNLIKELY(result_to_propagate)) {                                     \
    775       return result_to_propagate;                                               \
    776     }                                                                         \
    777   } while (0)
    778 
    779 //! \}
    780 
    781 //! \name Utilities
    782 //! \{
    783 
    784 //! Creates a 32-bit tag (uint32_t) from the given `A`, `B`, `C`, and `D` values.
    785 #define BL_MAKE_TAG(A, B, C, D) ((BLTag)(((BLTag)(A) << 24) | ((BLTag)(B) << 16) | ((BLTag)(C) << 8) | ((BLTag)(D))))
    786 
    787 //! \}
    788 
    789 //! \cond INTERNAL
    790 //! \name Internals
    791 //! \{
    792 
    793 //! \def BL_DEFINE_ENUM(NAME)
    794 //!
    795 //! Defines an enumeration used by Blend2D that is `uint32_t`.
    796 
    797 //! \def BL_FORCE_ENUM_UINT32(ENUM_VALUE_PREFIX)
    798 //!
    799 //! Forces an enumeration to be represented as 32-bit unsigned integer.
    800 //!
    801 //! This must be used in public C API, because when compiled by a C compiler (not C++ compiler) the enums won't
    802 //! have type information (it's a C++ feature). So this macro adds an additional enum value that would force the
    803 //! C compiler to make the type unsigned and at 32-bit.
    804 
    805 //! \}
    806 //! \endcond
    807 
    808 #ifdef __cplusplus
    809   #define BL_DEFINE_CONST static constexpr
    810   #define BL_DEFINE_ENUM(NAME) enum NAME : uint32_t
    811   #define BL_FORCE_ENUM_UINT32(ENUM_VALUE_PREFIX)
    812 #else
    813   #define BL_DEFINE_CONST static const
    814   #define BL_DEFINE_ENUM(NAME) typedef enum NAME NAME; enum NAME
    815   #define BL_FORCE_ENUM_UINT32(ENUM_VALUE_PREFIX) ,ENUM_VALUE_PREFIX##_FORCE_UINT = 0xFFFFFFFFu
    816 #endif
    817 
    818 //! \cond INTERNAL
    819 //! \name Internals
    820 //! \{
    821 
    822 //! \def BL_BEGIN_C_DECLS
    823 //! Begins C declarations scope when compiling with a C++ compiler.
    824 
    825 //! \def BL_END_C_DECLS
    826 //! Ends C declarations scope when compiling with a C++ compiler.
    827 
    828 //! \}
    829 //! \endcond
    830 
    831 #ifdef __cplusplus
    832   #define BL_BEGIN_C_DECLS extern "C" {
    833   #define BL_END_C_DECLS } /* {ExternC} */
    834 #else
    835   #define BL_BEGIN_C_DECLS
    836   #define BL_END_C_DECLS
    837 #endif
    838 
    839 //! \cond INTERNAL
    840 //! \name Compiler Diagnostics
    841 //! \{
    842 
    843 // Diagnostic warnings can be turned on/off by using pragmas, however, this is a compiler specific stuff we have to
    844 // maintain for each compiler. Ideally we should have a clean code that would compiler without any warnings with all
    845 // of them enabled by default, but since there is a lot of nitpicks we just disable some locally when needed (like
    846 // unused parameter in null-impl functions, etc).
    847 #if defined(__clang__)
    848   #define BL_DIAGNOSTIC_PUSH(...)              _Pragma("clang diagnostic push") __VA_ARGS__
    849   #define BL_DIAGNOSTIC_POP                    _Pragma("clang diagnostic pop")
    850   #define BL_DIAGNOSTIC_NO_UNUSED_PARAMETERS   _Pragma("clang diagnostic ignored \"-Wunused-parameter\"")
    851   #define BL_DIAGNOSTIC_NO_EXTRA_WARNINGS      _Pragma("clang diagnostic ignored \"-Wextra\"")
    852 #elif defined(__GNUC__)
    853   #define BL_DIAGNOSTIC_PUSH(...)              _Pragma("GCC diagnostic push") __VA_ARGS__
    854   #define BL_DIAGNOSTIC_POP                    _Pragma("GCC diagnostic pop")
    855   #define BL_DIAGNOSTIC_NO_UNUSED_PARAMETERS   _Pragma("GCC diagnostic ignored \"-Wunused-parameter\"")
    856   #define BL_DIAGNOSTIC_NO_EXTRA_WARNINGS      _Pragma("GCC diagnostic ignored \"-Wextra\"")
    857 #elif defined(_MSC_VER)
    858   #define BL_DIAGNOSTIC_PUSH(...)              __pragma(warning(push)) __VA_ARGS__
    859   #define BL_DIAGNOSTIC_POP                    __pragma(warning(pop))
    860   #define BL_DIAGNOSTIC_NO_UNUSED_PARAMETERS   __pragma(warning(disable: 4100))
    861   #define BL_DIAGNOSTIC_NO_EXTRA_WARNINGS
    862 #endif
    863 
    864 #if !defined(BL_DIAGNOSTIC_PUSH)
    865   #define BL_DIAGNOSTIC_PUSH(...)
    866   #define BL_DIAGNOSTIC_POP
    867   #define BL_DIAGNOSTIC_NO_UNUSED_PARAMETERS
    868   #define BL_DIAGNOSTIC_NO_EXTRA_WARNINGS
    869 #endif
    870 
    871 //! \}
    872 //! \endcond
    873 
    874 //! \}
    875 
    876 // Forward Declarations
    877 // ====================
    878 
    879 #ifdef __cplusplus
    880   #define BL_FORWARD_DECLARE_STRUCT(NAME) struct NAME
    881 #else
    882   #define BL_FORWARD_DECLARE_STRUCT(NAME) typedef struct NAME NAME
    883 #endif
    884 
    885 #ifdef __cplusplus
    886   #define BL_FORWARD_DECLARE_UNION(NAME) union NAME
    887 #else
    888   #define BL_FORWARD_DECLARE_UNION(NAME) typedef union NAME NAME
    889 #endif
    890 
    891 #ifdef __cplusplus
    892   #define BL_FORWARD_DECLARE_ENUM(NAME) enum NAME : uint32_t
    893 #else
    894   #define BL_FORWARD_DECLARE_ENUM(NAME) typedef enum NAME NAME
    895 #endif
    896 
    897 BL_FORWARD_DECLARE_STRUCT(BLRange);
    898 BL_FORWARD_DECLARE_STRUCT(BLRandom);
    899 BL_FORWARD_DECLARE_STRUCT(BLFileCore);
    900 BL_FORWARD_DECLARE_STRUCT(BLFileInfo);
    901 
    902 BL_FORWARD_DECLARE_STRUCT(BLRuntimeScopeCore);
    903 BL_FORWARD_DECLARE_STRUCT(BLRuntimeBuildInfo);
    904 BL_FORWARD_DECLARE_STRUCT(BLRuntimeSystemInfo);
    905 BL_FORWARD_DECLARE_STRUCT(BLRuntimeResourceInfo);
    906 
    907 BL_FORWARD_DECLARE_STRUCT(BLRgba);
    908 BL_FORWARD_DECLARE_STRUCT(BLRgba32);
    909 BL_FORWARD_DECLARE_STRUCT(BLRgba64);
    910 
    911 BL_FORWARD_DECLARE_STRUCT(BLPoint);
    912 BL_FORWARD_DECLARE_STRUCT(BLPointI);
    913 BL_FORWARD_DECLARE_STRUCT(BLSize);
    914 BL_FORWARD_DECLARE_STRUCT(BLSizeI);
    915 BL_FORWARD_DECLARE_STRUCT(BLBox);
    916 BL_FORWARD_DECLARE_STRUCT(BLBoxI);
    917 BL_FORWARD_DECLARE_STRUCT(BLRect);
    918 BL_FORWARD_DECLARE_STRUCT(BLRectI);
    919 BL_FORWARD_DECLARE_STRUCT(BLLine);
    920 BL_FORWARD_DECLARE_STRUCT(BLTriangle);
    921 BL_FORWARD_DECLARE_STRUCT(BLRoundRect);
    922 BL_FORWARD_DECLARE_STRUCT(BLCircle);
    923 BL_FORWARD_DECLARE_STRUCT(BLEllipse);
    924 BL_FORWARD_DECLARE_STRUCT(BLArc);
    925 
    926 BL_FORWARD_DECLARE_STRUCT(BLMatrix2D);
    927 BL_FORWARD_DECLARE_STRUCT(BLApproximationOptions);
    928 BL_FORWARD_DECLARE_STRUCT(BLStrokeOptionsCore);
    929 
    930 BL_FORWARD_DECLARE_STRUCT(BLFormatInfo);
    931 
    932 BL_FORWARD_DECLARE_STRUCT(BLObjectCore);
    933 BL_FORWARD_DECLARE_STRUCT(BLObjectImpl);
    934 BL_FORWARD_DECLARE_STRUCT(BLObjectVirt);
    935 BL_FORWARD_DECLARE_STRUCT(BLObjectVirtBase);
    936 BL_FORWARD_DECLARE_STRUCT(BLObjectInfo);
    937 BL_FORWARD_DECLARE_UNION(BLObjectDetail);
    938 
    939 BL_FORWARD_DECLARE_STRUCT(BLArrayCore);
    940 BL_FORWARD_DECLARE_STRUCT(BLArrayImpl);
    941 
    942 BL_FORWARD_DECLARE_STRUCT(BLBitArrayCore);
    943 BL_FORWARD_DECLARE_STRUCT(BLBitArrayImpl);
    944 
    945 BL_FORWARD_DECLARE_STRUCT(BLBitSetCore);
    946 BL_FORWARD_DECLARE_STRUCT(BLBitSetData);
    947 BL_FORWARD_DECLARE_STRUCT(BLBitSetImpl);
    948 BL_FORWARD_DECLARE_STRUCT(BLBitSetSegment);
    949 BL_FORWARD_DECLARE_STRUCT(BLBitSetBuilderCore);
    950 
    951 BL_FORWARD_DECLARE_STRUCT(BLStringCore);
    952 BL_FORWARD_DECLARE_STRUCT(BLStringImpl);
    953 
    954 BL_FORWARD_DECLARE_STRUCT(BLPathCore);
    955 BL_FORWARD_DECLARE_STRUCT(BLPathImpl);
    956 BL_FORWARD_DECLARE_STRUCT(BLPathView);
    957 
    958 BL_FORWARD_DECLARE_STRUCT(BLImageData);
    959 BL_FORWARD_DECLARE_STRUCT(BLImageInfo);
    960 
    961 BL_FORWARD_DECLARE_STRUCT(BLImageCore);
    962 BL_FORWARD_DECLARE_STRUCT(BLImageImpl);
    963 
    964 BL_FORWARD_DECLARE_STRUCT(BLImageCodecCore);
    965 BL_FORWARD_DECLARE_STRUCT(BLImageCodecImpl);
    966 BL_FORWARD_DECLARE_STRUCT(BLImageCodecVirt);
    967 
    968 BL_FORWARD_DECLARE_STRUCT(BLImageDecoderCore);
    969 BL_FORWARD_DECLARE_STRUCT(BLImageDecoderImpl);
    970 BL_FORWARD_DECLARE_STRUCT(BLImageDecoderVirt);
    971 
    972 BL_FORWARD_DECLARE_STRUCT(BLImageEncoderCore);
    973 BL_FORWARD_DECLARE_STRUCT(BLImageEncoderImpl);
    974 BL_FORWARD_DECLARE_STRUCT(BLImageEncoderVirt);
    975 
    976 BL_FORWARD_DECLARE_STRUCT(BLPixelConverterCore);
    977 BL_FORWARD_DECLARE_STRUCT(BLPixelConverterOptions);
    978 
    979 BL_FORWARD_DECLARE_STRUCT(BLGradientCore);
    980 BL_FORWARD_DECLARE_STRUCT(BLGradientImpl);
    981 BL_FORWARD_DECLARE_STRUCT(BLGradientStop);
    982 
    983 BL_FORWARD_DECLARE_STRUCT(BLLinearGradientValues);
    984 BL_FORWARD_DECLARE_STRUCT(BLRadialGradientValues);
    985 BL_FORWARD_DECLARE_STRUCT(BLConicGradientValues);
    986 
    987 BL_FORWARD_DECLARE_STRUCT(BLPatternCore);
    988 BL_FORWARD_DECLARE_STRUCT(BLPatternImpl);
    989 
    990 BL_FORWARD_DECLARE_STRUCT(BLContextCookie);
    991 BL_FORWARD_DECLARE_STRUCT(BLContextCreateInfo);
    992 BL_FORWARD_DECLARE_STRUCT(BLContextHints);
    993 BL_FORWARD_DECLARE_STRUCT(BLContextState);
    994 
    995 BL_FORWARD_DECLARE_STRUCT(BLContextCore);
    996 BL_FORWARD_DECLARE_STRUCT(BLContextImpl);
    997 BL_FORWARD_DECLARE_STRUCT(BLContextVirt);
    998 
    999 BL_FORWARD_DECLARE_STRUCT(BLGlyphBufferCore);
   1000 BL_FORWARD_DECLARE_STRUCT(BLGlyphBufferImpl);
   1001 BL_FORWARD_DECLARE_STRUCT(BLGlyphInfo);
   1002 BL_FORWARD_DECLARE_STRUCT(BLGlyphMappingState);
   1003 BL_FORWARD_DECLARE_STRUCT(BLGlyphOutlineSinkInfo);
   1004 BL_FORWARD_DECLARE_STRUCT(BLGlyphPlacement);
   1005 BL_FORWARD_DECLARE_STRUCT(BLGlyphRun);
   1006 
   1007 BL_FORWARD_DECLARE_STRUCT(BLFontCoverageInfo);
   1008 BL_FORWARD_DECLARE_STRUCT(BLFontFaceInfo);
   1009 BL_FORWARD_DECLARE_STRUCT(BLFontQueryProperties);
   1010 BL_FORWARD_DECLARE_STRUCT(BLFontFeatureItem);
   1011 BL_FORWARD_DECLARE_STRUCT(BLFontFeatureSettingsCore);
   1012 BL_FORWARD_DECLARE_STRUCT(BLFontFeatureSettingsImpl);
   1013 BL_FORWARD_DECLARE_STRUCT(BLFontFeatureSettingsView);
   1014 BL_FORWARD_DECLARE_STRUCT(BLFontDesignMetrics);
   1015 BL_FORWARD_DECLARE_STRUCT(BLFontMatrix);
   1016 BL_FORWARD_DECLARE_STRUCT(BLFontMetrics);
   1017 BL_FORWARD_DECLARE_STRUCT(BLFontPanoseInfo);
   1018 BL_FORWARD_DECLARE_STRUCT(BLFontTable);
   1019 BL_FORWARD_DECLARE_STRUCT(BLFontVariationItem);
   1020 BL_FORWARD_DECLARE_STRUCT(BLFontVariationSettingsCore);
   1021 BL_FORWARD_DECLARE_STRUCT(BLFontVariationSettingsImpl);
   1022 BL_FORWARD_DECLARE_STRUCT(BLFontVariationSettingsView);
   1023 BL_FORWARD_DECLARE_STRUCT(BLTextMetrics);
   1024 
   1025 BL_FORWARD_DECLARE_STRUCT(BLFontCore);
   1026 BL_FORWARD_DECLARE_STRUCT(BLFontImpl);
   1027 
   1028 BL_FORWARD_DECLARE_STRUCT(BLFontDataCore);
   1029 BL_FORWARD_DECLARE_STRUCT(BLFontDataImpl);
   1030 BL_FORWARD_DECLARE_STRUCT(BLFontDataVirt);
   1031 
   1032 BL_FORWARD_DECLARE_STRUCT(BLFontFaceCore);
   1033 BL_FORWARD_DECLARE_STRUCT(BLFontFaceImpl);
   1034 BL_FORWARD_DECLARE_STRUCT(BLFontFaceVirt);
   1035 
   1036 BL_FORWARD_DECLARE_STRUCT(BLFontManagerCore);
   1037 BL_FORWARD_DECLARE_STRUCT(BLFontManagerImpl);
   1038 BL_FORWARD_DECLARE_STRUCT(BLFontManagerVirt);
   1039 
   1040 BL_FORWARD_DECLARE_STRUCT(BLVarCore);
   1041 
   1042 #undef BL_FORWARD_DECLARE_ENUM
   1043 #undef BL_FORWARD_DECLARE_UNION
   1044 #undef BL_FORWARD_DECLARE_STRUCT
   1045 
   1046 // C++ API.
   1047 #ifdef __cplusplus
   1048 class BLFile;
   1049 class BLRuntimeScope;
   1050 template<typename T> class BLArray;
   1051 class BLBitArray;
   1052 class BLBitSet;
   1053 template<uint32_t> class BLBitSetBuilderT;
   1054 class BLString;
   1055 class BLPath;
   1056 class BLStrokeOptions;
   1057 class BLImage;
   1058 class BLImageCodec;
   1059 class BLImageDecoder;
   1060 class BLImageEncoder;
   1061 class BLPattern;
   1062 class BLGradient;
   1063 class BLContext;
   1064 class BLPixelConverter;
   1065 class BLGlyphBuffer;
   1066 class BLGlyphRunIterator;
   1067 class BLFont;
   1068 class BLFontData;
   1069 class BLFontFace;
   1070 class BLFontFeatureSettings;
   1071 class BLFontManager;
   1072 class BLFontVariationSettings;
   1073 class BLVar;
   1074 #endif
   1075 
   1076 // Public Types
   1077 // ============
   1078 
   1079 //! \ingroup bl_globals
   1080 //!
   1081 //! Result code used by most Blend2D functions (32-bit unsigned integer).
   1082 //!
   1083 //! The \ref BLResultCode enumeration contains Blend2D result codes that contain Blend2D specific set of errors
   1084 //! and an extended set of errors that can come from WIN32 or POSIX APIs. Since the success result code is zero
   1085 //! it's recommended to use the following check to determine whether a call failed or not:
   1086 //!
   1087 //! ```
   1088 //! BLResult result = do_something();
   1089 //! if (result != BL_SUCCESS) {
   1090 //!   // `do_something()` failed...
   1091 //! }
   1092 //! ```
   1093 typedef uint32_t BLResult;
   1094 
   1095 //! \ingroup bl_globals
   1096 //!
   1097 //! Tag is a 32-bit integer consisting of 4 characters in the following format:
   1098 //!
   1099 //! ```
   1100 //! tag = ((a << 24) | (b << 16) | (c << 8) | d)
   1101 //! ```
   1102 //!
   1103 //! Tags are used extensively by OpenType fonts and other binary formats like PNG. In most cases TAGs should only
   1104 //! contain ASCII letters, digits, and spaces.
   1105 //!
   1106 //! Blend2D uses \ref BLTag in public and internal APIs to distinguish between a regular `uint32_t` and tag.
   1107 typedef uint32_t BLTag;
   1108 
   1109 //! \ingroup bl_globals
   1110 //!
   1111 //! Unique identifier that can be used for caching purposes.
   1112 //!
   1113 //! Some objects such as \ref BLImage and \ref BLFontFace have assigned an unique identifier that can be used to
   1114 //! identify such objects for caching purposes. This identifier is never zero, so zero can be safely used as
   1115 //! "uncached".
   1116 //!
   1117 //! \note Unique identifier is per-process. It's implemented as an increasing global or thread-local counter in
   1118 //! a way that identifiers would not collide.
   1119 typedef uint64_t BLUniqueId;
   1120 
   1121 //! \ingroup bl_globals
   1122 //!
   1123 //! BLUnknown is `void` - it's used in places that accept pointer to \ref BLVarCore or any \ref BLObjectCore
   1124 //! compatible object.
   1125 typedef void BLUnknown;
   1126 
   1127 //! \ingroup bl_globals
   1128 //!
   1129 //! A sink that can be used to debug various parts of Blend2D.
   1130 typedef void (BL_CDECL* BLDebugMessageSinkFunc)(const char* message, size_t size, void* user_data) BL_NOEXCEPT_C;
   1131 
   1132 // Public Constants
   1133 // ================
   1134 
   1135 //! \ingroup bl_globals
   1136 //!
   1137 //! Blend2D result code.
   1138 BL_DEFINE_ENUM(BLResultCode) {
   1139   //! Successful result code.
   1140   BL_SUCCESS = 0,
   1141 
   1142   BL_ERROR_START_INDEX = 0x00010000u,
   1143 
   1144   BL_ERROR_OUT_OF_MEMORY = 0x00010000u,  //!< Out of memory                 [ENOMEM].
   1145   BL_ERROR_INVALID_VALUE,                //!< Invalid value/argument        [EINVAL].
   1146   BL_ERROR_INVALID_STATE,                //!< Invalid state                 [EFAULT].
   1147   BL_ERROR_INVALID_HANDLE,               //!< Invalid handle or file.       [EBADF].
   1148   BL_ERROR_INVALID_CONVERSION,           //!< Invalid conversion.
   1149   BL_ERROR_OVERFLOW,                     //!< Overflow or value too large   [EOVERFLOW].
   1150   BL_ERROR_NOT_INITIALIZED,              //!< Object not initialized.
   1151   BL_ERROR_NOT_IMPLEMENTED,              //!< Not implemented               [ENOSYS].
   1152   BL_ERROR_NOT_PERMITTED,                //!< Operation not permitted       [EPERM].
   1153 
   1154   BL_ERROR_IO,                           //!< IO error                      [EIO].
   1155   BL_ERROR_BUSY,                         //!< Device or resource busy       [EBUSY].
   1156   BL_ERROR_INTERRUPTED,                  //!< Operation interrupted         [EINTR].
   1157   BL_ERROR_TRY_AGAIN,                    //!< Try again                     [EAGAIN].
   1158   BL_ERROR_TIMED_OUT,                    //!< Timed out                     [ETIMEDOUT].
   1159   BL_ERROR_BROKEN_PIPE,                  //!< Broken pipe                   [EPIPE].
   1160   BL_ERROR_INVALID_SEEK,                 //!< File is not seekable          [ESPIPE].
   1161   BL_ERROR_SYMLINK_LOOP,                 //!< Too many levels of symlinks   [ELOOP].
   1162   BL_ERROR_FILE_TOO_LARGE,               //!< File is too large             [EFBIG].
   1163   BL_ERROR_ALREADY_EXISTS,               //!< File/directory already exists [EEXIST].
   1164   BL_ERROR_ACCESS_DENIED,                //!< Access denied                 [EACCES].
   1165   BL_ERROR_MEDIA_CHANGED,                //!< Media changed                 [Windows::ERROR_MEDIA_CHANGED].
   1166   BL_ERROR_READ_ONLY_FS,                 //!< The file/FS is read-only      [EROFS].
   1167   BL_ERROR_NO_DEVICE,                    //!< Device doesn't exist          [ENXIO].
   1168   BL_ERROR_NO_ENTRY,                     //!< Not found, no entry (fs)      [ENOENT].
   1169   BL_ERROR_NO_MEDIA,                     //!< No media in drive/device      [ENOMEDIUM].
   1170   BL_ERROR_NO_MORE_DATA,                 //!< No more data / end of file    [ENODATA].
   1171   BL_ERROR_NO_MORE_FILES,                //!< No more files                 [ENMFILE].
   1172   BL_ERROR_NO_SPACE_LEFT,                //!< No space left on device       [ENOSPC].
   1173   BL_ERROR_NOT_EMPTY,                    //!< Directory is not empty        [ENOTEMPTY].
   1174   BL_ERROR_NOT_FILE,                     //!< Not a file                    [EISDIR].
   1175   BL_ERROR_NOT_DIRECTORY,                //!< Not a directory               [ENOTDIR].
   1176   BL_ERROR_NOT_SAME_DEVICE,              //!< Not same device               [EXDEV].
   1177   BL_ERROR_NOT_BLOCK_DEVICE,             //!< Not a block device            [ENOTBLK].
   1178 
   1179   BL_ERROR_INVALID_FILE_NAME,            //!< File/path name is invalid     [n/a].
   1180   BL_ERROR_FILE_NAME_TOO_LONG,           //!< File/path name is too long    [ENAMETOOLONG].
   1181 
   1182   BL_ERROR_TOO_MANY_OPEN_FILES,          //!< Too many open files           [EMFILE].
   1183   BL_ERROR_TOO_MANY_OPEN_FILES_BY_OS,    //!< Too many open files by OS     [ENFILE].
   1184   BL_ERROR_TOO_MANY_LINKS,               //!< Too many symbolic links on FS [EMLINK].
   1185   BL_ERROR_TOO_MANY_THREADS,             //!< Too many threads              [EAGAIN].
   1186   BL_ERROR_THREAD_POOL_EXHAUSTED,        //!< Thread pool is exhausted and couldn't acquire the requested thread count.
   1187 
   1188   BL_ERROR_FILE_EMPTY,                   //!< File is empty (not specific to any OS error).
   1189   BL_ERROR_OPEN_FAILED,                  //!< File open failed              [Windows::ERROR_OPEN_FAILED].
   1190   BL_ERROR_NOT_ROOT_DEVICE,              //!< Not a root device/directory   [Windows::ERROR_DIR_NOT_ROOT].
   1191 
   1192   BL_ERROR_UNKNOWN_SYSTEM_ERROR,         //!< Unknown system error that failed to translate to Blend2D result code.
   1193 
   1194   BL_ERROR_INVALID_ALIGNMENT,            //!< Invalid data alignment.
   1195   BL_ERROR_INVALID_SIGNATURE,            //!< Invalid data signature or header.
   1196   BL_ERROR_INVALID_DATA,                 //!< Invalid or corrupted data.
   1197   BL_ERROR_INVALID_STRING,               //!< Invalid string (invalid data of either UTF8, UTF16, or UTF32).
   1198   BL_ERROR_INVALID_KEY,                  //!< Invalid key or property.
   1199   BL_ERROR_DATA_TRUNCATED,               //!< Truncated data (more data required than memory/stream provides).
   1200   BL_ERROR_DATA_TOO_LARGE,               //!< Input data too large to be processed.
   1201   BL_ERROR_DECOMPRESSION_FAILED,         //!< Decompression failed due to invalid data (RLE, Huffman, etc).
   1202 
   1203   BL_ERROR_INVALID_GEOMETRY,             //!< Invalid geometry (invalid path data or shape).
   1204   BL_ERROR_NO_MATCHING_VERTEX,           //!< Returned when there is no matching vertex in path data.
   1205 
   1206   BL_ERROR_INVALID_CREATE_FLAGS,         //!< Invalid create flags (BLContext).
   1207   BL_ERROR_NO_MATCHING_COOKIE,           //!< No matching cookie (BLContext).
   1208   BL_ERROR_NO_STATES_TO_RESTORE,         //!< No states to restore (BLContext).
   1209   BL_ERROR_TOO_MANY_SAVED_STATES,        //!< Cannot save state as the number of saved states reached the limit (BLContext).
   1210 
   1211   BL_ERROR_IMAGE_TOO_LARGE,              //!< The size of the image is too large.
   1212   BL_ERROR_IMAGE_NO_MATCHING_CODEC,      //!< Image codec for a required format doesn't exist.
   1213   BL_ERROR_IMAGE_UNKNOWN_FILE_FORMAT,    //!< Unknown or invalid file format that cannot be read.
   1214   BL_ERROR_IMAGE_DECODER_NOT_PROVIDED,   //!< Image codec doesn't support reading the file format.
   1215   BL_ERROR_IMAGE_ENCODER_NOT_PROVIDED,   //!< Image codec doesn't support writing the file format.
   1216 
   1217   BL_ERROR_PNG_MULTIPLE_IHDR,            //!< Multiple IHDR chunks are not allowed (PNG).
   1218   BL_ERROR_PNG_INVALID_IDAT,             //!< Invalid IDAT chunk (PNG).
   1219   BL_ERROR_PNG_INVALID_IEND,             //!< Invalid IEND chunk (PNG).
   1220   BL_ERROR_PNG_INVALID_PLTE,             //!< Invalid PLTE chunk (PNG).
   1221   BL_ERROR_PNG_INVALID_TRNS,             //!< Invalid tRNS chunk (PNG).
   1222   BL_ERROR_PNG_INVALID_FILTER,           //!< Invalid filter type (PNG).
   1223 
   1224   BL_ERROR_JPEG_UNSUPPORTED_FEATURE,     //!< Unsupported feature (JPEG).
   1225   BL_ERROR_JPEG_INVALID_SOS,             //!< Invalid SOS marker or header (JPEG).
   1226   BL_ERROR_JPEG_INVALID_SOF,             //!< Invalid SOF marker (JPEG).
   1227   BL_ERROR_JPEG_MULTIPLE_SOF,            //!< Multiple SOF markers (JPEG).
   1228   BL_ERROR_JPEG_UNSUPPORTED_SOF,         //!< Unsupported SOF marker (JPEG).
   1229 
   1230   BL_ERROR_FONT_NOT_INITIALIZED,         //!< Font doesn't have any data as it's not initialized.
   1231   BL_ERROR_FONT_NO_MATCH,                //!< Font or font face was not matched (BLFontManager).
   1232   BL_ERROR_FONT_NO_CHARACTER_MAPPING,    //!< Font has no character to glyph mapping data.
   1233   BL_ERROR_FONT_MISSING_IMPORTANT_TABLE, //!< Font has missing an important table.
   1234   BL_ERROR_FONT_FEATURE_NOT_AVAILABLE,   //!< Font feature is not available.
   1235   BL_ERROR_FONT_CFF_INVALID_DATA,        //!< Font has an invalid CFF data.
   1236   BL_ERROR_FONT_PROGRAM_TERMINATED,      //!< Font program terminated because the execution reached the limit.
   1237   BL_ERROR_GLYPH_SUBSTITUTION_TOO_LARGE, //!< Glyph substitution requires too much space and was terminated.
   1238 
   1239   BL_ERROR_INVALID_GLYPH                 //!< Invalid glyph identifier.
   1240 
   1241   BL_FORCE_ENUM_UINT32(BL_ERROR)
   1242 };
   1243 
   1244 //! \ingroup bl_globals
   1245 //!
   1246 //! Byte order.
   1247 BL_DEFINE_ENUM(BLByteOrder) {
   1248   //! Little endian byte-order.
   1249   BL_BYTE_ORDER_LE = 0,
   1250   //! Big endian byte-order.
   1251   BL_BYTE_ORDER_BE = 1,
   1252 
   1253   //! Native (host) byte-order.
   1254   BL_BYTE_ORDER_NATIVE = BL_BYTE_ORDER == 1234 ? BL_BYTE_ORDER_LE : BL_BYTE_ORDER_BE,
   1255   //! Swapped byte-order (BE if host is LE and vice versa).
   1256   BL_BYTE_ORDER_SWAPPED = BL_BYTE_ORDER == 1234 ? BL_BYTE_ORDER_BE : BL_BYTE_ORDER_LE
   1257 
   1258   BL_FORCE_ENUM_UINT32(BL_BYTE_ORDER)
   1259 };
   1260 
   1261 //! \ingroup bl_globals
   1262 //!
   1263 //! Data access flags.
   1264 BL_DEFINE_ENUM(BLDataAccessFlags) {
   1265   //! No data access flags.
   1266   BL_DATA_ACCESS_NO_FLAGS = 0x00u,
   1267   //! Read access.
   1268   BL_DATA_ACCESS_READ = 0x01u,
   1269   //! Write access.
   1270   BL_DATA_ACCESS_WRITE = 0x02u,
   1271   //! Read and write access.
   1272   BL_DATA_ACCESS_RW = 0x03u
   1273 
   1274   BL_FORCE_ENUM_UINT32(BL_DATA_ACCESS)
   1275 };
   1276 
   1277 //! \ingroup bl_globals
   1278 //!
   1279 //! Data source type.
   1280 BL_DEFINE_ENUM(BLDataSourceType) {
   1281   //! No data source.
   1282   BL_DATA_SOURCE_TYPE_NONE = 0,
   1283   //! Memory data source.
   1284   BL_DATA_SOURCE_TYPE_MEMORY = 1,
   1285   //! File data source.
   1286   BL_DATA_SOURCE_TYPE_FILE = 2,
   1287   //! Custom data source.
   1288   BL_DATA_SOURCE_TYPE_CUSTOM = 3,
   1289 
   1290   //! Maximum value `BLDataSourceType`.
   1291   BL_DATA_SOURCE_TYPE_MAX_VALUE = 3
   1292 
   1293   BL_FORCE_ENUM_UINT32(BL_DATA_SOURCE_TYPE)
   1294 };
   1295 
   1296 //! \ingroup bl_globals
   1297 //!
   1298 //! Modification operation applied to Blend2D containers.
   1299 BL_DEFINE_ENUM(BLModifyOp) {
   1300   //! Assign operation, which reserves space only to fit the requested input.
   1301   BL_MODIFY_OP_ASSIGN_FIT = 0,
   1302   //! Assign operation, which takes into consideration successive appends.
   1303   BL_MODIFY_OP_ASSIGN_GROW = 1,
   1304   //! Append operation, which reserves space only to fit the current and appended content.
   1305   BL_MODIFY_OP_APPEND_FIT = 2,
   1306   //! Append operation, which takes into consideration successive appends.
   1307   BL_MODIFY_OP_APPEND_GROW = 3,
   1308 
   1309   //! Maximum value of `BLModifyOp`.
   1310   BL_MODIFY_OP_MAX_VALUE = 3
   1311 
   1312   BL_FORCE_ENUM_UINT32(BL_MODIFY_OP)
   1313 };
   1314 
   1315 //! \ingroup bl_globals
   1316 //!
   1317 //! Boolean operator.
   1318 BL_DEFINE_ENUM(BLBooleanOp) {
   1319   //! Result = B.
   1320   BL_BOOLEAN_OP_COPY = 0,
   1321   //! Result = A & B.
   1322   BL_BOOLEAN_OP_AND = 1,
   1323   //! Result = A | B.
   1324   BL_BOOLEAN_OP_OR = 2,
   1325   //! Result = A ^ B.
   1326   BL_BOOLEAN_OP_XOR = 3,
   1327   //! Result = A & ~B.
   1328   BL_BOOLEAN_OP_AND_NOT = 4,
   1329   //! Result = ~A & B.
   1330   BL_BOOLEAN_OP_NOT_AND = 5,
   1331 
   1332   //! Maximum value of `BLBooleanOp`.
   1333   BL_BOOLEAN_OP_MAX_VALUE = 5
   1334 
   1335   BL_FORCE_ENUM_UINT32(BL_BOOLEAN_OP)
   1336 };
   1337 
   1338 //! \ingroup bl_styling
   1339 //!
   1340 //! Extend mode.
   1341 BL_DEFINE_ENUM(BLExtendMode) {
   1342   //! Pad extend [default].
   1343   BL_EXTEND_MODE_PAD = 0,
   1344   //! Repeat extend.
   1345   BL_EXTEND_MODE_REPEAT = 1,
   1346   //! Reflect extend.
   1347   BL_EXTEND_MODE_REFLECT = 2,
   1348 
   1349   //! Alias of `BL_EXTEND_MODE_PAD`.
   1350   BL_EXTEND_MODE_PAD_X_PAD_Y = 0,
   1351   //! Pad X and repeat Y.
   1352   BL_EXTEND_MODE_PAD_X_REPEAT_Y = 3,
   1353   //! Pad X and reflect Y.
   1354   BL_EXTEND_MODE_PAD_X_REFLECT_Y = 4,
   1355 
   1356   //! Alias of `BL_EXTEND_MODE_REPEAT`.
   1357   BL_EXTEND_MODE_REPEAT_X_REPEAT_Y = 1,
   1358   //! Repeat X and pad Y.
   1359   BL_EXTEND_MODE_REPEAT_X_PAD_Y = 5,
   1360   //! Repeat X and reflect Y.
   1361   BL_EXTEND_MODE_REPEAT_X_REFLECT_Y = 6,
   1362 
   1363   //! Alias of `BL_EXTEND_MODE_REFLECT`.
   1364   BL_EXTEND_MODE_REFLECT_X_REFLECT_Y = 2,
   1365   //! Reflect X and pad Y.
   1366   BL_EXTEND_MODE_REFLECT_X_PAD_Y = 7,
   1367   //! Reflect X and repeat Y.
   1368   BL_EXTEND_MODE_REFLECT_X_REPEAT_Y = 8,
   1369 
   1370   //! Count of simple extend modes (that use the same value for X and Y).
   1371   BL_EXTEND_MODE_SIMPLE_MAX_VALUE = 2,
   1372   //! Count of complex extend modes (that can use independent values for X and Y).
   1373   BL_EXTEND_MODE_COMPLEX_MAX_VALUE = 8,
   1374 
   1375   //! Maximum value of `BLExtendMode`.
   1376   BL_EXTEND_MODE_MAX_VALUE = 8
   1377 
   1378   BL_FORCE_ENUM_UINT32(BL_EXTEND_MODE)
   1379 };
   1380 
   1381 //! \ingroup bl_text
   1382 //!
   1383 //! Text encoding.
   1384 BL_DEFINE_ENUM(BLTextEncoding) {
   1385   //! UTF-8 encoding.
   1386   BL_TEXT_ENCODING_UTF8 = 0,
   1387   //! UTF-16 encoding (native endian).
   1388   BL_TEXT_ENCODING_UTF16 = 1,
   1389   //! UTF-32 encoding (native endian).
   1390   BL_TEXT_ENCODING_UTF32 = 2,
   1391   //! LATIN1 encoding (one byte per character).
   1392   BL_TEXT_ENCODING_LATIN1 = 3,
   1393 
   1394   //! Platform native `wchar_t` (or Windows `WCHAR`) encoding, alias to
   1395   //! either UTF-32, UTF-16, or UTF-8 depending on `sizeof(wchar_t)`.
   1396   BL_TEXT_ENCODING_WCHAR
   1397     = sizeof(wchar_t) == 4 ? BL_TEXT_ENCODING_UTF32 :
   1398       sizeof(wchar_t) == 2 ? BL_TEXT_ENCODING_UTF16 : BL_TEXT_ENCODING_UTF8,
   1399 
   1400   //! Maximum value of `BLTextEncoding`.
   1401   BL_TEXT_ENCODING_MAX_VALUE = 3
   1402 
   1403   BL_FORCE_ENUM_UINT32(BL_TEXT_ENCODING)
   1404 };
   1405 
   1406 // Internal API
   1407 // ============
   1408 
   1409 #ifdef __cplusplus
   1410 //! \cond INTERNAL
   1411 
   1412 //! \ingroup blend2d_internal
   1413 //!
   1414 //! Internal namespace that should never be used by Blend2D users.
   1415 //!
   1416 //! This namespace provides functionality that is internally used by the public C++ API in public headers.
   1417 //! There should never be functionality that is not used by public headers, that should always be hidden.
   1418 namespace BLInternal {
   1419 
   1420 template<typename T>
   1421 [[nodiscard]]
   1422 BL_INLINE_NODEBUG std::remove_reference_t<T>&& move(T&& v) noexcept { return static_cast<std::remove_reference_t<T>&&>(v); }
   1423 
   1424 template<typename T>
   1425 [[nodiscard]]
   1426 BL_INLINE_NODEBUG T&& forward(std::remove_reference_t<T>& v) noexcept { return static_cast<T&&>(v); }
   1427 
   1428 template<typename T>
   1429 [[nodiscard]]
   1430 BL_INLINE_NODEBUG T&& forward(std::remove_reference_t<T>&& v) noexcept { return static_cast<T&&>(v); }
   1431 
   1432 template<typename T>
   1433 BL_INLINE void swap(T& t1, T& t2) noexcept {
   1434   T temp(move(t1));
   1435   t1 = move(t2);
   1436   t2 = move(temp);
   1437 }
   1438 
   1439 template<typename... Args>
   1440 [[nodiscard]]
   1441 BL_INLINE_CONSTEXPR bool bool_and(Args&&... args) noexcept { return bool( (... & unsigned(forward<Args>(args))) ); }
   1442 
   1443 template<typename... Args>
   1444 [[nodiscard]]
   1445 BL_INLINE_CONSTEXPR bool bool_or(Args&&... args) noexcept { return bool( (... | unsigned(forward<Args>(args))) ); }
   1446 
   1447 //! StdIntT provides a signed integer type as defined by <stdint.h> by size.
   1448 template<size_t kSize, bool kUnsigned = false> struct StdIntT;
   1449 
   1450 template<> struct StdIntT<1, false> { using Type = int8_t; };
   1451 template<> struct StdIntT<2, false> { using Type = int16_t; };
   1452 template<> struct StdIntT<4, false> { using Type = int32_t; };
   1453 template<> struct StdIntT<8, false> { using Type = int64_t; };
   1454 template<> struct StdIntT<1, true> { using Type = uint8_t; };
   1455 template<> struct StdIntT<2, true> { using Type = uint16_t; };
   1456 template<> struct StdIntT<4, true> { using Type = uint32_t; };
   1457 template<> struct StdIntT<8, true> { using Type = uint64_t; };
   1458 
   1459 template<size_t kSize, bool kUnsigned = false>
   1460 using IntBySize = typename StdIntT<kSize, kUnsigned>::Type;
   1461 
   1462 template<size_t kSize>
   1463 using UIntBySize = typename StdIntT<kSize, true>::Type;
   1464 
   1465 template<typename T, bool kUnsigned = false>
   1466 using IntByType = typename StdIntT<sizeof(T), kUnsigned>::Type;
   1467 
   1468 template<typename T>
   1469 using UIntByType = typename StdIntT<sizeof(T), 1>::Type;
   1470 
   1471 template<uint64_t kInput>
   1472 struct ConstCTZ {
   1473   static inline constexpr uint32_t kValue =
   1474     (kInput & (uint64_t(1) <<  0)) ?  0 : (kInput & (uint64_t(1) <<  1)) ?  1 :
   1475     (kInput & (uint64_t(1) <<  2)) ?  2 : (kInput & (uint64_t(1) <<  3)) ?  3 :
   1476     (kInput & (uint64_t(1) <<  4)) ?  4 : (kInput & (uint64_t(1) <<  5)) ?  5 :
   1477     (kInput & (uint64_t(1) <<  6)) ?  6 : (kInput & (uint64_t(1) <<  7)) ?  7 :
   1478     (kInput & (uint64_t(1) <<  8)) ?  8 : (kInput & (uint64_t(1) <<  9)) ?  9 :
   1479     (kInput & (uint64_t(1) << 10)) ? 10 : (kInput & (uint64_t(1) << 11)) ? 11 :
   1480     (kInput & (uint64_t(1) << 12)) ? 12 : (kInput & (uint64_t(1) << 13)) ? 13 :
   1481     (kInput & (uint64_t(1) << 14)) ? 14 : (kInput & (uint64_t(1) << 15)) ? 15 :
   1482     (kInput & (uint64_t(1) << 16)) ? 16 : (kInput & (uint64_t(1) << 17)) ? 17 :
   1483     (kInput & (uint64_t(1) << 18)) ? 18 : (kInput & (uint64_t(1) << 19)) ? 19 :
   1484     (kInput & (uint64_t(1) << 20)) ? 20 : (kInput & (uint64_t(1) << 21)) ? 21 :
   1485     (kInput & (uint64_t(1) << 22)) ? 22 : (kInput & (uint64_t(1) << 23)) ? 23 :
   1486     (kInput & (uint64_t(1) << 24)) ? 24 : (kInput & (uint64_t(1) << 25)) ? 25 :
   1487     (kInput & (uint64_t(1) << 26)) ? 26 : (kInput & (uint64_t(1) << 27)) ? 27 :
   1488     (kInput & (uint64_t(1) << 28)) ? 28 : (kInput & (uint64_t(1) << 29)) ? 29 :
   1489     (kInput & (uint64_t(1) << 30)) ? 30 : (kInput & (uint64_t(1) << 31)) ? 31 :
   1490     (kInput & (uint64_t(1) << 32)) ? 32 : (kInput & (uint64_t(1) << 33)) ? 33 :
   1491     (kInput & (uint64_t(1) << 34)) ? 34 : (kInput & (uint64_t(1) << 35)) ? 35 :
   1492     (kInput & (uint64_t(1) << 36)) ? 36 : (kInput & (uint64_t(1) << 37)) ? 37 :
   1493     (kInput & (uint64_t(1) << 38)) ? 38 : (kInput & (uint64_t(1) << 39)) ? 39 :
   1494     (kInput & (uint64_t(1) << 40)) ? 40 : (kInput & (uint64_t(1) << 41)) ? 41 :
   1495     (kInput & (uint64_t(1) << 42)) ? 42 : (kInput & (uint64_t(1) << 43)) ? 43 :
   1496     (kInput & (uint64_t(1) << 44)) ? 44 : (kInput & (uint64_t(1) << 45)) ? 45 :
   1497     (kInput & (uint64_t(1) << 46)) ? 46 : (kInput & (uint64_t(1) << 47)) ? 47 :
   1498     (kInput & (uint64_t(1) << 48)) ? 48 : (kInput & (uint64_t(1) << 49)) ? 49 :
   1499     (kInput & (uint64_t(1) << 50)) ? 50 : (kInput & (uint64_t(1) << 51)) ? 51 :
   1500     (kInput & (uint64_t(1) << 52)) ? 52 : (kInput & (uint64_t(1) << 53)) ? 53 :
   1501     (kInput & (uint64_t(1) << 54)) ? 54 : (kInput & (uint64_t(1) << 55)) ? 55 :
   1502     (kInput & (uint64_t(1) << 56)) ? 56 : (kInput & (uint64_t(1) << 57)) ? 57 :
   1503     (kInput & (uint64_t(1) << 58)) ? 58 : (kInput & (uint64_t(1) << 59)) ? 59 :
   1504     (kInput & (uint64_t(1) << 60)) ? 60 : (kInput & (uint64_t(1) << 61)) ? 61 :
   1505     (kInput & (uint64_t(1) << 62)) ? 62 : (kInput & (uint64_t(1) << 63)) ? 63 : 64;
   1506 };
   1507 
   1508 //! Type category.
   1509 //!
   1510 //! Provides type categorization for compile-time type reflection that can be used by templates.
   1511 enum TypeCategory : uint32_t {
   1512   //! Type is unknown.
   1513   kTypeCategoryUnknown = 0,
   1514   //! Type is a boolean (`bool`).
   1515   kTypeCategoryBool = 1,
   1516   //! Type is integral.
   1517   kTypeCategoryInt = 2,
   1518   //! Type is a floating point.
   1519   kTypeCategoryFloat = 3,
   1520   //! Type is a pointer.
   1521   kTypeCategoryPtr = 4,
   1522   //! Type is a structure.
   1523   kTypeCategoryStruct = 5,
   1524   //! Type is BLObject compatible.
   1525   kTypeCategoryObject = 6
   1526 };
   1527 
   1528 //! Type flags.
   1529 //!
   1530 //! Provides details about a categorized type.
   1531 enum TypeFlags : uint32_t {
   1532   //! Type has no flags.
   1533   kTypeNoFlags = 0x0000u,
   1534   //! Type is primitive (either bool, integer, or floating point).
   1535   kTypeFlagPrimitive = 0x0001u,
   1536   //! Type is `BLArrayCore` or `BLArray<T>`.
   1537   kTypeFlagArray = 0x0002u,
   1538   //! Type is `BLVarCore` or `BLVar`
   1539   kTypeFlagVar = 0x0004u,
   1540   //! Type is `BLxxxCore` - C API type.
   1541   kTypeFlagCore = 0x0008u,
   1542 
   1543   //! Type is `BLRgba`.
   1544   kTypeFlagRgba = 0x0010u,
   1545   //! Type is `BLRgba32`.
   1546   kTypeFlagRgba32 = 0x0020u,
   1547   //! Type is `BLRgba64`.
   1548   kTypeFlagRgba64 = 0x0040u,
   1549   //! Type is `BLGradient[Core]` or `BLPattern[Core]`.
   1550   kTypeFlagStyle = 0x0080u
   1551 };
   1552 
   1553 template<typename T>
   1554 struct TypeTraits {
   1555   static inline constexpr uint32_t kCategory =
   1556     std::is_pointer_v<T> ? kTypeCategoryPtr :
   1557     std::is_integral_v<T> ? kTypeCategoryInt :
   1558     std::is_floating_point_v<T> ? kTypeCategoryFloat : kTypeCategoryStruct;
   1559 
   1560   static inline constexpr uint32_t kFlags =
   1561     std::is_pointer_v<T> ? kTypeFlagPrimitive :
   1562     std::is_integral_v<T> ? kTypeFlagPrimitive :
   1563     std::is_floating_point_v<T> ? kTypeFlagPrimitive : kTypeNoFlags;
   1564 };
   1565 
   1566 template<>
   1567 struct TypeTraits<bool> {
   1568   static inline constexpr uint32_t kCategory = kTypeCategoryBool;
   1569   static inline constexpr uint32_t kFlags = kTypeFlagPrimitive;
   1570 };
   1571 
   1572 // BLArrayCore and BLArray<T> specialization.
   1573 template<>
   1574 struct TypeTraits<BLArrayCore> {
   1575   static inline constexpr uint32_t kCategory = kTypeCategoryObject;
   1576   static inline constexpr uint32_t kFlags = kTypeFlagArray | kTypeFlagCore;
   1577 };
   1578 
   1579 template<typename T>
   1580 struct TypeTraits<BLArray<T>> {
   1581   static inline constexpr uint32_t kCategory = kTypeCategoryObject;
   1582   static inline constexpr uint32_t kFlags = kTypeFlagArray;
   1583 };
   1584 
   1585 // Other types compatible with BLObjectCore.
   1586 #define BL_DEFINE_OBJECT_TRAITS(T, Flags)                             \
   1587   template<>                                                          \
   1588   struct TypeTraits<T##Core> {                                        \
   1589     static inline constexpr uint32_t kCategory = kTypeCategoryObject; \
   1590     static inline constexpr uint32_t kFlags = Flags | kTypeFlagCore;  \
   1591   };                                                                  \
   1592                                                                       \
   1593   template<>                                                          \
   1594   struct TypeTraits<T> {                                              \
   1595     static inline constexpr uint32_t kCategory = kTypeCategoryObject; \
   1596     static inline constexpr uint32_t kFlags = Flags;                  \
   1597   };
   1598 
   1599 BL_DEFINE_OBJECT_TRAITS(BLBitArray             , kTypeNoFlags)
   1600 BL_DEFINE_OBJECT_TRAITS(BLBitSet               , kTypeNoFlags)
   1601 BL_DEFINE_OBJECT_TRAITS(BLContext              , kTypeNoFlags)
   1602 BL_DEFINE_OBJECT_TRAITS(BLFont                 , kTypeNoFlags)
   1603 BL_DEFINE_OBJECT_TRAITS(BLFontData             , kTypeNoFlags)
   1604 BL_DEFINE_OBJECT_TRAITS(BLFontFace             , kTypeNoFlags)
   1605 BL_DEFINE_OBJECT_TRAITS(BLFontFeatureSettings  , kTypeNoFlags)
   1606 BL_DEFINE_OBJECT_TRAITS(BLFontManager          , kTypeNoFlags)
   1607 BL_DEFINE_OBJECT_TRAITS(BLFontVariationSettings, kTypeNoFlags)
   1608 BL_DEFINE_OBJECT_TRAITS(BLGradient             , kTypeFlagStyle)
   1609 BL_DEFINE_OBJECT_TRAITS(BLImage                , kTypeNoFlags)
   1610 BL_DEFINE_OBJECT_TRAITS(BLImageCodec           , kTypeNoFlags)
   1611 BL_DEFINE_OBJECT_TRAITS(BLImageDecoder         , kTypeNoFlags)
   1612 BL_DEFINE_OBJECT_TRAITS(BLImageEncoder         , kTypeNoFlags)
   1613 BL_DEFINE_OBJECT_TRAITS(BLPath                 , kTypeNoFlags)
   1614 BL_DEFINE_OBJECT_TRAITS(BLPattern              , kTypeFlagStyle)
   1615 BL_DEFINE_OBJECT_TRAITS(BLString               , kTypeNoFlags)
   1616 BL_DEFINE_OBJECT_TRAITS(BLVar                  , kTypeFlagVar)
   1617 
   1618 #undef BL_DEFINE_OBJECT_TRAITS
   1619 
   1620 //! Helper to implement placement new/delete without relying on `<new>` header.
   1621 struct PlacementNew { void* ptr; };
   1622 
   1623 } // {BLInternal}
   1624 
   1625 //! Implementation of a placement new so we don't have to depend on `<new>`.
   1626 BL_INLINE_NODEBUG void* operator new(size_t, const BLInternal::PlacementNew& p) {
   1627 #if defined(_MSC_VER) && !defined(__clang__)
   1628   BL_ASSUME(p.ptr != nullptr); // Otherwise MSVC would emit a nullptr check.
   1629 #endif
   1630   return p.ptr;
   1631 }
   1632 
   1633 BL_INLINE_NODEBUG void operator delete(void*, const BLInternal::PlacementNew&) noexcept {}
   1634 
   1635 //! \endcond
   1636 #endif
   1637 
   1638 // Public API - TraceError
   1639 // =======================
   1640 
   1641 //! \addtogroup bl_globals
   1642 //! \{
   1643 
   1644 //! \name Debugging Functionality
   1645 //! \{
   1646 
   1647 //! Returns the `result` passed.
   1648 //!
   1649 //! Provided for debugging purposes. Putting a breakpoint inside `bl_make_error()` can help with tracing an origin
   1650 //! of errors reported / returned by Blend2D as each error goes through this function.
   1651 //!
   1652 //! It's a zero-cost solution that doesn't affect release builds in any way.
   1653 #ifdef __cplusplus
   1654 [[nodiscard]]
   1655 #endif
   1656 static inline BLResult bl_make_error(BLResult result) BL_NOEXCEPT_C { return result; }
   1657 
   1658 BL_BEGIN_C_DECLS
   1659 
   1660 //! This function is called by Blend2D when an internal assertion failure happens.
   1661 //!
   1662 //! Failing an assertion means that there is either a bug in Blend2D or in user code that uses Blend2D and that the
   1663 //! state of the application is already corrupted and thus irrecoverable. Note that this would be a fatal error if
   1664 //! this function gets called in production.
   1665 BL_API BL_NORETURN void BL_CDECL bl_runtime_assertion_failure(const char* file, int line, const char* msg) BL_NOEXCEPT_C;
   1666 
   1667 BL_END_C_DECLS
   1668 
   1669 //! \}
   1670 //! \}
   1671 
   1672 // Public API - Templates
   1673 // ======================
   1674 
   1675 #ifdef __cplusplus
   1676 // These are the only global functions provided in C++ mode. They are needed by C++ API wrappers and can be used
   1677 // freely by Blend2D users as these templates have specializations for some geometry types. For example \ref bl_min()
   1678 // works with numbers as well as with \ref BLPoint.
   1679 
   1680 //! \addtogroup bl_globals
   1681 //! \{
   1682 
   1683 //! \name Explicit Construction & Destruction.
   1684 //!
   1685 //! These should be only necessary when extending Blend2D.
   1686 //!
   1687 //! \{
   1688 
   1689 //! Constructs an instance in place (calls its constructor) with optional `args`.
   1690 template<typename T, typename... Args>
   1691 static BL_INLINE void bl_call_ctor(T& instance, Args&&... args) noexcept {
   1692   // Only needed by MSVC as otherwise it could generate null-pointer check before calling the constructor. If the
   1693   // assumption is used with GCC or Clang it would emit a "-Wtautological-undefined-compare" warning so we really
   1694   // have to only enable this for compilers that don't have the necessary diagnostics to remove the nullptr check.
   1695 #if defined(_MSC_VER) && !defined(__clang__)
   1696   BL_ASSUME(&instance != nullptr);
   1697 #endif
   1698 
   1699   new(BLInternal::PlacementNew{&instance}) T(BLInternal::forward<Args>(args)...);
   1700 }
   1701 
   1702 //! Destroys an instance in place (calls its destructor).
   1703 template<typename T>
   1704 static BL_INLINE void bl_call_dtor(T& instance) noexcept {
   1705   // Only needed by MSVC as otherwise it could generate null-pointer check before calling the destructor. If the
   1706   // assumption is used with GCC or Clang it would emit a "-Wtautological-undefined-compare" warning so we really
   1707   // have to only enable this for compilers that don't have the necessary diagnostics to remove the nullptr check.
   1708 #if defined(_MSC_VER) && !defined(__clang__)
   1709   BL_ASSUME(&instance != nullptr);
   1710 #endif
   1711 
   1712   instance.~T();
   1713 }
   1714 
   1715 //! \}
   1716 
   1717 //! \name Global C++ Functions
   1718 //! \{
   1719 
   1720 //! Bit-cast `x` of `In` type to the given `Out` type.
   1721 //!
   1722 //! Useful to bit-cast between integers and floating points. The size of `Out` and `In` must be the same otherwise the
   1723 //! compilation would fail. Bit casting is used by \ref bl_equals() to implement bit equality for floating point types.
   1724 template<typename Out, typename In>
   1725 [[nodiscard]]
   1726 static BL_INLINE_NODEBUG Out bl_bit_cast(const In& x) noexcept {
   1727   static_assert(sizeof(Out) == sizeof(In),
   1728                 "The size of 'In' and 'Out' types must match");
   1729   union { In in; Out out; } u = { x };
   1730   return u.out;
   1731 }
   1732 
   1733 //! Returns an absolute value of `a`.
   1734 template<typename T>
   1735 [[nodiscard]]
   1736 BL_INLINE_CONSTEXPR T bl_abs(const T& a) noexcept { return T(a < T(0) ? -a : a); }
   1737 
   1738 //! Returns a minimum value of `a` and `b`.
   1739 template<typename T>
   1740 [[nodiscard]]
   1741 BL_INLINE_CONSTEXPR T bl_min(const T& a, const T& b) noexcept { return T(b < a ? b : a); }
   1742 
   1743 //! Returns a maximum value of `a` and `b`.
   1744 template<typename T>
   1745 [[nodiscard]]
   1746 BL_INLINE_CONSTEXPR T bl_max(const T& a, const T& b) noexcept { return T(a < b ? b : a); }
   1747 
   1748 //! Clamps `a` to a range defined as `[b, c]`.
   1749 template<typename T>
   1750 [[nodiscard]]
   1751 BL_INLINE_CONSTEXPR T bl_clamp(const T& a, const T& b, const T& c) noexcept { return bl_min(c, bl_max(b, a)); }
   1752 
   1753 //! Returns a minimum value of all arguments passed.
   1754 template<typename T, typename... Args>
   1755 [[nodiscard]]
   1756 BL_INLINE_CONSTEXPR T bl_min(const T& a, const T& b, Args&&... args) noexcept { return bl_min(bl_min(a, b), BLInternal::forward<Args>(args)...); }
   1757 
   1758 //! Returns a maximum value of all arguments passed.
   1759 template<typename T, typename... Args>
   1760 [[nodiscard]]
   1761 BL_INLINE_CONSTEXPR T bl_max(const T& a, const T& b, Args&&... args) noexcept { return bl_max(bl_max(a, b), BLInternal::forward<Args>(args)...); }
   1762 
   1763 //! Returns `true` if `a` and `b` equals at binary level.
   1764 //!
   1765 //! For example `bl_equals(NaN, NaN) == true`.
   1766 template<typename T>
   1767 [[nodiscard]]
   1768 BL_INLINE_NODEBUG bool bl_equals(const T& a, const T& b) noexcept { return a == b; }
   1769 
   1770 //! \cond NEVER
   1771 template<>
   1772 [[nodiscard]]
   1773 BL_INLINE_NODEBUG bool bl_equals(const float& a, const float& b) noexcept {
   1774   return bl_bit_cast<uint32_t>(a) == bl_bit_cast<uint32_t>(b);
   1775 }
   1776 
   1777 template<>
   1778 [[nodiscard]]
   1779 BL_INLINE_NODEBUG bool bl_equals(const double& a, const double& b) noexcept {
   1780   return bl_bit_cast<uint64_t>(a) == bl_bit_cast<uint64_t>(b);
   1781 }
   1782 //! \endcond
   1783 
   1784 //! \}
   1785 //! \}
   1786 #endif
   1787 
   1788 //! \addtogroup bl_containers
   1789 //! \{
   1790 
   1791 //! Provides start and end indexes. It has the same semantics as Slices in other programming languages - range is
   1792 //! always within [star, end) internal (start is inclusive, end is exclusive). It's used to specify a range of an
   1793 //! operation of indexed containers like \ref BLString, \ref BLArray, \ref BLGradient, \ref BLPath, etc...
   1794 struct BLRange {
   1795   size_t start;
   1796   size_t end;
   1797 
   1798 #ifdef __cplusplus
   1799   //! \name Construction & Destruction
   1800   //! \{
   1801 
   1802   [[nodiscard]]
   1803   static BL_INLINE_CONSTEXPR BLRange everything() noexcept { return BLRange{0, SIZE_MAX}; }
   1804 
   1805   //! \}
   1806 
   1807   //! \name Overloaded Operators
   1808   //! \{
   1809 
   1810   [[nodiscard]]
   1811   BL_INLINE_NODEBUG bool operator==(const BLRange& other) const noexcept { return equals(other); }
   1812 
   1813   [[nodiscard]]
   1814   BL_INLINE_NODEBUG bool operator!=(const BLRange& other) const noexcept { return !equals(other); }
   1815 
   1816   //! \}
   1817 
   1818   //! \name Common Functionality
   1819   //! \{
   1820 
   1821   //! Reset the range to [0, 0).
   1822   BL_INLINE_NODEBUG void reset() noexcept { *this = BLRange{}; }
   1823 
   1824   //! Reset the range to [start, end).
   1825   BL_INLINE_NODEBUG void reset(size_t r_start, size_t r_end) noexcept { *this = BLRange{r_start, r_end}; }
   1826 
   1827   //! \}
   1828 
   1829   //! \name Equality & Comparison
   1830   //! \{
   1831 
   1832   [[nodiscard]]
   1833   BL_INLINE_NODEBUG bool equals(const BLRange& other) const noexcept {
   1834     return BLInternal::bool_and(bl_equals(start, other.start),
   1835                                 bl_equals(end, other.end));
   1836   }
   1837 
   1838   //! \}
   1839 #endif
   1840 };
   1841 
   1842 #ifdef __cplusplus
   1843 
   1844 //! Array view of `T`.
   1845 //!
   1846 //! \note In C mode the type of data used by \ref BLArrayView is `const void*`, thus it has to be retyped to a real
   1847 //! type this view points to. There are only few specializations like \ref BLStringView that point to a real type.
   1848 template<typename T>
   1849 struct BLArrayView {
   1850   const T* data;
   1851   size_t size;
   1852 
   1853   BL_INLINE_NODEBUG void reset() noexcept { *this = BLArrayView{}; }
   1854 
   1855   BL_INLINE_NODEBUG void reset(const T* data_in, size_t size_in) noexcept {
   1856     data = data_in;
   1857     size = size_in;
   1858   }
   1859 
   1860   [[nodiscard]]
   1861   BL_INLINE const T& operator[](size_t index) noexcept {
   1862     BL_ASSERT(index < size);
   1863     return data[index];
   1864   }
   1865 
   1866   [[nodiscard]]
   1867   BL_INLINE_NODEBUG const T* begin() const noexcept { return data; }
   1868 
   1869   [[nodiscard]]
   1870   BL_INLINE_NODEBUG const T* end() const noexcept { return data + size; }
   1871 
   1872   [[nodiscard]]
   1873   BL_INLINE_NODEBUG const T* cbegin() const noexcept { return data; }
   1874 
   1875   [[nodiscard]]
   1876   BL_INLINE_NODEBUG const T* cend() const noexcept { return data + size; }
   1877 };
   1878 
   1879 // In C++ mode these are just typedefs of `BLArrayView<Type>`.
   1880 
   1881 //! View of `char[]` data used by String.
   1882 using BLStringView = BLArrayView<char>;
   1883 
   1884 //! View of untyped data.
   1885 using BLDataView = BLArrayView<uint8_t>;
   1886 
   1887 #else
   1888 
   1889 #define BL_DEFINE_ARRAY_VIEW(NAME, TYPE) \
   1890   typedef struct {                       \
   1891     const TYPE* data;                    \
   1892     size_t size;                         \
   1893   } NAME
   1894 
   1895 BL_DEFINE_ARRAY_VIEW(BLArrayView, void);
   1896 BL_DEFINE_ARRAY_VIEW(BLStringView, char);
   1897 
   1898 typedef BLArrayView BLDataView;
   1899 
   1900 #undef BL_DEFINE_ARRAY_VIEW
   1901 
   1902 #endif
   1903 
   1904 //! \}
   1905 
   1906 #endif // BLEND2D_API_H_INCLUDED