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