twitchapon-anim

Basic Twitchapon Receiver/Visuals
git clone git://bsandro.tech/twitchapon-anim
Log | Files | Refs | README | LICENSE

nuklear.h (980614B)


      1 /*
      2 /// # Nuklear
      3 /// ![](https://cloud.githubusercontent.com/assets/8057201/11761525/ae06f0ca-a0c6-11e5-819d-5610b25f6ef4.gif)
      4 ///
      5 /// ## Contents
      6 /// 1. About section
      7 /// 2. Highlights section
      8 /// 3. Features section
      9 /// 4. Usage section
     10 ///     1. Flags section
     11 ///     2. Constants section
     12 ///     3. Dependencies section
     13 /// 5. Example section
     14 /// 6. API section
     15 ///     1. Context section
     16 ///     2. Input section
     17 ///     3. Drawing section
     18 ///     4. Window section
     19 ///     5. Layouting section
     20 ///     6. Groups section
     21 ///     7. Tree section
     22 ///     8. Properties section
     23 /// 7. License section
     24 /// 8. Changelog section
     25 /// 9. Gallery section
     26 /// 10. Credits section
     27 ///
     28 /// ## About
     29 /// This is a minimal state immediate mode graphical user interface toolkit
     30 /// written in ANSI C and licensed under public domain. It was designed as a simple
     31 /// embeddable user interface for application and does not have any dependencies,
     32 /// a default renderbackend or OS window and input handling but instead provides a very modular
     33 /// library approach by using simple input state for input and draw
     34 /// commands describing primitive shapes as output. So instead of providing a
     35 /// layered library that tries to abstract over a number of platform and
     36 /// render backends it only focuses on the actual UI.
     37 ///
     38 /// ## Highlights
     39 /// - Graphical user interface toolkit
     40 /// - Single header library
     41 /// - Written in C89 (a.k.a. ANSI C or ISO C90)
     42 /// - Small codebase (~18kLOC)
     43 /// - Focus on portability, efficiency and simplicity
     44 /// - No dependencies (not even the standard library if not wanted)
     45 /// - Fully skinnable and customizable
     46 /// - Low memory footprint with total memory control if needed or wanted
     47 /// - UTF-8 support
     48 /// - No global or hidden state
     49 /// - Customizable library modules (you can compile and use only what you need)
     50 /// - Optional font baker and vertex buffer output
     51 ///
     52 /// ## Features
     53 /// - Absolutely no platform dependent code
     54 /// - Memory management control ranging from/to
     55 ///     - Ease of use by allocating everything from standard library
     56 ///     - Control every byte of memory inside the library
     57 /// - Font handling control ranging from/to
     58 ///     - Use your own font implementation for everything
     59 ///     - Use this libraries internal font baking and handling API
     60 /// - Drawing output control ranging from/to
     61 ///     - Simple shapes for more high level APIs which already have drawing capabilities
     62 ///     - Hardware accessible anti-aliased vertex buffer output
     63 /// - Customizable colors and properties ranging from/to
     64 ///     - Simple changes to color by filling a simple color table
     65 ///     - Complete control with ability to use skinning to decorate widgets
     66 /// - Bendable UI library with widget ranging from/to
     67 ///     - Basic widgets like buttons, checkboxes, slider, ...
     68 ///     - Advanced widget like abstract comboboxes, contextual menus,...
     69 /// - Compile time configuration to only compile what you need
     70 ///     - Subset which can be used if you do not want to link or use the standard library
     71 /// - Can be easily modified to only update on user input instead of frame updates
     72 ///
     73 /// ## Usage
     74 /// This library is self contained in one single header file and can be used either
     75 /// in header only mode or in implementation mode. The header only mode is used
     76 /// by default when included and allows including this header in other headers
     77 /// and does not contain the actual implementation. <br /><br />
     78 ///
     79 /// The implementation mode requires to define  the preprocessor macro
     80 /// NK_IMPLEMENTATION in *one* .c/.cpp file before #includeing this file, e.g.:
     81 ///
     82 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~C
     83 ///     #define NK_IMPLEMENTATION
     84 ///     #include "nuklear.h"
     85 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     86 ///
     87 /// Also optionally define the symbols listed in the section "OPTIONAL DEFINES"
     88 /// below in header and implementation mode if you want to use additional functionality
     89 /// or need more control over the library.
     90 ///
     91 /// !!! WARNING
     92 ///     Every time nuklear is included define the same compiler flags. This very important not doing so could lead to compiler errors or even worse stack corruptions.
     93 ///
     94 /// ### Flags
     95 /// Flag                            | Description
     96 /// --------------------------------|------------------------------------------
     97 /// NK_PRIVATE                      | If defined declares all functions as static, so they can only be accessed inside the file that contains the implementation
     98 /// NK_INCLUDE_FIXED_TYPES          | If defined it will include header `<stdint.h>` for fixed sized types otherwise nuklear tries to select the correct type. If that fails it will throw a compiler error and you have to select the correct types yourself.
     99 /// NK_INCLUDE_DEFAULT_ALLOCATOR    | If defined it will include header `<stdlib.h>` and provide additional functions to use this library without caring for memory allocation control and therefore ease memory management.
    100 /// NK_INCLUDE_STANDARD_IO          | If defined it will include header `<stdio.h>` and provide additional functions depending on file loading.
    101 /// NK_INCLUDE_STANDARD_VARARGS     | If defined it will include header <stdio.h> and provide additional functions depending on file loading.
    102 /// NK_INCLUDE_VERTEX_BUFFER_OUTPUT | Defining this adds a vertex draw command list backend to this library, which allows you to convert queue commands into vertex draw commands. This is mainly if you need a hardware accessible format for OpenGL, DirectX, Vulkan, Metal,...
    103 /// NK_INCLUDE_FONT_BAKING          | Defining this adds `stb_truetype` and `stb_rect_pack` implementation to this library and provides font baking and rendering. If you already have font handling or do not want to use this font handler you don't have to define it.
    104 /// NK_INCLUDE_DEFAULT_FONT         | Defining this adds the default font: ProggyClean.ttf into this library which can be loaded into a font atlas and allows using this library without having a truetype font
    105 /// NK_INCLUDE_COMMAND_USERDATA     | Defining this adds a userdata pointer into each command. Can be useful for example if you want to provide custom shaders depending on the used widget. Can be combined with the style structures.
    106 /// NK_BUTTON_TRIGGER_ON_RELEASE    | Different platforms require button clicks occurring either on buttons being pressed (up to down) or released (down to up). By default this library will react on buttons being pressed, but if you define this it will only trigger if a button is released.
    107 /// NK_ZERO_COMMAND_MEMORY          | Defining this will zero out memory for each drawing command added to a drawing queue (inside nk_command_buffer_push). Zeroing command memory is very useful for fast checking (using memcmp) if command buffers are equal and avoid drawing frames when nothing on screen has changed since previous frame.
    108 ///
    109 /// !!! WARNING
    110 ///     The following flags will pull in the standard C library:
    111 ///     - NK_INCLUDE_DEFAULT_ALLOCATOR
    112 ///     - NK_INCLUDE_STANDARD_IO
    113 ///     - NK_INCLUDE_STANDARD_VARARGS
    114 ///
    115 /// !!! WARNING
    116 ///     The following flags if defined need to be defined for both header and implementation:
    117 ///     - NK_INCLUDE_FIXED_TYPES
    118 ///     - NK_INCLUDE_DEFAULT_ALLOCATOR
    119 ///     - NK_INCLUDE_STANDARD_VARARGS
    120 ///     - NK_INCLUDE_VERTEX_BUFFER_OUTPUT
    121 ///     - NK_INCLUDE_FONT_BAKING
    122 ///     - NK_INCLUDE_DEFAULT_FONT
    123 ///     - NK_INCLUDE_STANDARD_VARARGS
    124 ///     - NK_INCLUDE_COMMAND_USERDATA
    125 ///
    126 /// ### Constants
    127 /// Define                          | Description
    128 /// --------------------------------|---------------------------------------
    129 /// NK_BUFFER_DEFAULT_INITIAL_SIZE  | Initial buffer size allocated by all buffers while using the default allocator functions included by defining NK_INCLUDE_DEFAULT_ALLOCATOR. If you don't want to allocate the default 4k memory then redefine it.
    130 /// NK_MAX_NUMBER_BUFFER            | Maximum buffer size for the conversion buffer between float and string Under normal circumstances this should be more than sufficient.
    131 /// NK_INPUT_MAX                    | Defines the max number of bytes which can be added as text input in one frame. Under normal circumstances this should be more than sufficient.
    132 ///
    133 /// !!! WARNING
    134 ///     The following constants if defined need to be defined for both header and implementation:
    135 ///     - NK_MAX_NUMBER_BUFFER
    136 ///     - NK_BUFFER_DEFAULT_INITIAL_SIZE
    137 ///     - NK_INPUT_MAX
    138 ///
    139 /// ### Dependencies
    140 /// Function    | Description
    141 /// ------------|---------------------------------------------------------------
    142 /// NK_ASSERT   | If you don't define this, nuklear will use <assert.h> with assert().
    143 /// NK_MEMSET   | You can define this to 'memset' or your own memset implementation replacement. If not nuklear will use its own version.
    144 /// NK_MEMCPY   | You can define this to 'memcpy' or your own memcpy implementation replacement. If not nuklear will use its own version.
    145 /// NK_SQRT     | You can define this to 'sqrt' or your own sqrt implementation replacement. If not nuklear will use its own slow and not highly accurate version.
    146 /// NK_SIN      | You can define this to 'sinf' or your own sine implementation replacement. If not nuklear will use its own approximation implementation.
    147 /// NK_COS      | You can define this to 'cosf' or your own cosine implementation replacement. If not nuklear will use its own approximation implementation.
    148 /// NK_STRTOD   | You can define this to `strtod` or your own string to double conversion implementation replacement. If not defined nuklear will use its own imprecise and possibly unsafe version (does not handle nan or infinity!).
    149 /// NK_DTOA     | You can define this to `dtoa` or your own double to string conversion implementation replacement. If not defined nuklear will use its own imprecise and possibly unsafe version (does not handle nan or infinity!).
    150 /// NK_VSNPRINTF| If you define `NK_INCLUDE_STANDARD_VARARGS` as well as `NK_INCLUDE_STANDARD_IO` and want to be safe define this to `vsnprintf` on compilers supporting later versions of C or C++. By default nuklear will check for your stdlib version in C as well as compiler version in C++. if `vsnprintf` is available it will define it to `vsnprintf` directly. If not defined and if you have older versions of C or C++ it will be defined to `vsprintf` which is unsafe.
    151 ///
    152 /// !!! WARNING
    153 ///     The following dependencies will pull in the standard C library if not redefined:
    154 ///     - NK_ASSERT
    155 ///
    156 /// !!! WARNING
    157 ///     The following dependencies if defined need to be defined for both header and implementation:
    158 ///     - NK_ASSERT
    159 ///
    160 /// !!! WARNING
    161 ///     The following dependencies if defined need to be defined only for the implementation part:
    162 ///     - NK_MEMSET
    163 ///     - NK_MEMCPY
    164 ///     - NK_SQRT
    165 ///     - NK_SIN
    166 ///     - NK_COS
    167 ///     - NK_STRTOD
    168 ///     - NK_DTOA
    169 ///     - NK_VSNPRINTF
    170 ///
    171 /// ## Example
    172 ///
    173 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    174 /// // init gui state
    175 /// enum {EASY, HARD};
    176 /// static int op = EASY;
    177 /// static float value = 0.6f;
    178 /// static int i =  20;
    179 /// struct nk_context ctx;
    180 ///
    181 /// nk_init_fixed(&ctx, calloc(1, MAX_MEMORY), MAX_MEMORY, &font);
    182 /// if (nk_begin(&ctx, "Show", nk_rect(50, 50, 220, 220),
    183 ///     NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_CLOSABLE)) {
    184 ///     // fixed widget pixel width
    185 ///     nk_layout_row_static(&ctx, 30, 80, 1);
    186 ///     if (nk_button_label(&ctx, "button")) {
    187 ///         // event handling
    188 ///     }
    189 ///
    190 ///     // fixed widget window ratio width
    191 ///     nk_layout_row_dynamic(&ctx, 30, 2);
    192 ///     if (nk_option_label(&ctx, "easy", op == EASY)) op = EASY;
    193 ///     if (nk_option_label(&ctx, "hard", op == HARD)) op = HARD;
    194 ///
    195 ///     // custom widget pixel width
    196 ///     nk_layout_row_begin(&ctx, NK_STATIC, 30, 2);
    197 ///     {
    198 ///         nk_layout_row_push(&ctx, 50);
    199 ///         nk_label(&ctx, "Volume:", NK_TEXT_LEFT);
    200 ///         nk_layout_row_push(&ctx, 110);
    201 ///         nk_slider_float(&ctx, 0, &value, 1.0f, 0.1f);
    202 ///     }
    203 ///     nk_layout_row_end(&ctx);
    204 /// }
    205 /// nk_end(&ctx);
    206 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    207 ///
    208 /// ![](https://cloud.githubusercontent.com/assets/8057201/10187981/584ecd68-675c-11e5-897c-822ef534a876.png)
    209 ///
    210 /// ## API
    211 ///
    212 */
    213 #ifndef NK_SINGLE_FILE
    214   #define NK_SINGLE_FILE
    215 #endif
    216 
    217 #ifndef NK_NUKLEAR_H_
    218 #define NK_NUKLEAR_H_
    219 
    220 #ifdef __cplusplus
    221 extern "C" {
    222 #endif
    223 /*
    224  * ==============================================================
    225  *
    226  *                          CONSTANTS
    227  *
    228  * ===============================================================
    229  */
    230 #define NK_UNDEFINED (-1.0f)
    231 #define NK_UTF_INVALID 0xFFFD /* internal invalid utf8 rune */
    232 #define NK_UTF_SIZE 4 /* describes the number of bytes a glyph consists of*/
    233 #ifndef NK_INPUT_MAX
    234   #define NK_INPUT_MAX 16
    235 #endif
    236 #ifndef NK_MAX_NUMBER_BUFFER
    237   #define NK_MAX_NUMBER_BUFFER 64
    238 #endif
    239 #ifndef NK_SCROLLBAR_HIDING_TIMEOUT
    240   #define NK_SCROLLBAR_HIDING_TIMEOUT 4.0f
    241 #endif
    242 /*
    243  * ==============================================================
    244  *
    245  *                          HELPER
    246  *
    247  * ===============================================================
    248  */
    249 #ifndef NK_API
    250   #ifdef NK_PRIVATE
    251     #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199409L))
    252       #define NK_API static inline
    253     #elif defined(__cplusplus)
    254       #define NK_API static inline
    255     #else
    256       #define NK_API static
    257     #endif
    258   #else
    259     #define NK_API extern
    260   #endif
    261 #endif
    262 #ifndef NK_LIB
    263   #ifdef NK_SINGLE_FILE
    264     #define NK_LIB static
    265   #else
    266     #define NK_LIB extern
    267   #endif
    268 #endif
    269 
    270 #define NK_INTERN static
    271 #define NK_STORAGE static
    272 #define NK_GLOBAL static
    273 
    274 #define NK_FLAG(x) (1 << (x))
    275 #define NK_STRINGIFY(x) #x
    276 #define NK_MACRO_STRINGIFY(x) NK_STRINGIFY(x)
    277 #define NK_STRING_JOIN_IMMEDIATE(arg1, arg2) arg1 ## arg2
    278 #define NK_STRING_JOIN_DELAY(arg1, arg2) NK_STRING_JOIN_IMMEDIATE(arg1, arg2)
    279 #define NK_STRING_JOIN(arg1, arg2) NK_STRING_JOIN_DELAY(arg1, arg2)
    280 
    281 #ifdef _MSC_VER
    282   #define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__COUNTER__)
    283 #else
    284   #define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__LINE__)
    285 #endif
    286 
    287 #ifndef NK_STATIC_ASSERT
    288   #define NK_STATIC_ASSERT(exp) typedef char NK_UNIQUE_NAME(_dummy_array)[(exp)?1:-1]
    289 #endif
    290 
    291 #ifndef NK_FILE_LINE
    292 #ifdef _MSC_VER
    293   #define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__COUNTER__)
    294 #else
    295   #define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__LINE__)
    296 #endif
    297 #endif
    298 
    299 #define NK_MIN(a,b) ((a) < (b) ? (a) : (b))
    300 #define NK_MAX(a,b) ((a) < (b) ? (b) : (a))
    301 #define NK_CLAMP(i,v,x) (NK_MAX(NK_MIN(v,x), i))
    302 
    303 #ifdef NK_INCLUDE_STANDARD_VARARGS
    304   #if defined(_MSC_VER) && (_MSC_VER >= 1600) /* VS 2010 and above */
    305     #include <sal.h>
    306     #define NK_PRINTF_FORMAT_STRING _Printf_format_string_
    307   #else
    308     #define NK_PRINTF_FORMAT_STRING
    309   #endif
    310   #if defined(__GNUC__)
    311     #define NK_PRINTF_VARARG_FUNC(fmtargnumber) __attribute__((format(__printf__, fmtargnumber, fmtargnumber+1)))
    312     #define NK_PRINTF_VALIST_FUNC(fmtargnumber) __attribute__((format(__printf__, fmtargnumber, 0)))
    313   #else
    314     #define NK_PRINTF_VARARG_FUNC(fmtargnumber)
    315     #define NK_PRINTF_VALIST_FUNC(fmtargnumber)
    316   #endif
    317   #include <stdarg.h> /* valist, va_start, va_end, ... */
    318 #endif
    319 
    320 /*
    321  * ===============================================================
    322  *
    323  *                          BASIC
    324  *
    325  * ===============================================================
    326  */
    327 #ifdef NK_INCLUDE_FIXED_TYPES
    328  #include <stdint.h>
    329  #define NK_INT8 int8_t
    330  #define NK_UINT8 uint8_t
    331  #define NK_INT16 int16_t
    332  #define NK_UINT16 uint16_t
    333  #define NK_INT32 int32_t
    334  #define NK_UINT32 uint32_t
    335  #define NK_SIZE_TYPE uintptr_t
    336  #define NK_POINTER_TYPE uintptr_t
    337 #else
    338   #ifndef NK_INT8
    339     #define NK_INT8 char
    340   #endif
    341   #ifndef NK_UINT8
    342     #define NK_UINT8 unsigned char
    343   #endif
    344   #ifndef NK_INT16
    345     #define NK_INT16 signed short
    346   #endif
    347   #ifndef NK_UINT16
    348     #define NK_UINT16 unsigned short
    349   #endif
    350   #ifndef NK_INT32
    351     #if defined(_MSC_VER)
    352       #define NK_INT32 __int32
    353     #else
    354       #define NK_INT32 signed int
    355     #endif
    356   #endif
    357   #ifndef NK_UINT32
    358     #if defined(_MSC_VER)
    359       #define NK_UINT32 unsigned __int32
    360     #else
    361       #define NK_UINT32 unsigned int
    362     #endif
    363   #endif
    364   #ifndef NK_SIZE_TYPE
    365     #if defined(_WIN64) && defined(_MSC_VER)
    366       #define NK_SIZE_TYPE unsigned __int64
    367     #elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
    368       #define NK_SIZE_TYPE unsigned __int32
    369     #elif defined(__GNUC__) || defined(__clang__)
    370       #if defined(__x86_64__) || defined(__ppc64__)
    371         #define NK_SIZE_TYPE unsigned long
    372       #else
    373         #define NK_SIZE_TYPE unsigned int
    374       #endif
    375     #else
    376       #define NK_SIZE_TYPE unsigned long
    377     #endif
    378   #endif
    379   #ifndef NK_POINTER_TYPE
    380     #if defined(_WIN64) && defined(_MSC_VER)
    381       #define NK_POINTER_TYPE unsigned __int64
    382     #elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
    383       #define NK_POINTER_TYPE unsigned __int32
    384     #elif defined(__GNUC__) || defined(__clang__)
    385       #if defined(__x86_64__) || defined(__ppc64__)
    386         #define NK_POINTER_TYPE unsigned long
    387       #else
    388         #define NK_POINTER_TYPE unsigned int
    389       #endif
    390     #else
    391       #define NK_POINTER_TYPE unsigned long
    392     #endif
    393   #endif
    394 #endif
    395 
    396 typedef NK_INT8 nk_char;
    397 typedef NK_UINT8 nk_uchar;
    398 typedef NK_UINT8 nk_byte;
    399 typedef NK_INT16 nk_short;
    400 typedef NK_UINT16 nk_ushort;
    401 typedef NK_INT32 nk_int;
    402 typedef NK_UINT32 nk_uint;
    403 typedef NK_SIZE_TYPE nk_size;
    404 typedef NK_POINTER_TYPE nk_ptr;
    405 
    406 typedef nk_uint nk_hash;
    407 typedef nk_uint nk_flags;
    408 typedef nk_uint nk_rune;
    409 
    410 /* Make sure correct type size:
    411  * This will fire with a negative subscript error if the type sizes
    412  * are set incorrectly by the compiler, and compile out if not */
    413 NK_STATIC_ASSERT(sizeof(nk_short) == 2);
    414 NK_STATIC_ASSERT(sizeof(nk_ushort) == 2);
    415 NK_STATIC_ASSERT(sizeof(nk_uint) == 4);
    416 NK_STATIC_ASSERT(sizeof(nk_int) == 4);
    417 NK_STATIC_ASSERT(sizeof(nk_byte) == 1);
    418 NK_STATIC_ASSERT(sizeof(nk_flags) >= 4);
    419 NK_STATIC_ASSERT(sizeof(nk_rune) >= 4);
    420 NK_STATIC_ASSERT(sizeof(nk_size) >= sizeof(void*));
    421 NK_STATIC_ASSERT(sizeof(nk_ptr) >= sizeof(void*));
    422 
    423 /* ============================================================================
    424  *
    425  *                                  API
    426  *
    427  * =========================================================================== */
    428 struct nk_buffer;
    429 struct nk_allocator;
    430 struct nk_command_buffer;
    431 struct nk_draw_command;
    432 struct nk_convert_config;
    433 struct nk_style_item;
    434 struct nk_text_edit;
    435 struct nk_draw_list;
    436 struct nk_user_font;
    437 struct nk_panel;
    438 struct nk_context;
    439 struct nk_draw_vertex_layout_element;
    440 struct nk_style_button;
    441 struct nk_style_toggle;
    442 struct nk_style_selectable;
    443 struct nk_style_slide;
    444 struct nk_style_progress;
    445 struct nk_style_scrollbar;
    446 struct nk_style_edit;
    447 struct nk_style_property;
    448 struct nk_style_chart;
    449 struct nk_style_combo;
    450 struct nk_style_tab;
    451 struct nk_style_window_header;
    452 struct nk_style_window;
    453 
    454 enum {nk_false, nk_true};
    455 struct nk_color {nk_byte r,g,b,a;};
    456 struct nk_colorf {float r,g,b,a;};
    457 struct nk_vec2 {float x,y;};
    458 struct nk_vec2i {short x, y;};
    459 struct nk_rect {float x,y,w,h;};
    460 struct nk_recti {short x,y,w,h;};
    461 typedef char nk_glyph[NK_UTF_SIZE];
    462 typedef union {void *ptr; int id;} nk_handle;
    463 struct nk_image {nk_handle handle;unsigned short w,h;unsigned short region[4];};
    464 struct nk_cursor {struct nk_image img; struct nk_vec2 size, offset;};
    465 struct nk_scroll {nk_uint x, y;};
    466 
    467 enum nk_heading         {NK_UP, NK_RIGHT, NK_DOWN, NK_LEFT};
    468 enum nk_button_behavior {NK_BUTTON_DEFAULT, NK_BUTTON_REPEATER};
    469 enum nk_modify          {NK_FIXED = nk_false, NK_MODIFIABLE = nk_true};
    470 enum nk_orientation     {NK_VERTICAL, NK_HORIZONTAL};
    471 enum nk_collapse_states {NK_MINIMIZED = nk_false, NK_MAXIMIZED = nk_true};
    472 enum nk_show_states     {NK_HIDDEN = nk_false, NK_SHOWN = nk_true};
    473 enum nk_chart_type      {NK_CHART_LINES, NK_CHART_COLUMN, NK_CHART_MAX};
    474 enum nk_chart_event     {NK_CHART_HOVERING = 0x01, NK_CHART_CLICKED = 0x02};
    475 enum nk_color_format    {NK_RGB, NK_RGBA};
    476 enum nk_popup_type      {NK_POPUP_STATIC, NK_POPUP_DYNAMIC};
    477 enum nk_layout_format   {NK_DYNAMIC, NK_STATIC};
    478 enum nk_tree_type       {NK_TREE_NODE, NK_TREE_TAB};
    479 
    480 typedef void*(*nk_plugin_alloc)(nk_handle, void *old, nk_size);
    481 typedef void (*nk_plugin_free)(nk_handle, void *old);
    482 typedef int(*nk_plugin_filter)(const struct nk_text_edit*, nk_rune unicode);
    483 typedef void(*nk_plugin_paste)(nk_handle, struct nk_text_edit*);
    484 typedef void(*nk_plugin_copy)(nk_handle, const char*, int len);
    485 
    486 struct nk_allocator {
    487     nk_handle userdata;
    488     nk_plugin_alloc alloc;
    489     nk_plugin_free free;
    490 };
    491 enum nk_symbol_type {
    492     NK_SYMBOL_NONE,
    493     NK_SYMBOL_X,
    494     NK_SYMBOL_UNDERSCORE,
    495     NK_SYMBOL_CIRCLE_SOLID,
    496     NK_SYMBOL_CIRCLE_OUTLINE,
    497     NK_SYMBOL_RECT_SOLID,
    498     NK_SYMBOL_RECT_OUTLINE,
    499     NK_SYMBOL_TRIANGLE_UP,
    500     NK_SYMBOL_TRIANGLE_DOWN,
    501     NK_SYMBOL_TRIANGLE_LEFT,
    502     NK_SYMBOL_TRIANGLE_RIGHT,
    503     NK_SYMBOL_PLUS,
    504     NK_SYMBOL_MINUS,
    505     NK_SYMBOL_MAX
    506 };
    507 /* =============================================================================
    508  *
    509  *                                  CONTEXT
    510  *
    511  * =============================================================================*/
    512 /*/// ### Context
    513 /// Contexts are the main entry point and the majestro of nuklear and contain all required state.
    514 /// They are used for window, memory, input, style, stack, commands and time management and need
    515 /// to be passed into all nuklear GUI specific functions.
    516 ///
    517 /// #### Usage
    518 /// To use a context it first has to be initialized which can be achieved by calling
    519 /// one of either `nk_init_default`, `nk_init_fixed`, `nk_init`, `nk_init_custom`.
    520 /// Each takes in a font handle and a specific way of handling memory. Memory control
    521 /// hereby ranges from standard library to just specifying a fixed sized block of memory
    522 /// which nuklear has to manage itself from.
    523 ///
    524 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    525 /// struct nk_context ctx;
    526 /// nk_init_xxx(&ctx, ...);
    527 /// while (1) {
    528 ///     // [...]
    529 ///     nk_clear(&ctx);
    530 /// }
    531 /// nk_free(&ctx);
    532 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    533 ///
    534 /// #### Reference
    535 /// Function            | Description
    536 /// --------------------|-------------------------------------------------------
    537 /// __nk_init_default__ | Initializes context with standard library memory allocation (malloc,free)
    538 /// __nk_init_fixed__   | Initializes context from single fixed size memory block
    539 /// __nk_init__         | Initializes context with memory allocator callbacks for alloc and free
    540 /// __nk_init_custom__  | Initializes context from two buffers. One for draw commands the other for window/panel/table allocations
    541 /// __nk_clear__        | Called at the end of the frame to reset and prepare the context for the next frame
    542 /// __nk_free__         | Shutdown and free all memory allocated inside the context
    543 /// __nk_set_user_data__| Utility function to pass user data to draw command
    544  */
    545 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
    546 /*/// #### nk_init_default
    547 /// Initializes a `nk_context` struct with a default standard library allocator.
    548 /// Should be used if you don't want to be bothered with memory management in nuklear.
    549 ///
    550 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    551 /// int nk_init_default(struct nk_context *ctx, const struct nk_user_font *font);
    552 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    553 ///
    554 /// Parameter   | Description
    555 /// ------------|---------------------------------------------------------------
    556 /// __ctx__     | Must point to an either stack or heap allocated `nk_context` struct
    557 /// __font__    | Must point to a previously initialized font handle for more info look at font documentation
    558 ///
    559 /// Returns either `false(0)` on failure or `true(1)` on success.
    560 ///
    561 */
    562 NK_API int nk_init_default(struct nk_context*, const struct nk_user_font*);
    563 #endif
    564 /*/// #### nk_init_fixed
    565 /// Initializes a `nk_context` struct from single fixed size memory block
    566 /// Should be used if you want complete control over nuklear's memory management.
    567 /// Especially recommended for system with little memory or systems with virtual memory.
    568 /// For the later case you can just allocate for example 16MB of virtual memory
    569 /// and only the required amount of memory will actually be committed.
    570 ///
    571 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    572 /// int nk_init_fixed(struct nk_context *ctx, void *memory, nk_size size, const struct nk_user_font *font);
    573 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    574 ///
    575 /// !!! Warning
    576 ///     make sure the passed memory block is aligned correctly for `nk_draw_commands`.
    577 ///
    578 /// Parameter   | Description
    579 /// ------------|--------------------------------------------------------------
    580 /// __ctx__     | Must point to an either stack or heap allocated `nk_context` struct
    581 /// __memory__  | Must point to a previously allocated memory block
    582 /// __size__    | Must contain the total size of __memory__
    583 /// __font__    | Must point to a previously initialized font handle for more info look at font documentation
    584 ///
    585 /// Returns either `false(0)` on failure or `true(1)` on success.
    586 */
    587 NK_API int nk_init_fixed(struct nk_context*, void *memory, nk_size size, const struct nk_user_font*);
    588 /*/// #### nk_init
    589 /// Initializes a `nk_context` struct with memory allocation callbacks for nuklear to allocate
    590 /// memory from. Used internally for `nk_init_default` and provides a kitchen sink allocation
    591 /// interface to nuklear. Can be useful for cases like monitoring memory consumption.
    592 ///
    593 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    594 /// int nk_init(struct nk_context *ctx, struct nk_allocator *alloc, const struct nk_user_font *font);
    595 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    596 ///
    597 /// Parameter   | Description
    598 /// ------------|---------------------------------------------------------------
    599 /// __ctx__     | Must point to an either stack or heap allocated `nk_context` struct
    600 /// __alloc__   | Must point to a previously allocated memory allocator
    601 /// __font__    | Must point to a previously initialized font handle for more info look at font documentation
    602 ///
    603 /// Returns either `false(0)` on failure or `true(1)` on success.
    604 */
    605 NK_API int nk_init(struct nk_context*, struct nk_allocator*, const struct nk_user_font*);
    606 /*/// #### nk_init_custom
    607 /// Initializes a `nk_context` struct from two different either fixed or growing
    608 /// buffers. The first buffer is for allocating draw commands while the second buffer is
    609 /// used for allocating windows, panels and state tables.
    610 ///
    611 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    612 /// int nk_init_custom(struct nk_context *ctx, struct nk_buffer *cmds, struct nk_buffer *pool, const struct nk_user_font *font);
    613 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    614 ///
    615 /// Parameter   | Description
    616 /// ------------|---------------------------------------------------------------
    617 /// __ctx__     | Must point to an either stack or heap allocated `nk_context` struct
    618 /// __cmds__    | Must point to a previously initialized memory buffer either fixed or dynamic to store draw commands into
    619 /// __pool__    | Must point to a previously initialized memory buffer either fixed or dynamic to store windows, panels and tables
    620 /// __font__    | Must point to a previously initialized font handle for more info look at font documentation
    621 ///
    622 /// Returns either `false(0)` on failure or `true(1)` on success.
    623 */
    624 NK_API int nk_init_custom(struct nk_context*, struct nk_buffer *cmds, struct nk_buffer *pool, const struct nk_user_font*);
    625 /*/// #### nk_clear
    626 /// Resets the context state at the end of the frame. This includes mostly
    627 /// garbage collector tasks like removing windows or table not called and therefore
    628 /// used anymore.
    629 ///
    630 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    631 /// void nk_clear(struct nk_context *ctx);
    632 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    633 ///
    634 /// Parameter   | Description
    635 /// ------------|-----------------------------------------------------------
    636 /// __ctx__     | Must point to a previously initialized `nk_context` struct
    637 */
    638 NK_API void nk_clear(struct nk_context*);
    639 /*/// #### nk_free
    640 /// Frees all memory allocated by nuklear. Not needed if context was
    641 /// initialized with `nk_init_fixed`.
    642 ///
    643 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    644 /// void nk_free(struct nk_context *ctx);
    645 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    646 ///
    647 /// Parameter   | Description
    648 /// ------------|-----------------------------------------------------------
    649 /// __ctx__     | Must point to a previously initialized `nk_context` struct
    650 */
    651 NK_API void nk_free(struct nk_context*);
    652 #ifdef NK_INCLUDE_COMMAND_USERDATA
    653 /*/// #### nk_set_user_data
    654 /// Sets the currently passed userdata passed down into each draw command.
    655 ///
    656 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    657 /// void nk_set_user_data(struct nk_context *ctx, nk_handle data);
    658 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    659 ///
    660 /// Parameter   | Description
    661 /// ------------|--------------------------------------------------------------
    662 /// __ctx__     | Must point to a previously initialized `nk_context` struct
    663 /// __data__    | Handle with either pointer or index to be passed into every draw commands
    664 */
    665 NK_API void nk_set_user_data(struct nk_context*, nk_handle handle);
    666 #endif
    667 /* =============================================================================
    668  *
    669  *                                  INPUT
    670  *
    671  * =============================================================================*/
    672 /*/// ### Input
    673 /// The input API is responsible for holding the current input state composed of
    674 /// mouse, key and text input states.
    675 /// It is worth noting that no direct OS or window handling is done in nuklear.
    676 /// Instead all input state has to be provided by platform specific code. This on one hand
    677 /// expects more work from the user and complicates usage but on the other hand
    678 /// provides simple abstraction over a big number of platforms, libraries and other
    679 /// already provided functionality.
    680 ///
    681 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    682 /// nk_input_begin(&ctx);
    683 /// while (GetEvent(&evt)) {
    684 ///     if (evt.type == MOUSE_MOVE)
    685 ///         nk_input_motion(&ctx, evt.motion.x, evt.motion.y);
    686 ///     else if (evt.type == [...]) {
    687 ///         // [...]
    688 ///     }
    689 /// } nk_input_end(&ctx);
    690 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    691 ///
    692 /// #### Usage
    693 /// Input state needs to be provided to nuklear by first calling `nk_input_begin`
    694 /// which resets internal state like delta mouse position and button transistions.
    695 /// After `nk_input_begin` all current input state needs to be provided. This includes
    696 /// mouse motion, button and key pressed and released, text input and scrolling.
    697 /// Both event- or state-based input handling are supported by this API
    698 /// and should work without problems. Finally after all input state has been
    699 /// mirrored `nk_input_end` needs to be called to finish input process.
    700 ///
    701 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    702 /// struct nk_context ctx;
    703 /// nk_init_xxx(&ctx, ...);
    704 /// while (1) {
    705 ///     Event evt;
    706 ///     nk_input_begin(&ctx);
    707 ///     while (GetEvent(&evt)) {
    708 ///         if (evt.type == MOUSE_MOVE)
    709 ///             nk_input_motion(&ctx, evt.motion.x, evt.motion.y);
    710 ///         else if (evt.type == [...]) {
    711 ///             // [...]
    712 ///         }
    713 ///     }
    714 ///     nk_input_end(&ctx);
    715 ///     // [...]
    716 ///     nk_clear(&ctx);
    717 /// } nk_free(&ctx);
    718 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    719 ///
    720 /// #### Reference
    721 /// Function            | Description
    722 /// --------------------|-------------------------------------------------------
    723 /// __nk_input_begin__  | Begins the input mirroring process. Needs to be called before all other `nk_input_xxx` calls
    724 /// __nk_input_motion__ | Mirrors mouse cursor position
    725 /// __nk_input_key__    | Mirrors key state with either pressed or released
    726 /// __nk_input_button__ | Mirrors mouse button state with either pressed or released
    727 /// __nk_input_scroll__ | Mirrors mouse scroll values
    728 /// __nk_input_char__   | Adds a single ASCII text character into an internal text buffer
    729 /// __nk_input_glyph__  | Adds a single multi-byte UTF-8 character into an internal text buffer
    730 /// __nk_input_unicode__| Adds a single unicode rune into an internal text buffer
    731 /// __nk_input_end__    | Ends the input mirroring process by calculating state changes. Don't call any `nk_input_xxx` function referenced above after this call
    732 */
    733 enum nk_keys {
    734     NK_KEY_NONE,
    735     NK_KEY_SHIFT,
    736     NK_KEY_CTRL,
    737     NK_KEY_DEL,
    738     NK_KEY_ENTER,
    739     NK_KEY_TAB,
    740     NK_KEY_BACKSPACE,
    741     NK_KEY_COPY,
    742     NK_KEY_CUT,
    743     NK_KEY_PASTE,
    744     NK_KEY_UP,
    745     NK_KEY_DOWN,
    746     NK_KEY_LEFT,
    747     NK_KEY_RIGHT,
    748     /* Shortcuts: text field */
    749     NK_KEY_TEXT_INSERT_MODE,
    750     NK_KEY_TEXT_REPLACE_MODE,
    751     NK_KEY_TEXT_RESET_MODE,
    752     NK_KEY_TEXT_LINE_START,
    753     NK_KEY_TEXT_LINE_END,
    754     NK_KEY_TEXT_START,
    755     NK_KEY_TEXT_END,
    756     NK_KEY_TEXT_UNDO,
    757     NK_KEY_TEXT_REDO,
    758     NK_KEY_TEXT_SELECT_ALL,
    759     NK_KEY_TEXT_WORD_LEFT,
    760     NK_KEY_TEXT_WORD_RIGHT,
    761     /* Shortcuts: scrollbar */
    762     NK_KEY_SCROLL_START,
    763     NK_KEY_SCROLL_END,
    764     NK_KEY_SCROLL_DOWN,
    765     NK_KEY_SCROLL_UP,
    766     NK_KEY_MAX
    767 };
    768 enum nk_buttons {
    769     NK_BUTTON_LEFT,
    770     NK_BUTTON_MIDDLE,
    771     NK_BUTTON_RIGHT,
    772     NK_BUTTON_DOUBLE,
    773     NK_BUTTON_MAX
    774 };
    775 /*/// #### nk_input_begin
    776 /// Begins the input mirroring process by resetting text, scroll
    777 /// mouse, previous mouse position and movement as well as key state transitions,
    778 ///
    779 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    780 /// void nk_input_begin(struct nk_context*);
    781 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    782 ///
    783 /// Parameter   | Description
    784 /// ------------|-----------------------------------------------------------
    785 /// __ctx__     | Must point to a previously initialized `nk_context` struct
    786 */
    787 NK_API void nk_input_begin(struct nk_context*);
    788 /*/// #### nk_input_motion
    789 /// Mirrors current mouse position to nuklear
    790 ///
    791 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    792 /// void nk_input_motion(struct nk_context *ctx, int x, int y);
    793 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    794 ///
    795 /// Parameter   | Description
    796 /// ------------|-----------------------------------------------------------
    797 /// __ctx__     | Must point to a previously initialized `nk_context` struct
    798 /// __x__       | Must hold an integer describing the current mouse cursor x-position
    799 /// __y__       | Must hold an integer describing the current mouse cursor y-position
    800 */
    801 NK_API void nk_input_motion(struct nk_context*, int x, int y);
    802 /*/// #### nk_input_key
    803 /// Mirrors the state of a specific key to nuklear
    804 ///
    805 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    806 /// void nk_input_key(struct nk_context*, enum nk_keys key, int down);
    807 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    808 ///
    809 /// Parameter   | Description
    810 /// ------------|-----------------------------------------------------------
    811 /// __ctx__     | Must point to a previously initialized `nk_context` struct
    812 /// __key__     | Must be any value specified in enum `nk_keys` that needs to be mirrored
    813 /// __down__    | Must be 0 for key is up and 1 for key is down
    814 */
    815 NK_API void nk_input_key(struct nk_context*, enum nk_keys, int down);
    816 /*/// #### nk_input_button
    817 /// Mirrors the state of a specific mouse button to nuklear
    818 ///
    819 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    820 /// void nk_input_button(struct nk_context *ctx, enum nk_buttons btn, int x, int y, int down);
    821 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    822 ///
    823 /// Parameter   | Description
    824 /// ------------|-----------------------------------------------------------
    825 /// __ctx__     | Must point to a previously initialized `nk_context` struct
    826 /// __btn__     | Must be any value specified in enum `nk_buttons` that needs to be mirrored
    827 /// __x__       | Must contain an integer describing mouse cursor x-position on click up/down
    828 /// __y__       | Must contain an integer describing mouse cursor y-position on click up/down
    829 /// __down__    | Must be 0 for key is up and 1 for key is down
    830 */
    831 NK_API void nk_input_button(struct nk_context*, enum nk_buttons, int x, int y, int down);
    832 /*/// #### nk_input_scroll
    833 /// Copies the last mouse scroll value to nuklear. Is generally
    834 /// a scroll value. So does not have to come from mouse and could also originate
    835 /// TODO finish this sentence
    836 ///
    837 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    838 /// void nk_input_scroll(struct nk_context *ctx, struct nk_vec2 val);
    839 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    840 ///
    841 /// Parameter   | Description
    842 /// ------------|-----------------------------------------------------------
    843 /// __ctx__     | Must point to a previously initialized `nk_context` struct
    844 /// __val__     | vector with both X- as well as Y-scroll value
    845 */
    846 NK_API void nk_input_scroll(struct nk_context*, struct nk_vec2 val);
    847 /*/// #### nk_input_char
    848 /// Copies a single ASCII character into an internal text buffer
    849 /// This is basically a helper function to quickly push ASCII characters into
    850 /// nuklear.
    851 ///
    852 /// !!! Note
    853 ///     Stores up to NK_INPUT_MAX bytes between `nk_input_begin` and `nk_input_end`.
    854 ///
    855 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    856 /// void nk_input_char(struct nk_context *ctx, char c);
    857 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    858 ///
    859 /// Parameter   | Description
    860 /// ------------|-----------------------------------------------------------
    861 /// __ctx__     | Must point to a previously initialized `nk_context` struct
    862 /// __c__       | Must be a single ASCII character preferable one that can be printed
    863 */
    864 NK_API void nk_input_char(struct nk_context*, char);
    865 /*/// #### nk_input_glyph
    866 /// Converts an encoded unicode rune into UTF-8 and copies the result into an
    867 /// internal text buffer.
    868 ///
    869 /// !!! Note
    870 ///     Stores up to NK_INPUT_MAX bytes between `nk_input_begin` and `nk_input_end`.
    871 ///
    872 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    873 /// void nk_input_glyph(struct nk_context *ctx, const nk_glyph g);
    874 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    875 ///
    876 /// Parameter   | Description
    877 /// ------------|-----------------------------------------------------------
    878 /// __ctx__     | Must point to a previously initialized `nk_context` struct
    879 /// __g__       | UTF-32 unicode codepoint
    880 */
    881 NK_API void nk_input_glyph(struct nk_context*, const nk_glyph);
    882 /*/// #### nk_input_unicode
    883 /// Converts a unicode rune into UTF-8 and copies the result
    884 /// into an internal text buffer.
    885 /// !!! Note
    886 ///     Stores up to NK_INPUT_MAX bytes between `nk_input_begin` and `nk_input_end`.
    887 ///
    888 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    889 /// void nk_input_unicode(struct nk_context*, nk_rune rune);
    890 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    891 ///
    892 /// Parameter   | Description
    893 /// ------------|-----------------------------------------------------------
    894 /// __ctx__     | Must point to a previously initialized `nk_context` struct
    895 /// __rune__    | UTF-32 unicode codepoint
    896 */
    897 NK_API void nk_input_unicode(struct nk_context*, nk_rune);
    898 /*/// #### nk_input_end
    899 /// End the input mirroring process by resetting mouse grabbing
    900 /// state to ensure the mouse cursor is not grabbed indefinitely.
    901 ///
    902 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    903 /// void nk_input_end(struct nk_context *ctx);
    904 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    905 ///
    906 /// Parameter   | Description
    907 /// ------------|-----------------------------------------------------------
    908 /// __ctx__     | Must point to a previously initialized `nk_context` struct
    909 */
    910 NK_API void nk_input_end(struct nk_context*);
    911 /* =============================================================================
    912  *
    913  *                                  DRAWING
    914  *
    915  * =============================================================================*/
    916 /*/// ### Drawing
    917 /// This library was designed to be render backend agnostic so it does
    918 /// not draw anything to screen directly. Instead all drawn shapes, widgets
    919 /// are made of, are buffered into memory and make up a command queue.
    920 /// Each frame therefore fills the command buffer with draw commands
    921 /// that then need to be executed by the user and his own render backend.
    922 /// After that the command buffer needs to be cleared and a new frame can be
    923 /// started. It is probably important to note that the command buffer is the main
    924 /// drawing API and the optional vertex buffer API only takes this format and
    925 /// converts it into a hardware accessible format.
    926 ///
    927 /// #### Usage
    928 /// To draw all draw commands accumulated over a frame you need your own render
    929 /// backend able to draw a number of 2D primitives. This includes at least
    930 /// filled and stroked rectangles, circles, text, lines, triangles and scissors.
    931 /// As soon as this criterion is met you can iterate over each draw command
    932 /// and execute each draw command in a interpreter like fashion:
    933 ///
    934 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    935 /// const struct nk_command *cmd = 0;
    936 /// nk_foreach(cmd, &ctx) {
    937 ///     switch (cmd->type) {
    938 ///     case NK_COMMAND_LINE:
    939 ///         your_draw_line_function(...)
    940 ///         break;
    941 ///     case NK_COMMAND_RECT
    942 ///         your_draw_rect_function(...)
    943 ///         break;
    944 ///     case //...:
    945 ///         //[...]
    946 ///     }
    947 /// }
    948 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    949 ///
    950 /// In program flow context draw commands need to be executed after input has been
    951 /// gathered and the complete UI with windows and their contained widgets have
    952 /// been executed and before calling `nk_clear` which frees all previously
    953 /// allocated draw commands.
    954 ///
    955 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
    956 /// struct nk_context ctx;
    957 /// nk_init_xxx(&ctx, ...);
    958 /// while (1) {
    959 ///     Event evt;
    960 ///     nk_input_begin(&ctx);
    961 ///     while (GetEvent(&evt)) {
    962 ///         if (evt.type == MOUSE_MOVE)
    963 ///             nk_input_motion(&ctx, evt.motion.x, evt.motion.y);
    964 ///         else if (evt.type == [...]) {
    965 ///             [...]
    966 ///         }
    967 ///     }
    968 ///     nk_input_end(&ctx);
    969 ///     //
    970 ///     // [...]
    971 ///     //
    972 ///     const struct nk_command *cmd = 0;
    973 ///     nk_foreach(cmd, &ctx) {
    974 ///     switch (cmd->type) {
    975 ///     case NK_COMMAND_LINE:
    976 ///         your_draw_line_function(...)
    977 ///         break;
    978 ///     case NK_COMMAND_RECT
    979 ///         your_draw_rect_function(...)
    980 ///         break;
    981 ///     case ...:
    982 ///         // [...]
    983 ///     }
    984 ///     nk_clear(&ctx);
    985 /// }
    986 /// nk_free(&ctx);
    987 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    988 ///
    989 /// You probably noticed that you have to draw all of the UI each frame which is
    990 /// quite wasteful. While the actual UI updating loop is quite fast rendering
    991 /// without actually needing it is not. So there are multiple things you could do.
    992 ///
    993 /// First is only update on input. This of course is only an option if your
    994 /// application only depends on the UI and does not require any outside calculations.
    995 /// If you actually only update on input make sure to update the UI two times each
    996 /// frame and call `nk_clear` directly after the first pass and only draw in
    997 /// the second pass. In addition it is recommended to also add additional timers
    998 /// to make sure the UI is not drawn more than a fixed number of frames per second.
    999 ///
   1000 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1001 /// struct nk_context ctx;
   1002 /// nk_init_xxx(&ctx, ...);
   1003 /// while (1) {
   1004 ///     // [...wait for input ]
   1005 ///     // [...do two UI passes ...]
   1006 ///     do_ui(...)
   1007 ///     nk_clear(&ctx);
   1008 ///     do_ui(...)
   1009 ///     //
   1010 ///     // draw
   1011 ///     const struct nk_command *cmd = 0;
   1012 ///     nk_foreach(cmd, &ctx) {
   1013 ///     switch (cmd->type) {
   1014 ///     case NK_COMMAND_LINE:
   1015 ///         your_draw_line_function(...)
   1016 ///         break;
   1017 ///     case NK_COMMAND_RECT
   1018 ///         your_draw_rect_function(...)
   1019 ///         break;
   1020 ///     case ...:
   1021 ///         //[...]
   1022 ///     }
   1023 ///     nk_clear(&ctx);
   1024 /// }
   1025 /// nk_free(&ctx);
   1026 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1027 ///
   1028 /// The second probably more applicable trick is to only draw if anything changed.
   1029 /// It is not really useful for applications with continuous draw loop but
   1030 /// quite useful for desktop applications. To actually get nuklear to only
   1031 /// draw on changes you first have to define `NK_ZERO_COMMAND_MEMORY` and
   1032 /// allocate a memory buffer that will store each unique drawing output.
   1033 /// After each frame you compare the draw command memory inside the library
   1034 /// with your allocated buffer by memcmp. If memcmp detects differences
   1035 /// you have to copy the command buffer into the allocated buffer
   1036 /// and then draw like usual (this example uses fixed memory but you could
   1037 /// use dynamically allocated memory).
   1038 ///
   1039 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1040 /// //[... other defines ...]
   1041 /// #define NK_ZERO_COMMAND_MEMORY
   1042 /// #include "nuklear.h"
   1043 /// //
   1044 /// // setup context
   1045 /// struct nk_context ctx;
   1046 /// void *last = calloc(1,64*1024);
   1047 /// void *buf = calloc(1,64*1024);
   1048 /// nk_init_fixed(&ctx, buf, 64*1024);
   1049 /// //
   1050 /// // loop
   1051 /// while (1) {
   1052 ///     // [...input...]
   1053 ///     // [...ui...]
   1054 ///     void *cmds = nk_buffer_memory(&ctx.memory);
   1055 ///     if (memcmp(cmds, last, ctx.memory.allocated)) {
   1056 ///         memcpy(last,cmds,ctx.memory.allocated);
   1057 ///         const struct nk_command *cmd = 0;
   1058 ///         nk_foreach(cmd, &ctx) {
   1059 ///             switch (cmd->type) {
   1060 ///             case NK_COMMAND_LINE:
   1061 ///                 your_draw_line_function(...)
   1062 ///                 break;
   1063 ///             case NK_COMMAND_RECT
   1064 ///                 your_draw_rect_function(...)
   1065 ///                 break;
   1066 ///             case ...:
   1067 ///                 // [...]
   1068 ///             }
   1069 ///         }
   1070 ///     }
   1071 ///     nk_clear(&ctx);
   1072 /// }
   1073 /// nk_free(&ctx);
   1074 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1075 ///
   1076 /// Finally while using draw commands makes sense for higher abstracted platforms like
   1077 /// X11 and Win32 or drawing libraries it is often desirable to use graphics
   1078 /// hardware directly. Therefore it is possible to just define
   1079 /// `NK_INCLUDE_VERTEX_BUFFER_OUTPUT` which includes optional vertex output.
   1080 /// To access the vertex output you first have to convert all draw commands into
   1081 /// vertexes by calling `nk_convert` which takes in your preferred vertex format.
   1082 /// After successfully converting all draw commands just iterate over and execute all
   1083 /// vertex draw commands:
   1084 ///
   1085 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1086 /// // fill configuration
   1087 /// struct nk_convert_config cfg = {};
   1088 /// static const struct nk_draw_vertex_layout_element vertex_layout[] = {
   1089 ///     {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct your_vertex, pos)},
   1090 ///     {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct your_vertex, uv)},
   1091 ///     {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct your_vertex, col)},
   1092 ///     {NK_VERTEX_LAYOUT_END}
   1093 /// };
   1094 /// cfg.shape_AA = NK_ANTI_ALIASING_ON;
   1095 /// cfg.line_AA = NK_ANTI_ALIASING_ON;
   1096 /// cfg.vertex_layout = vertex_layout;
   1097 /// cfg.vertex_size = sizeof(struct your_vertex);
   1098 /// cfg.vertex_alignment = NK_ALIGNOF(struct your_vertex);
   1099 /// cfg.circle_segment_count = 22;
   1100 /// cfg.curve_segment_count = 22;
   1101 /// cfg.arc_segment_count = 22;
   1102 /// cfg.global_alpha = 1.0f;
   1103 /// cfg.null = dev->null;
   1104 /// //
   1105 /// // setup buffers and convert
   1106 /// struct nk_buffer cmds, verts, idx;
   1107 /// nk_buffer_init_default(&cmds);
   1108 /// nk_buffer_init_default(&verts);
   1109 /// nk_buffer_init_default(&idx);
   1110 /// nk_convert(&ctx, &cmds, &verts, &idx, &cfg);
   1111 /// //
   1112 /// // draw
   1113 /// nk_draw_foreach(cmd, &ctx, &cmds) {
   1114 /// if (!cmd->elem_count) continue;
   1115 ///     //[...]
   1116 /// }
   1117 /// nk_buffer_free(&cms);
   1118 /// nk_buffer_free(&verts);
   1119 /// nk_buffer_free(&idx);
   1120 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1121 ///
   1122 /// #### Reference
   1123 /// Function            | Description
   1124 /// --------------------|-------------------------------------------------------
   1125 /// __nk__begin__       | Returns the first draw command in the context draw command list to be drawn
   1126 /// __nk__next__        | Increments the draw command iterator to the next command inside the context draw command list
   1127 /// __nk_foreach__      | Iterates over each draw command inside the context draw command list
   1128 /// __nk_convert__      | Converts from the abstract draw commands list into a hardware accessible vertex format
   1129 /// __nk_draw_begin__   | Returns the first vertex command in the context vertex draw list to be executed
   1130 /// __nk__draw_next__   | Increments the vertex command iterator to the next command inside the context vertex command list
   1131 /// __nk__draw_end__    | Returns the end of the vertex draw list
   1132 /// __nk_draw_foreach__ | Iterates over each vertex draw command inside the vertex draw list
   1133 */
   1134 enum nk_anti_aliasing {NK_ANTI_ALIASING_OFF, NK_ANTI_ALIASING_ON};
   1135 enum nk_convert_result {
   1136     NK_CONVERT_SUCCESS = 0,
   1137     NK_CONVERT_INVALID_PARAM = 1,
   1138     NK_CONVERT_COMMAND_BUFFER_FULL = NK_FLAG(1),
   1139     NK_CONVERT_VERTEX_BUFFER_FULL = NK_FLAG(2),
   1140     NK_CONVERT_ELEMENT_BUFFER_FULL = NK_FLAG(3)
   1141 };
   1142 struct nk_draw_null_texture {
   1143     nk_handle texture; /* texture handle to a texture with a white pixel */
   1144     struct nk_vec2 uv; /* coordinates to a white pixel in the texture  */
   1145 };
   1146 struct nk_convert_config {
   1147     float global_alpha; /* global alpha value */
   1148     enum nk_anti_aliasing line_AA; /* line anti-aliasing flag can be turned off if you are tight on memory */
   1149     enum nk_anti_aliasing shape_AA; /* shape anti-aliasing flag can be turned off if you are tight on memory */
   1150     unsigned circle_segment_count; /* number of segments used for circles: default to 22 */
   1151     unsigned arc_segment_count; /* number of segments used for arcs: default to 22 */
   1152     unsigned curve_segment_count; /* number of segments used for curves: default to 22 */
   1153     struct nk_draw_null_texture null; /* handle to texture with a white pixel for shape drawing */
   1154     const struct nk_draw_vertex_layout_element *vertex_layout; /* describes the vertex output format and packing */
   1155     nk_size vertex_size; /* sizeof one vertex for vertex packing */
   1156     nk_size vertex_alignment; /* vertex alignment: Can be obtained by NK_ALIGNOF */
   1157 };
   1158 /*/// #### nk__begin
   1159 /// Returns a draw command list iterator to iterate all draw
   1160 /// commands accumulated over one frame.
   1161 ///
   1162 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1163 /// const struct nk_command* nk__begin(struct nk_context*);
   1164 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1165 ///
   1166 /// Parameter   | Description
   1167 /// ------------|-----------------------------------------------------------
   1168 /// __ctx__     | must point to an previously initialized `nk_context` struct at the end of a frame
   1169 ///
   1170 /// Returns draw command pointer pointing to the first command inside the draw command list
   1171 */
   1172 NK_API const struct nk_command* nk__begin(struct nk_context*);
   1173 /*/// #### nk__next
   1174 /// Returns draw command pointer pointing to the next command inside the draw command list
   1175 ///
   1176 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1177 /// const struct nk_command* nk__next(struct nk_context*, const struct nk_command*);
   1178 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1179 ///
   1180 /// Parameter   | Description
   1181 /// ------------|-----------------------------------------------------------
   1182 /// __ctx__     | Must point to an previously initialized `nk_context` struct at the end of a frame
   1183 /// __cmd__     | Must point to an previously a draw command either returned by `nk__begin` or `nk__next`
   1184 ///
   1185 /// Returns draw command pointer pointing to the next command inside the draw command list
   1186 */
   1187 NK_API const struct nk_command* nk__next(struct nk_context*, const struct nk_command*);
   1188 /*/// #### nk_foreach
   1189 /// Iterates over each draw command inside the context draw command list
   1190 ///
   1191 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1192 /// #define nk_foreach(c, ctx)
   1193 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1194 ///
   1195 /// Parameter   | Description
   1196 /// ------------|-----------------------------------------------------------
   1197 /// __ctx__     | Must point to an previously initialized `nk_context` struct at the end of a frame
   1198 /// __cmd__     | Command pointer initialized to NULL
   1199 ///
   1200 /// Iterates over each draw command inside the context draw command list
   1201 */
   1202 #define nk_foreach(c, ctx) for((c) = nk__begin(ctx); (c) != 0; (c) = nk__next(ctx,c))
   1203 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
   1204 /*/// #### nk_convert
   1205 /// Converts all internal draw commands into vertex draw commands and fills
   1206 /// three buffers with vertexes, vertex draw commands and vertex indices. The vertex format
   1207 /// as well as some other configuration values have to be configured by filling out a
   1208 /// `nk_convert_config` struct.
   1209 ///
   1210 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1211 /// nk_flags nk_convert(struct nk_context *ctx, struct nk_buffer *cmds,
   1212 //      struct nk_buffer *vertices, struct nk_buffer *elements, const struct nk_convert_config*);
   1213 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1214 ///
   1215 /// Parameter   | Description
   1216 /// ------------|-----------------------------------------------------------
   1217 /// __ctx__     | Must point to an previously initialized `nk_context` struct at the end of a frame
   1218 /// __cmds__    | Must point to a previously initialized buffer to hold converted vertex draw commands
   1219 /// __vertices__| Must point to a previously initialized buffer to hold all produced vertices
   1220 /// __elements__| Must point to a previously initialized buffer to hold all produced vertex indices
   1221 /// __config__  | Must point to a filled out `nk_config` struct to configure the conversion process
   1222 ///
   1223 /// Returns one of enum nk_convert_result error codes
   1224 ///
   1225 /// Parameter                       | Description
   1226 /// --------------------------------|-----------------------------------------------------------
   1227 /// NK_CONVERT_SUCCESS              | Signals a successful draw command to vertex buffer conversion
   1228 /// NK_CONVERT_INVALID_PARAM        | An invalid argument was passed in the function call
   1229 /// NK_CONVERT_COMMAND_BUFFER_FULL  | The provided buffer for storing draw commands is full or failed to allocate more memory
   1230 /// NK_CONVERT_VERTEX_BUFFER_FULL   | The provided buffer for storing vertices is full or failed to allocate more memory
   1231 /// NK_CONVERT_ELEMENT_BUFFER_FULL  | The provided buffer for storing indicies is full or failed to allocate more memory
   1232 */
   1233 NK_API nk_flags nk_convert(struct nk_context*, struct nk_buffer *cmds, struct nk_buffer *vertices, struct nk_buffer *elements, const struct nk_convert_config*);
   1234 /*/// #### nk__draw_begin
   1235 /// Returns a draw vertex command buffer iterator to iterate over the vertex draw command buffer
   1236 ///
   1237 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1238 /// const struct nk_draw_command* nk__draw_begin(const struct nk_context*, const struct nk_buffer*);
   1239 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1240 ///
   1241 /// Parameter   | Description
   1242 /// ------------|-----------------------------------------------------------
   1243 /// __ctx__     | Must point to an previously initialized `nk_context` struct at the end of a frame
   1244 /// __buf__     | Must point to an previously by `nk_convert` filled out vertex draw command buffer
   1245 ///
   1246 /// Returns vertex draw command pointer pointing to the first command inside the vertex draw command buffer
   1247 */
   1248 NK_API const struct nk_draw_command* nk__draw_begin(const struct nk_context*, const struct nk_buffer*);
   1249 /*/// #### nk__draw_end
   1250 /// Returns the vertex draw command at the end of the vertex draw command buffer
   1251 ///
   1252 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1253 /// const struct nk_draw_command* nk__draw_end(const struct nk_context *ctx, const struct nk_buffer *buf);
   1254 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1255 ///
   1256 /// Parameter   | Description
   1257 /// ------------|-----------------------------------------------------------
   1258 /// __ctx__     | Must point to an previously initialized `nk_context` struct at the end of a frame
   1259 /// __buf__     | Must point to an previously by `nk_convert` filled out vertex draw command buffer
   1260 ///
   1261 /// Returns vertex draw command pointer pointing to the end of the last vertex draw command inside the vertex draw command buffer
   1262 */
   1263 NK_API const struct nk_draw_command* nk__draw_end(const struct nk_context*, const struct nk_buffer*);
   1264 /*/// #### nk__draw_next
   1265 /// Increments the vertex draw command buffer iterator
   1266 ///
   1267 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1268 /// const struct nk_draw_command* nk__draw_next(const struct nk_draw_command*, const struct nk_buffer*, const struct nk_context*);
   1269 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1270 ///
   1271 /// Parameter   | Description
   1272 /// ------------|-----------------------------------------------------------
   1273 /// __cmd__     | Must point to an previously either by `nk__draw_begin` or `nk__draw_next` returned vertex draw command
   1274 /// __buf__     | Must point to an previously by `nk_convert` filled out vertex draw command buffer
   1275 /// __ctx__     | Must point to an previously initialized `nk_context` struct at the end of a frame
   1276 ///
   1277 /// Returns vertex draw command pointer pointing to the end of the last vertex draw command inside the vertex draw command buffer
   1278 */
   1279 NK_API const struct nk_draw_command* nk__draw_next(const struct nk_draw_command*, const struct nk_buffer*, const struct nk_context*);
   1280 /*/// #### nk_draw_foreach
   1281 /// Iterates over each vertex draw command inside a vertex draw command buffer
   1282 ///
   1283 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1284 /// #define nk_draw_foreach(cmd,ctx, b)
   1285 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1286 ///
   1287 /// Parameter   | Description
   1288 /// ------------|-----------------------------------------------------------
   1289 /// __cmd__     | `nk_draw_command`iterator set to NULL
   1290 /// __buf__     | Must point to an previously by `nk_convert` filled out vertex draw command buffer
   1291 /// __ctx__     | Must point to an previously initialized `nk_context` struct at the end of a frame
   1292 */
   1293 #define nk_draw_foreach(cmd,ctx, b) for((cmd)=nk__draw_begin(ctx, b); (cmd)!=0; (cmd)=nk__draw_next(cmd, b, ctx))
   1294 #endif
   1295 /* =============================================================================
   1296  *
   1297  *                                  WINDOW
   1298  *
   1299  * =============================================================================
   1300 /// ### Window
   1301 /// Windows are the main persistent state used inside nuklear and are life time
   1302 /// controlled by simply "retouching" (i.e. calling) each window each frame.
   1303 /// All widgets inside nuklear can only be added inside the function pair `nk_begin_xxx`
   1304 /// and `nk_end`. Calling any widgets outside these two functions will result in an
   1305 /// assert in debug or no state change in release mode.<br /><br />
   1306 ///
   1307 /// Each window holds frame persistent state like position, size, flags, state tables,
   1308 /// and some garbage collected internal persistent widget state. Each window
   1309 /// is linked into a window stack list which determines the drawing and overlapping
   1310 /// order. The topmost window thereby is the currently active window.<br /><br />
   1311 ///
   1312 /// To change window position inside the stack occurs either automatically by
   1313 /// user input by being clicked on or programmatically by calling `nk_window_focus`.
   1314 /// Windows by default are visible unless explicitly being defined with flag
   1315 /// `NK_WINDOW_HIDDEN`, the user clicked the close button on windows with flag
   1316 /// `NK_WINDOW_CLOSABLE` or if a window was explicitly hidden by calling
   1317 /// `nk_window_show`. To explicitly close and destroy a window call `nk_window_close`.<br /><br />
   1318 ///
   1319 /// #### Usage
   1320 /// To create and keep a window you have to call one of the two `nk_begin_xxx`
   1321 /// functions to start window declarations and `nk_end` at the end. Furthermore it
   1322 /// is recommended to check the return value of `nk_begin_xxx` and only process
   1323 /// widgets inside the window if the value is not 0. Either way you have to call
   1324 /// `nk_end` at the end of window declarations. Furthermore, do not attempt to
   1325 /// nest `nk_begin_xxx` calls which will hopefully result in an assert or if not
   1326 /// in a segmentation fault.
   1327 ///
   1328 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1329 /// if (nk_begin_xxx(...) {
   1330 ///     // [... widgets ...]
   1331 /// }
   1332 /// nk_end(ctx);
   1333 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1334 ///
   1335 /// In the grand concept window and widget declarations need to occur after input
   1336 /// handling and before drawing to screen. Not doing so can result in higher
   1337 /// latency or at worst invalid behavior. Furthermore make sure that `nk_clear`
   1338 /// is called at the end of the frame. While nuklear's default platform backends
   1339 /// already call `nk_clear` for you if you write your own backend not calling
   1340 /// `nk_clear` can cause asserts or even worse undefined behavior.
   1341 ///
   1342 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1343 /// struct nk_context ctx;
   1344 /// nk_init_xxx(&ctx, ...);
   1345 /// while (1) {
   1346 ///     Event evt;
   1347 ///     nk_input_begin(&ctx);
   1348 ///     while (GetEvent(&evt)) {
   1349 ///         if (evt.type == MOUSE_MOVE)
   1350 ///             nk_input_motion(&ctx, evt.motion.x, evt.motion.y);
   1351 ///         else if (evt.type == [...]) {
   1352 ///             nk_input_xxx(...);
   1353 ///         }
   1354 ///     }
   1355 ///     nk_input_end(&ctx);
   1356 ///
   1357 ///     if (nk_begin_xxx(...) {
   1358 ///         //[...]
   1359 ///     }
   1360 ///     nk_end(ctx);
   1361 ///
   1362 ///     const struct nk_command *cmd = 0;
   1363 ///     nk_foreach(cmd, &ctx) {
   1364 ///     case NK_COMMAND_LINE:
   1365 ///         your_draw_line_function(...)
   1366 ///         break;
   1367 ///     case NK_COMMAND_RECT
   1368 ///         your_draw_rect_function(...)
   1369 ///         break;
   1370 ///     case //...:
   1371 ///         //[...]
   1372 ///     }
   1373 ///     nk_clear(&ctx);
   1374 /// }
   1375 /// nk_free(&ctx);
   1376 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1377 ///
   1378 /// #### Reference
   1379 /// Function                            | Description
   1380 /// ------------------------------------|----------------------------------------
   1381 /// nk_begin                            | Starts a new window; needs to be called every frame for every window (unless hidden) or otherwise the window gets removed
   1382 /// nk_begin_titled                     | Extended window start with separated title and identifier to allow multiple windows with same name but not title
   1383 /// nk_end                              | Needs to be called at the end of the window building process to process scaling, scrollbars and general cleanup
   1384 //
   1385 /// nk_window_find                      | Finds and returns the window with give name
   1386 /// nk_window_get_bounds                | Returns a rectangle with screen position and size of the currently processed window.
   1387 /// nk_window_get_position              | Returns the position of the currently processed window
   1388 /// nk_window_get_size                  | Returns the size with width and height of the currently processed window
   1389 /// nk_window_get_width                 | Returns the width of the currently processed window
   1390 /// nk_window_get_height                | Returns the height of the currently processed window
   1391 /// nk_window_get_panel                 | Returns the underlying panel which contains all processing state of the current window
   1392 /// nk_window_get_content_region        | Returns the position and size of the currently visible and non-clipped space inside the currently processed window
   1393 /// nk_window_get_content_region_min    | Returns the upper rectangle position of the currently visible and non-clipped space inside the currently processed window
   1394 /// nk_window_get_content_region_max    | Returns the upper rectangle position of the currently visible and non-clipped space inside the currently processed window
   1395 /// nk_window_get_content_region_size   | Returns the size of the currently visible and non-clipped space inside the currently processed window
   1396 /// nk_window_get_canvas                | Returns the draw command buffer. Can be used to draw custom widgets
   1397 /// nk_window_has_focus                 | Returns if the currently processed window is currently active
   1398 /// nk_window_is_collapsed              | Returns if the window with given name is currently minimized/collapsed
   1399 /// nk_window_is_closed                 | Returns if the currently processed window was closed
   1400 /// nk_window_is_hidden                 | Returns if the currently processed window was hidden
   1401 /// nk_window_is_active                 | Same as nk_window_has_focus for some reason
   1402 /// nk_window_is_hovered                | Returns if the currently processed window is currently being hovered by mouse
   1403 /// nk_window_is_any_hovered            | Return if any window currently hovered
   1404 /// nk_item_is_any_active               | Returns if any window or widgets is currently hovered or active
   1405 //
   1406 /// nk_window_set_bounds                | Updates position and size of the currently processed window
   1407 /// nk_window_set_position              | Updates position of the currently process window
   1408 /// nk_window_set_size                  | Updates the size of the currently processed window
   1409 /// nk_window_set_focus                 | Set the currently processed window as active window
   1410 //
   1411 /// nk_window_close                     | Closes the window with given window name which deletes the window at the end of the frame
   1412 /// nk_window_collapse                  | Collapses the window with given window name
   1413 /// nk_window_collapse_if               | Collapses the window with given window name if the given condition was met
   1414 /// nk_window_show                      | Hides a visible or reshows a hidden window
   1415 /// nk_window_show_if                   | Hides/shows a window depending on condition
   1416 */
   1417 /*
   1418 /// #### nk_panel_flags
   1419 /// Flag                        | Description
   1420 /// ----------------------------|----------------------------------------
   1421 /// NK_WINDOW_BORDER            | Draws a border around the window to visually separate window from the background
   1422 /// NK_WINDOW_MOVABLE           | The movable flag indicates that a window can be moved by user input or by dragging the window header
   1423 /// NK_WINDOW_SCALABLE          | The scalable flag indicates that a window can be scaled by user input by dragging a scaler icon at the button of the window
   1424 /// NK_WINDOW_CLOSABLE          | Adds a closable icon into the header
   1425 /// NK_WINDOW_MINIMIZABLE       | Adds a minimize icon into the header
   1426 /// NK_WINDOW_NO_SCROLLBAR      | Removes the scrollbar from the window
   1427 /// NK_WINDOW_TITLE             | Forces a header at the top at the window showing the title
   1428 /// NK_WINDOW_SCROLL_AUTO_HIDE  | Automatically hides the window scrollbar if no user interaction: also requires delta time in `nk_context` to be set each frame
   1429 /// NK_WINDOW_BACKGROUND        | Always keep window in the background
   1430 /// NK_WINDOW_SCALE_LEFT        | Puts window scaler in the left-ottom corner instead right-bottom
   1431 /// NK_WINDOW_NO_INPUT          | Prevents window of scaling, moving or getting focus
   1432 ///
   1433 /// #### nk_collapse_states
   1434 /// State           | Description
   1435 /// ----------------|-----------------------------------------------------------
   1436 /// __NK_MINIMIZED__| UI section is collased and not visibile until maximized
   1437 /// __NK_MAXIMIZED__| UI section is extended and visibile until minimized
   1438 /// <br /><br />
   1439 */
   1440 enum nk_panel_flags {
   1441     NK_WINDOW_BORDER            = NK_FLAG(0),
   1442     NK_WINDOW_MOVABLE           = NK_FLAG(1),
   1443     NK_WINDOW_SCALABLE          = NK_FLAG(2),
   1444     NK_WINDOW_CLOSABLE          = NK_FLAG(3),
   1445     NK_WINDOW_MINIMIZABLE       = NK_FLAG(4),
   1446     NK_WINDOW_NO_SCROLLBAR      = NK_FLAG(5),
   1447     NK_WINDOW_TITLE             = NK_FLAG(6),
   1448     NK_WINDOW_SCROLL_AUTO_HIDE  = NK_FLAG(7),
   1449     NK_WINDOW_BACKGROUND        = NK_FLAG(8),
   1450     NK_WINDOW_SCALE_LEFT        = NK_FLAG(9),
   1451     NK_WINDOW_NO_INPUT          = NK_FLAG(10)
   1452 };
   1453 /*/// #### nk_begin
   1454 /// Starts a new window; needs to be called every frame for every
   1455 /// window (unless hidden) or otherwise the window gets removed
   1456 ///
   1457 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1458 /// int nk_begin(struct nk_context *ctx, const char *title, struct nk_rect bounds, nk_flags flags);
   1459 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1460 ///
   1461 /// Parameter   | Description
   1462 /// ------------|-----------------------------------------------------------
   1463 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1464 /// __title__   | Window title and identifier. Needs to be persistent over frames to identify the window
   1465 /// __bounds__  | Initial position and window size. However if you do not define `NK_WINDOW_SCALABLE` or `NK_WINDOW_MOVABLE` you can set window position and size every frame
   1466 /// __flags__   | Window flags defined in the nk_panel_flags section with a number of different window behaviors
   1467 ///
   1468 /// Returns `true(1)` if the window can be filled up with widgets from this point
   1469 /// until `nk_end` or `false(0)` otherwise for example if minimized
   1470 */
   1471 NK_API int nk_begin(struct nk_context *ctx, const char *title, struct nk_rect bounds, nk_flags flags);
   1472 /*/// #### nk_begin_titled
   1473 /// Extended window start with separated title and identifier to allow multiple
   1474 /// windows with same title but not name
   1475 ///
   1476 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1477 /// int nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, struct nk_rect bounds, nk_flags flags);
   1478 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1479 ///
   1480 /// Parameter   | Description
   1481 /// ------------|-----------------------------------------------------------
   1482 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1483 /// __name__    | Window identifier. Needs to be persistent over frames to identify the window
   1484 /// __title__   | Window title displayed inside header if flag `NK_WINDOW_TITLE` or either `NK_WINDOW_CLOSABLE` or `NK_WINDOW_MINIMIZED` was set
   1485 /// __bounds__  | Initial position and window size. However if you do not define `NK_WINDOW_SCALABLE` or `NK_WINDOW_MOVABLE` you can set window position and size every frame
   1486 /// __flags__   | Window flags defined in the nk_panel_flags section with a number of different window behaviors
   1487 ///
   1488 /// Returns `true(1)` if the window can be filled up with widgets from this point
   1489 /// until `nk_end` or `false(0)` otherwise for example if minimized
   1490 */
   1491 NK_API int nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, struct nk_rect bounds, nk_flags flags);
   1492 /*/// #### nk_end
   1493 /// Needs to be called at the end of the window building process to process scaling, scrollbars and general cleanup.
   1494 /// All widget calls after this functions will result in asserts or no state changes
   1495 ///
   1496 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1497 /// void nk_end(struct nk_context *ctx);
   1498 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1499 ///
   1500 /// Parameter   | Description
   1501 /// ------------|-----------------------------------------------------------
   1502 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1503 */
   1504 NK_API void nk_end(struct nk_context *ctx);
   1505 /*/// #### nk_window_find
   1506 /// Finds and returns a window from passed name
   1507 ///
   1508 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1509 /// void nk_end(struct nk_context *ctx);
   1510 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1511 ///
   1512 /// Parameter   | Description
   1513 /// ------------|-----------------------------------------------------------
   1514 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1515 /// __name__    | Window identifier
   1516 ///
   1517 /// Returns a `nk_window` struct pointing to the identified window or NULL if
   1518 /// no window with the given name was found
   1519 */
   1520 NK_API struct nk_window *nk_window_find(struct nk_context *ctx, const char *name);
   1521 /*/// #### nk_window_get_bounds
   1522 /// Returns a rectangle with screen position and size of the currently processed window
   1523 ///
   1524 /// !!! WARNING
   1525 ///     Only call this function between calls `nk_begin_xxx` and `nk_end`
   1526 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1527 /// struct nk_rect nk_window_get_bounds(const struct nk_context *ctx);
   1528 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1529 ///
   1530 /// Parameter   | Description
   1531 /// ------------|-----------------------------------------------------------
   1532 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1533 ///
   1534 /// Returns a `nk_rect` struct with window upper left window position and size
   1535 */
   1536 NK_API struct nk_rect nk_window_get_bounds(const struct nk_context *ctx);
   1537 /*/// #### nk_window_get_position
   1538 /// Returns the position of the currently processed window.
   1539 ///
   1540 /// !!! WARNING
   1541 ///     Only call this function between calls `nk_begin_xxx` and `nk_end`
   1542 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1543 /// struct nk_vec2 nk_window_get_position(const struct nk_context *ctx);
   1544 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1545 ///
   1546 /// Parameter   | Description
   1547 /// ------------|-----------------------------------------------------------
   1548 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1549 ///
   1550 /// Returns a `nk_vec2` struct with window upper left position
   1551 */
   1552 NK_API struct nk_vec2 nk_window_get_position(const struct nk_context *ctx);
   1553 /*/// #### nk_window_get_size
   1554 /// Returns the size with width and height of the currently processed window.
   1555 ///
   1556 /// !!! WARNING
   1557 ///     Only call this function between calls `nk_begin_xxx` and `nk_end`
   1558 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1559 /// struct nk_vec2 nk_window_get_size(const struct nk_context *ctx);
   1560 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1561 ///
   1562 /// Parameter   | Description
   1563 /// ------------|-----------------------------------------------------------
   1564 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1565 ///
   1566 /// Returns a `nk_vec2` struct with window width and height
   1567 */
   1568 NK_API struct nk_vec2 nk_window_get_size(const struct nk_context*);
   1569 /*/// #### nk_window_get_width
   1570 /// Returns the width of the currently processed window.
   1571 ///
   1572 /// !!! WARNING
   1573 ///     Only call this function between calls `nk_begin_xxx` and `nk_end`
   1574 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1575 /// float nk_window_get_width(const struct nk_context *ctx);
   1576 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1577 ///
   1578 /// Parameter   | Description
   1579 /// ------------|-----------------------------------------------------------
   1580 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1581 ///
   1582 /// Returns the current window width
   1583 */
   1584 NK_API float nk_window_get_width(const struct nk_context*);
   1585 /*/// #### nk_window_get_height
   1586 /// Returns the height of the currently processed window.
   1587 ///
   1588 /// !!! WARNING
   1589 ///     Only call this function between calls `nk_begin_xxx` and `nk_end`
   1590 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1591 /// float nk_window_get_height(const struct nk_context *ctx);
   1592 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1593 ///
   1594 /// Parameter   | Description
   1595 /// ------------|-----------------------------------------------------------
   1596 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1597 ///
   1598 /// Returns the current window height
   1599 */
   1600 NK_API float nk_window_get_height(const struct nk_context*);
   1601 /*/// #### nk_window_get_panel
   1602 /// Returns the underlying panel which contains all processing state of the current window.
   1603 ///
   1604 /// !!! WARNING
   1605 ///     Only call this function between calls `nk_begin_xxx` and `nk_end`
   1606 /// !!! WARNING
   1607 ///     Do not keep the returned panel pointer around, it is only valid until `nk_end`
   1608 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1609 /// struct nk_panel* nk_window_get_panel(struct nk_context *ctx);
   1610 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1611 ///
   1612 /// Parameter   | Description
   1613 /// ------------|-----------------------------------------------------------
   1614 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1615 ///
   1616 /// Returns a pointer to window internal `nk_panel` state.
   1617 */
   1618 NK_API struct nk_panel* nk_window_get_panel(struct nk_context*);
   1619 /*/// #### nk_window_get_content_region
   1620 /// Returns the position and size of the currently visible and non-clipped space
   1621 /// inside the currently processed window.
   1622 ///
   1623 /// !!! WARNING
   1624 ///     Only call this function between calls `nk_begin_xxx` and `nk_end`
   1625 ///
   1626 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1627 /// struct nk_rect nk_window_get_content_region(struct nk_context *ctx);
   1628 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1629 ///
   1630 /// Parameter   | Description
   1631 /// ------------|-----------------------------------------------------------
   1632 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1633 ///
   1634 /// Returns `nk_rect` struct with screen position and size (no scrollbar offset)
   1635 /// of the visible space inside the current window
   1636 */
   1637 NK_API struct nk_rect nk_window_get_content_region(struct nk_context*);
   1638 /*/// #### nk_window_get_content_region_min
   1639 /// Returns the upper left position of the currently visible and non-clipped
   1640 /// space inside the currently processed window.
   1641 ///
   1642 /// !!! WARNING
   1643 ///     Only call this function between calls `nk_begin_xxx` and `nk_end`
   1644 ///
   1645 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1646 /// struct nk_vec2 nk_window_get_content_region_min(struct nk_context *ctx);
   1647 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1648 ///
   1649 /// Parameter   | Description
   1650 /// ------------|-----------------------------------------------------------
   1651 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1652 ///
   1653 /// returns `nk_vec2` struct with  upper left screen position (no scrollbar offset)
   1654 /// of the visible space inside the current window
   1655 */
   1656 NK_API struct nk_vec2 nk_window_get_content_region_min(struct nk_context*);
   1657 /*/// #### nk_window_get_content_region_max
   1658 /// Returns the lower right screen position of the currently visible and
   1659 /// non-clipped space inside the currently processed window.
   1660 ///
   1661 /// !!! WARNING
   1662 ///     Only call this function between calls `nk_begin_xxx` and `nk_end`
   1663 ///
   1664 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1665 /// struct nk_vec2 nk_window_get_content_region_max(struct nk_context *ctx);
   1666 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1667 ///
   1668 /// Parameter   | Description
   1669 /// ------------|-----------------------------------------------------------
   1670 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1671 ///
   1672 /// Returns `nk_vec2` struct with lower right screen position (no scrollbar offset)
   1673 /// of the visible space inside the current window
   1674 */
   1675 NK_API struct nk_vec2 nk_window_get_content_region_max(struct nk_context*);
   1676 /*/// #### nk_window_get_content_region_size
   1677 /// Returns the size of the currently visible and non-clipped space inside the
   1678 /// currently processed window
   1679 ///
   1680 /// !!! WARNING
   1681 ///     Only call this function between calls `nk_begin_xxx` and `nk_end`
   1682 ///
   1683 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1684 /// struct nk_vec2 nk_window_get_content_region_size(struct nk_context *ctx);
   1685 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1686 ///
   1687 /// Parameter   | Description
   1688 /// ------------|-----------------------------------------------------------
   1689 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1690 ///
   1691 /// Returns `nk_vec2` struct with size the visible space inside the current window
   1692 */
   1693 NK_API struct nk_vec2 nk_window_get_content_region_size(struct nk_context*);
   1694 /*/// #### nk_window_get_canvas
   1695 /// Returns the draw command buffer. Can be used to draw custom widgets
   1696 /// !!! WARNING
   1697 ///     Only call this function between calls `nk_begin_xxx` and `nk_end`
   1698 /// !!! WARNING
   1699 ///     Do not keep the returned command buffer pointer around it is only valid until `nk_end`
   1700 ///
   1701 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1702 /// struct nk_command_buffer* nk_window_get_canvas(struct nk_context *ctx);
   1703 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1704 ///
   1705 /// Parameter   | Description
   1706 /// ------------|-----------------------------------------------------------
   1707 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1708 ///
   1709 /// Returns a pointer to window internal `nk_command_buffer` struct used as
   1710 /// drawing canvas. Can be used to do custom drawing.
   1711 */
   1712 NK_API struct nk_command_buffer* nk_window_get_canvas(struct nk_context*);
   1713 /*/// #### nk_window_has_focus
   1714 /// Returns if the currently processed window is currently active
   1715 /// !!! WARNING
   1716 ///     Only call this function between calls `nk_begin_xxx` and `nk_end`
   1717 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1718 /// int nk_window_has_focus(const struct nk_context *ctx);
   1719 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1720 ///
   1721 /// Parameter   | Description
   1722 /// ------------|-----------------------------------------------------------
   1723 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1724 ///
   1725 /// Returns `false(0)` if current window is not active or `true(1)` if it is
   1726 */
   1727 NK_API int nk_window_has_focus(const struct nk_context*);
   1728 /*/// #### nk_window_is_hovered
   1729 /// Return if the current window is being hovered
   1730 /// !!! WARNING
   1731 ///     Only call this function between calls `nk_begin_xxx` and `nk_end`
   1732 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1733 /// int nk_window_is_hovered(struct nk_context *ctx);
   1734 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1735 ///
   1736 /// Parameter   | Description
   1737 /// ------------|-----------------------------------------------------------
   1738 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1739 ///
   1740 /// Returns `true(1)` if current window is hovered or `false(0)` otherwise
   1741 */
   1742 NK_API int nk_window_is_hovered(struct nk_context*);
   1743 /*/// #### nk_window_is_collapsed
   1744 /// Returns if the window with given name is currently minimized/collapsed
   1745 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1746 /// int nk_window_is_collapsed(struct nk_context *ctx, const char *name);
   1747 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1748 ///
   1749 /// Parameter   | Description
   1750 /// ------------|-----------------------------------------------------------
   1751 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1752 /// __name__    | Identifier of window you want to check if it is collapsed
   1753 ///
   1754 /// Returns `true(1)` if current window is minimized and `false(0)` if window not
   1755 /// found or is not minimized
   1756 */
   1757 NK_API int nk_window_is_collapsed(struct nk_context *ctx, const char *name);
   1758 /*/// #### nk_window_is_closed
   1759 /// Returns if the window with given name was closed by calling `nk_close`
   1760 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1761 /// int nk_window_is_closed(struct nk_context *ctx, const char *name);
   1762 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1763 ///
   1764 /// Parameter   | Description
   1765 /// ------------|-----------------------------------------------------------
   1766 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1767 /// __name__    | Identifier of window you want to check if it is closed
   1768 ///
   1769 /// Returns `true(1)` if current window was closed or `false(0)` window not found or not closed
   1770 */
   1771 NK_API int nk_window_is_closed(struct nk_context*, const char*);
   1772 /*/// #### nk_window_is_hidden
   1773 /// Returns if the window with given name is hidden
   1774 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1775 /// int nk_window_is_hidden(struct nk_context *ctx, const char *name);
   1776 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1777 ///
   1778 /// Parameter   | Description
   1779 /// ------------|-----------------------------------------------------------
   1780 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1781 /// __name__    | Identifier of window you want to check if it is hidden
   1782 ///
   1783 /// Returns `true(1)` if current window is hidden or `false(0)` window not found or visible
   1784 */
   1785 NK_API int nk_window_is_hidden(struct nk_context*, const char*);
   1786 /*/// #### nk_window_is_active
   1787 /// Same as nk_window_has_focus for some reason
   1788 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1789 /// int nk_window_is_active(struct nk_context *ctx, const char *name);
   1790 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1791 ///
   1792 /// Parameter   | Description
   1793 /// ------------|-----------------------------------------------------------
   1794 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1795 /// __name__    | Identifier of window you want to check if it is active
   1796 ///
   1797 /// Returns `true(1)` if current window is active or `false(0)` window not found or not active
   1798 */
   1799 NK_API int nk_window_is_active(struct nk_context*, const char*);
   1800 /*/// #### nk_window_is_any_hovered
   1801 /// Returns if the any window is being hovered
   1802 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1803 /// int nk_window_is_any_hovered(struct nk_context*);
   1804 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1805 ///
   1806 /// Parameter   | Description
   1807 /// ------------|-----------------------------------------------------------
   1808 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1809 ///
   1810 /// Returns `true(1)` if any window is hovered or `false(0)` otherwise
   1811 */
   1812 NK_API int nk_window_is_any_hovered(struct nk_context*);
   1813 /*/// #### nk_item_is_any_active
   1814 /// Returns if the any window is being hovered or any widget is currently active.
   1815 /// Can be used to decide if input should be processed by UI or your specific input handling.
   1816 /// Example could be UI and 3D camera to move inside a 3D space.
   1817 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1818 /// int nk_item_is_any_active(struct nk_context*);
   1819 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1820 ///
   1821 /// Parameter   | Description
   1822 /// ------------|-----------------------------------------------------------
   1823 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1824 ///
   1825 /// Returns `true(1)` if any window is hovered or any item is active or `false(0)` otherwise
   1826 */
   1827 NK_API int nk_item_is_any_active(struct nk_context*);
   1828 /*/// #### nk_window_set_bounds
   1829 /// Updates position and size of window with passed in name
   1830 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1831 /// void nk_window_set_bounds(struct nk_context*, const char *name, struct nk_rect bounds);
   1832 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1833 ///
   1834 /// Parameter   | Description
   1835 /// ------------|-----------------------------------------------------------
   1836 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1837 /// __name__    | Identifier of the window to modify both position and size
   1838 /// __bounds__  | Must point to a `nk_rect` struct with the new position and size
   1839 */
   1840 NK_API void nk_window_set_bounds(struct nk_context*, const char *name, struct nk_rect bounds);
   1841 /*/// #### nk_window_set_position
   1842 /// Updates position of window with passed name
   1843 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1844 /// void nk_window_set_position(struct nk_context*, const char *name, struct nk_vec2 pos);
   1845 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1846 ///
   1847 /// Parameter   | Description
   1848 /// ------------|-----------------------------------------------------------
   1849 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1850 /// __name__    | Identifier of the window to modify both position
   1851 /// __pos__     | Must point to a `nk_vec2` struct with the new position
   1852 */
   1853 NK_API void nk_window_set_position(struct nk_context*, const char *name, struct nk_vec2 pos);
   1854 /*/// #### nk_window_set_size
   1855 /// Updates size of window with passed in name
   1856 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1857 /// void nk_window_set_size(struct nk_context*, const char *name, struct nk_vec2);
   1858 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1859 ///
   1860 /// Parameter   | Description
   1861 /// ------------|-----------------------------------------------------------
   1862 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1863 /// __name__    | Identifier of the window to modify both window size
   1864 /// __size__    | Must point to a `nk_vec2` struct with new window size
   1865 */
   1866 NK_API void nk_window_set_size(struct nk_context*, const char *name, struct nk_vec2);
   1867 /*/// #### nk_window_set_focus
   1868 /// Sets the window with given name as active
   1869 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1870 /// void nk_window_set_focus(struct nk_context*, const char *name);
   1871 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1872 ///
   1873 /// Parameter   | Description
   1874 /// ------------|-----------------------------------------------------------
   1875 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1876 /// __name__    | Identifier of the window to set focus on
   1877 */
   1878 NK_API void nk_window_set_focus(struct nk_context*, const char *name);
   1879 /*/// #### nk_window_close
   1880 /// Closes a window and marks it for being freed at the end of the frame
   1881 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1882 /// void nk_window_close(struct nk_context *ctx, const char *name);
   1883 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1884 ///
   1885 /// Parameter   | Description
   1886 /// ------------|-----------------------------------------------------------
   1887 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1888 /// __name__    | Identifier of the window to close
   1889 */
   1890 NK_API void nk_window_close(struct nk_context *ctx, const char *name);
   1891 /*/// #### nk_window_collapse
   1892 /// Updates collapse state of a window with given name
   1893 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1894 /// void nk_window_collapse(struct nk_context*, const char *name, enum nk_collapse_states state);
   1895 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1896 ///
   1897 /// Parameter   | Description
   1898 /// ------------|-----------------------------------------------------------
   1899 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1900 /// __name__    | Identifier of the window to close
   1901 /// __state__   | value out of nk_collapse_states section
   1902 */
   1903 NK_API void nk_window_collapse(struct nk_context*, const char *name, enum nk_collapse_states state);
   1904 /*/// #### nk_window_collapse_if
   1905 /// Updates collapse state of a window with given name if given condition is met
   1906 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1907 /// void nk_window_collapse_if(struct nk_context*, const char *name, enum nk_collapse_states, int cond);
   1908 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1909 ///
   1910 /// Parameter   | Description
   1911 /// ------------|-----------------------------------------------------------
   1912 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1913 /// __name__    | Identifier of the window to either collapse or maximize
   1914 /// __state__   | value out of nk_collapse_states section the window should be put into
   1915 /// __cond__    | condition that has to be met to actually commit the collapse state change
   1916 */
   1917 NK_API void nk_window_collapse_if(struct nk_context*, const char *name, enum nk_collapse_states, int cond);
   1918 /*/// #### nk_window_show
   1919 /// updates visibility state of a window with given name
   1920 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1921 /// void nk_window_show(struct nk_context*, const char *name, enum nk_show_states);
   1922 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1923 ///
   1924 /// Parameter   | Description
   1925 /// ------------|-----------------------------------------------------------
   1926 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1927 /// __name__    | Identifier of the window to either collapse or maximize
   1928 /// __state__   | state with either visible or hidden to modify the window with
   1929 */
   1930 NK_API void nk_window_show(struct nk_context*, const char *name, enum nk_show_states);
   1931 /*/// #### nk_window_show_if
   1932 /// Updates visibility state of a window with given name if a given condition is met
   1933 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1934 /// void nk_window_show_if(struct nk_context*, const char *name, enum nk_show_states, int cond);
   1935 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1936 ///
   1937 /// Parameter   | Description
   1938 /// ------------|-----------------------------------------------------------
   1939 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   1940 /// __name__    | Identifier of the window to either hide or show
   1941 /// __state__   | state with either visible or hidden to modify the window with
   1942 /// __cond__    | condition that has to be met to actually commit the visbility state change
   1943 */
   1944 NK_API void nk_window_show_if(struct nk_context*, const char *name, enum nk_show_states, int cond);
   1945 /* =============================================================================
   1946  *
   1947  *                                  LAYOUT
   1948  *
   1949  * =============================================================================
   1950 /// ### Layouting
   1951 /// Layouting in general describes placing widget inside a window with position and size.
   1952 /// While in this particular implementation there are five different APIs for layouting
   1953 /// each with different trade offs between control and ease of use. <br /><br />
   1954 ///
   1955 /// All layouting methods in this library are based around the concept of a row.
   1956 /// A row has a height the window content grows by and a number of columns and each
   1957 /// layouting method specifies how each widget is placed inside the row.
   1958 /// After a row has been allocated by calling a layouting functions and then
   1959 /// filled with widgets will advance an internal pointer over the allocated row. <br /><br />
   1960 ///
   1961 /// To actually define a layout you just call the appropriate layouting function
   1962 /// and each subsequent widget call will place the widget as specified. Important
   1963 /// here is that if you define more widgets then columns defined inside the layout
   1964 /// functions it will allocate the next row without you having to make another layouting <br /><br />
   1965 /// call.
   1966 ///
   1967 /// Biggest limitation with using all these APIs outside the `nk_layout_space_xxx` API
   1968 /// is that you have to define the row height for each. However the row height
   1969 /// often depends on the height of the font. <br /><br />
   1970 ///
   1971 /// To fix that internally nuklear uses a minimum row height that is set to the
   1972 /// height plus padding of currently active font and overwrites the row height
   1973 /// value if zero. <br /><br />
   1974 ///
   1975 /// If you manually want to change the minimum row height then
   1976 /// use nk_layout_set_min_row_height, and use nk_layout_reset_min_row_height to
   1977 /// reset it back to be derived from font height. <br /><br />
   1978 ///
   1979 /// Also if you change the font in nuklear it will automatically change the minimum
   1980 /// row height for you and. This means if you change the font but still want
   1981 /// a minimum row height smaller than the font you have to repush your value. <br /><br />
   1982 ///
   1983 /// For actually more advanced UI I would even recommend using the `nk_layout_space_xxx`
   1984 /// layouting method in combination with a cassowary constraint solver (there are
   1985 /// some versions on github with permissive license model) to take over all control over widget
   1986 /// layouting yourself. However for quick and dirty layouting using all the other layouting
   1987 /// functions should be fine.
   1988 ///
   1989 /// #### Usage
   1990 /// 1.  __nk_layout_row_dynamic__<br /><br />
   1991 ///     The easiest layouting function is `nk_layout_row_dynamic`. It provides each
   1992 ///     widgets with same horizontal space inside the row and dynamically grows
   1993 ///     if the owning window grows in width. So the number of columns dictates
   1994 ///     the size of each widget dynamically by formula:
   1995 ///
   1996 ///     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   1997 ///     widget_width = (window_width - padding - spacing) * (1/colum_count)
   1998 ///     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1999 ///
   2000 ///     Just like all other layouting APIs if you define more widget than columns this
   2001 ///     library will allocate a new row and keep all layouting parameters previously
   2002 ///     defined.
   2003 ///
   2004 ///     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2005 ///     if (nk_begin_xxx(...) {
   2006 ///         // first row with height: 30 composed of two widgets
   2007 ///         nk_layout_row_dynamic(&ctx, 30, 2);
   2008 ///         nk_widget(...);
   2009 ///         nk_widget(...);
   2010 ///         //
   2011 ///         // second row with same parameter as defined above
   2012 ///         nk_widget(...);
   2013 ///         nk_widget(...);
   2014 ///         //
   2015 ///         // third row uses 0 for height which will use auto layouting
   2016 ///         nk_layout_row_dynamic(&ctx, 0, 2);
   2017 ///         nk_widget(...);
   2018 ///         nk_widget(...);
   2019 ///     }
   2020 ///     nk_end(...);
   2021 ///     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2022 ///
   2023 /// 2.  __nk_layout_row_static__<br /><br />
   2024 ///     Another easy layouting function is `nk_layout_row_static`. It provides each
   2025 ///     widget with same horizontal pixel width inside the row and does not grow
   2026 ///     if the owning window scales smaller or bigger.
   2027 ///
   2028 ///     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2029 ///     if (nk_begin_xxx(...) {
   2030 ///         // first row with height: 30 composed of two widgets with width: 80
   2031 ///         nk_layout_row_static(&ctx, 30, 80, 2);
   2032 ///         nk_widget(...);
   2033 ///         nk_widget(...);
   2034 ///         //
   2035 ///         // second row with same parameter as defined above
   2036 ///         nk_widget(...);
   2037 ///         nk_widget(...);
   2038 ///         //
   2039 ///         // third row uses 0 for height which will use auto layouting
   2040 ///         nk_layout_row_static(&ctx, 0, 80, 2);
   2041 ///         nk_widget(...);
   2042 ///         nk_widget(...);
   2043 ///     }
   2044 ///     nk_end(...);
   2045 ///     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2046 ///
   2047 /// 3.  __nk_layout_row_xxx__<br /><br />
   2048 ///     A little bit more advanced layouting API are functions `nk_layout_row_begin`,
   2049 ///     `nk_layout_row_push` and `nk_layout_row_end`. They allow to directly
   2050 ///     specify each column pixel or window ratio in a row. It supports either
   2051 ///     directly setting per column pixel width or widget window ratio but not
   2052 ///     both. Furthermore it is a immediate mode API so each value is directly
   2053 ///     pushed before calling a widget. Therefore the layout is not automatically
   2054 ///     repeating like the last two layouting functions.
   2055 ///
   2056 ///     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2057 ///     if (nk_begin_xxx(...) {
   2058 ///         // first row with height: 25 composed of two widgets with width 60 and 40
   2059 ///         nk_layout_row_begin(ctx, NK_STATIC, 25, 2);
   2060 ///         nk_layout_row_push(ctx, 60);
   2061 ///         nk_widget(...);
   2062 ///         nk_layout_row_push(ctx, 40);
   2063 ///         nk_widget(...);
   2064 ///         nk_layout_row_end(ctx);
   2065 ///         //
   2066 ///         // second row with height: 25 composed of two widgets with window ratio 0.25 and 0.75
   2067 ///         nk_layout_row_begin(ctx, NK_DYNAMIC, 25, 2);
   2068 ///         nk_layout_row_push(ctx, 0.25f);
   2069 ///         nk_widget(...);
   2070 ///         nk_layout_row_push(ctx, 0.75f);
   2071 ///         nk_widget(...);
   2072 ///         nk_layout_row_end(ctx);
   2073 ///         //
   2074 ///         // third row with auto generated height: composed of two widgets with window ratio 0.25 and 0.75
   2075 ///         nk_layout_row_begin(ctx, NK_DYNAMIC, 0, 2);
   2076 ///         nk_layout_row_push(ctx, 0.25f);
   2077 ///         nk_widget(...);
   2078 ///         nk_layout_row_push(ctx, 0.75f);
   2079 ///         nk_widget(...);
   2080 ///         nk_layout_row_end(ctx);
   2081 ///     }
   2082 ///     nk_end(...);
   2083 ///     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2084 ///
   2085 /// 4.  __nk_layout_row__<br /><br />
   2086 ///     The array counterpart to API nk_layout_row_xxx is the single nk_layout_row
   2087 ///     functions. Instead of pushing either pixel or window ratio for every widget
   2088 ///     it allows to define it by array. The trade of for less control is that
   2089 ///     `nk_layout_row` is automatically repeating. Otherwise the behavior is the
   2090 ///     same.
   2091 ///
   2092 ///     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2093 ///     if (nk_begin_xxx(...) {
   2094 ///         // two rows with height: 30 composed of two widgets with width 60 and 40
   2095 ///         const float size[] = {60,40};
   2096 ///         nk_layout_row(ctx, NK_STATIC, 30, 2, ratio);
   2097 ///         nk_widget(...);
   2098 ///         nk_widget(...);
   2099 ///         nk_widget(...);
   2100 ///         nk_widget(...);
   2101 ///         //
   2102 ///         // two rows with height: 30 composed of two widgets with window ratio 0.25 and 0.75
   2103 ///         const float ratio[] = {0.25, 0.75};
   2104 ///         nk_layout_row(ctx, NK_DYNAMIC, 30, 2, ratio);
   2105 ///         nk_widget(...);
   2106 ///         nk_widget(...);
   2107 ///         nk_widget(...);
   2108 ///         nk_widget(...);
   2109 ///         //
   2110 ///         // two rows with auto generated height composed of two widgets with window ratio 0.25 and 0.75
   2111 ///         const float ratio[] = {0.25, 0.75};
   2112 ///         nk_layout_row(ctx, NK_DYNAMIC, 30, 2, ratio);
   2113 ///         nk_widget(...);
   2114 ///         nk_widget(...);
   2115 ///         nk_widget(...);
   2116 ///         nk_widget(...);
   2117 ///     }
   2118 ///     nk_end(...);
   2119 ///     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2120 ///
   2121 /// 5.  __nk_layout_row_template_xxx__<br /><br />
   2122 ///     The most complex and second most flexible API is a simplified flexbox version without
   2123 ///     line wrapping and weights for dynamic widgets. It is an immediate mode API but
   2124 ///     unlike `nk_layout_row_xxx` it has auto repeat behavior and needs to be called
   2125 ///     before calling the templated widgets.
   2126 ///     The row template layout has three different per widget size specifier. The first
   2127 ///     one is the `nk_layout_row_template_push_static`  with fixed widget pixel width.
   2128 ///     They do not grow if the row grows and will always stay the same.
   2129 ///     The second size specifier is `nk_layout_row_template_push_variable`
   2130 ///     which defines a minimum widget size but it also can grow if more space is available
   2131 ///     not taken by other widgets.
   2132 ///     Finally there are dynamic widgets with `nk_layout_row_template_push_dynamic`
   2133 ///     which are completely flexible and unlike variable widgets can even shrink
   2134 ///     to zero if not enough space is provided.
   2135 ///
   2136 ///     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2137 ///     if (nk_begin_xxx(...) {
   2138 ///         // two rows with height: 30 composed of three widgets
   2139 ///         nk_layout_row_template_begin(ctx, 30);
   2140 ///         nk_layout_row_template_push_dynamic(ctx);
   2141 ///         nk_layout_row_template_push_variable(ctx, 80);
   2142 ///         nk_layout_row_template_push_static(ctx, 80);
   2143 ///         nk_layout_row_template_end(ctx);
   2144 ///         //
   2145 ///         // first row
   2146 ///         nk_widget(...); // dynamic widget can go to zero if not enough space
   2147 ///         nk_widget(...); // variable widget with min 80 pixel but can grow bigger if enough space
   2148 ///         nk_widget(...); // static widget with fixed 80 pixel width
   2149 ///         //
   2150 ///         // second row same layout
   2151 ///         nk_widget(...);
   2152 ///         nk_widget(...);
   2153 ///         nk_widget(...);
   2154 ///     }
   2155 ///     nk_end(...);
   2156 ///     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2157 ///
   2158 /// 6.  __nk_layout_space_xxx__<br /><br />
   2159 ///     Finally the most flexible API directly allows you to place widgets inside the
   2160 ///     window. The space layout API is an immediate mode API which does not support
   2161 ///     row auto repeat and directly sets position and size of a widget. Position
   2162 ///     and size hereby can be either specified as ratio of allocated space or
   2163 ///     allocated space local position and pixel size. Since this API is quite
   2164 ///     powerful there are a number of utility functions to get the available space
   2165 ///     and convert between local allocated space and screen space.
   2166 ///
   2167 ///     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2168 ///     if (nk_begin_xxx(...) {
   2169 ///         // static row with height: 500 (you can set column count to INT_MAX if you don't want to be bothered)
   2170 ///         nk_layout_space_begin(ctx, NK_STATIC, 500, INT_MAX);
   2171 ///         nk_layout_space_push(ctx, nk_rect(0,0,150,200));
   2172 ///         nk_widget(...);
   2173 ///         nk_layout_space_push(ctx, nk_rect(200,200,100,200));
   2174 ///         nk_widget(...);
   2175 ///         nk_layout_space_end(ctx);
   2176 ///         //
   2177 ///         // dynamic row with height: 500 (you can set column count to INT_MAX if you don't want to be bothered)
   2178 ///         nk_layout_space_begin(ctx, NK_DYNAMIC, 500, INT_MAX);
   2179 ///         nk_layout_space_push(ctx, nk_rect(0.5,0.5,0.1,0.1));
   2180 ///         nk_widget(...);
   2181 ///         nk_layout_space_push(ctx, nk_rect(0.7,0.6,0.1,0.1));
   2182 ///         nk_widget(...);
   2183 ///     }
   2184 ///     nk_end(...);
   2185 ///     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2186 ///
   2187 /// #### Reference
   2188 /// Function                                | Description
   2189 /// ----------------------------------------|------------------------------------
   2190 /// nk_layout_set_min_row_height            | Set the currently used minimum row height to a specified value
   2191 /// nk_layout_reset_min_row_height          | Resets the currently used minimum row height to font height
   2192 /// nk_layout_widget_bounds                 | Calculates current width a static layout row can fit inside a window
   2193 /// nk_layout_ratio_from_pixel              | Utility functions to calculate window ratio from pixel size
   2194 //
   2195 /// nk_layout_row_dynamic                   | Current layout is divided into n same sized growing columns
   2196 /// nk_layout_row_static                    | Current layout is divided into n same fixed sized columns
   2197 /// nk_layout_row_begin                     | Starts a new row with given height and number of columns
   2198 /// nk_layout_row_push                      | Pushes another column with given size or window ratio
   2199 /// nk_layout_row_end                       | Finished previously started row
   2200 /// nk_layout_row                           | Specifies row columns in array as either window ratio or size
   2201 //
   2202 /// nk_layout_row_template_begin            | Begins the row template declaration
   2203 /// nk_layout_row_template_push_dynamic     | Adds a dynamic column that dynamically grows and can go to zero if not enough space
   2204 /// nk_layout_row_template_push_variable    | Adds a variable column that dynamically grows but does not shrink below specified pixel width
   2205 /// nk_layout_row_template_push_static      | Adds a static column that does not grow and will always have the same size
   2206 /// nk_layout_row_template_end              | Marks the end of the row template
   2207 //
   2208 /// nk_layout_space_begin                   | Begins a new layouting space that allows to specify each widgets position and size
   2209 /// nk_layout_space_push                    | Pushes position and size of the next widget in own coordinate space either as pixel or ratio
   2210 /// nk_layout_space_end                     | Marks the end of the layouting space
   2211 //
   2212 /// nk_layout_space_bounds                  | Callable after nk_layout_space_begin and returns total space allocated
   2213 /// nk_layout_space_to_screen               | Converts vector from nk_layout_space coordinate space into screen space
   2214 /// nk_layout_space_to_local                | Converts vector from screen space into nk_layout_space coordinates
   2215 /// nk_layout_space_rect_to_screen          | Converts rectangle from nk_layout_space coordinate space into screen space
   2216 /// nk_layout_space_rect_to_local           | Converts rectangle from screen space into nk_layout_space coordinates
   2217 */
   2218 /*/// #### nk_layout_set_min_row_height
   2219 /// Sets the currently used minimum row height.
   2220 /// !!! WARNING
   2221 ///     The passed height needs to include both your preferred row height
   2222 ///     as well as padding. No internal padding is added.
   2223 ///
   2224 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2225 /// void nk_layout_set_min_row_height(struct nk_context*, float height);
   2226 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2227 ///
   2228 /// Parameter   | Description
   2229 /// ------------|-----------------------------------------------------------
   2230 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
   2231 /// __height__  | New minimum row height to be used for auto generating the row height
   2232 */
   2233 NK_API void nk_layout_set_min_row_height(struct nk_context*, float height);
   2234 /*/// #### nk_layout_reset_min_row_height
   2235 /// Reset the currently used minimum row height back to `font_height + text_padding + padding`
   2236 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2237 /// void nk_layout_reset_min_row_height(struct nk_context*);
   2238 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2239 ///
   2240 /// Parameter   | Description
   2241 /// ------------|-----------------------------------------------------------
   2242 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
   2243 */
   2244 NK_API void nk_layout_reset_min_row_height(struct nk_context*);
   2245 /*/// #### nk_layout_widget_bounds
   2246 /// Returns the width of the next row allocate by one of the layouting functions
   2247 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2248 /// struct nk_rect nk_layout_widget_bounds(struct nk_context*);
   2249 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2250 ///
   2251 /// Parameter   | Description
   2252 /// ------------|-----------------------------------------------------------
   2253 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
   2254 ///
   2255 /// Return `nk_rect` with both position and size of the next row
   2256 */
   2257 NK_API struct nk_rect nk_layout_widget_bounds(struct nk_context*);
   2258 /*/// #### nk_layout_ratio_from_pixel
   2259 /// Utility functions to calculate window ratio from pixel size
   2260 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2261 /// float nk_layout_ratio_from_pixel(struct nk_context*, float pixel_width);
   2262 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2263 ///
   2264 /// Parameter   | Description
   2265 /// ------------|-----------------------------------------------------------
   2266 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
   2267 /// __pixel__   | Pixel_width to convert to window ratio
   2268 ///
   2269 /// Returns `nk_rect` with both position and size of the next row
   2270 */
   2271 NK_API float nk_layout_ratio_from_pixel(struct nk_context*, float pixel_width);
   2272 /*/// #### nk_layout_row_dynamic
   2273 /// Sets current row layout to share horizontal space
   2274 /// between @cols number of widgets evenly. Once called all subsequent widget
   2275 /// calls greater than @cols will allocate a new row with same layout.
   2276 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2277 /// void nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols);
   2278 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2279 ///
   2280 /// Parameter   | Description
   2281 /// ------------|-----------------------------------------------------------
   2282 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
   2283 /// __height__  | Holds height of each widget in row or zero for auto layouting
   2284 /// __columns__ | Number of widget inside row
   2285 */
   2286 NK_API void nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols);
   2287 /*/// #### nk_layout_row_static
   2288 /// Sets current row layout to fill @cols number of widgets
   2289 /// in row with same @item_width horizontal size. Once called all subsequent widget
   2290 /// calls greater than @cols will allocate a new row with same layout.
   2291 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2292 /// void nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols);
   2293 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2294 ///
   2295 /// Parameter   | Description
   2296 /// ------------|-----------------------------------------------------------
   2297 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
   2298 /// __height__  | Holds height of each widget in row or zero for auto layouting
   2299 /// __width__   | Holds pixel width of each widget in the row
   2300 /// __columns__ | Number of widget inside row
   2301 */
   2302 NK_API void nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols);
   2303 /*/// #### nk_layout_row_begin
   2304 /// Starts a new dynamic or fixed row with given height and columns.
   2305 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2306 /// void nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt, float row_height, int cols);
   2307 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2308 ///
   2309 /// Parameter   | Description
   2310 /// ------------|-----------------------------------------------------------
   2311 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
   2312 /// __fmt__     | either `NK_DYNAMIC` for window ratio or `NK_STATIC` for fixed size columns
   2313 /// __height__  | holds height of each widget in row or zero for auto layouting
   2314 /// __columns__ | Number of widget inside row
   2315 */
   2316 NK_API void nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt, float row_height, int cols);
   2317 /*/// #### nk_layout_row_push
   2318 /// Specifies either window ratio or width of a single column
   2319 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2320 /// void nk_layout_row_push(struct nk_context*, float value);
   2321 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2322 ///
   2323 /// Parameter   | Description
   2324 /// ------------|-----------------------------------------------------------
   2325 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
   2326 /// __value__   | either a window ratio or fixed width depending on @fmt in previous `nk_layout_row_begin` call
   2327 */
   2328 NK_API void nk_layout_row_push(struct nk_context*, float value);
   2329 /*/// #### nk_layout_row_end
   2330 /// Finished previously started row
   2331 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2332 /// void nk_layout_row_end(struct nk_context*);
   2333 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2334 ///
   2335 /// Parameter   | Description
   2336 /// ------------|-----------------------------------------------------------
   2337 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
   2338 */
   2339 NK_API void nk_layout_row_end(struct nk_context*);
   2340 /*/// #### nk_layout_row
   2341 /// Specifies row columns in array as either window ratio or size
   2342 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2343 /// void nk_layout_row(struct nk_context*, enum nk_layout_format, float height, int cols, const float *ratio);
   2344 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2345 ///
   2346 /// Parameter   | Description
   2347 /// ------------|-----------------------------------------------------------
   2348 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
   2349 /// __fmt__     | Either `NK_DYNAMIC` for window ratio or `NK_STATIC` for fixed size columns
   2350 /// __height__  | Holds height of each widget in row or zero for auto layouting
   2351 /// __columns__ | Number of widget inside row
   2352 */
   2353 NK_API void nk_layout_row(struct nk_context*, enum nk_layout_format, float height, int cols, const float *ratio);
   2354 /*/// #### nk_layout_row_template_begin
   2355 /// Begins the row template declaration
   2356 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2357 /// void nk_layout_row_template_begin(struct nk_context*, float row_height);
   2358 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2359 ///
   2360 /// Parameter   | Description
   2361 /// ------------|-----------------------------------------------------------
   2362 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
   2363 /// __height__  | Holds height of each widget in row or zero for auto layouting
   2364 */
   2365 NK_API void nk_layout_row_template_begin(struct nk_context*, float row_height);
   2366 /*/// #### nk_layout_row_template_push_dynamic
   2367 /// Adds a dynamic column that dynamically grows and can go to zero if not enough space
   2368 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2369 /// void nk_layout_row_template_push_dynamic(struct nk_context*);
   2370 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2371 ///
   2372 /// Parameter   | Description
   2373 /// ------------|-----------------------------------------------------------
   2374 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
   2375 /// __height__  | Holds height of each widget in row or zero for auto layouting
   2376 */
   2377 NK_API void nk_layout_row_template_push_dynamic(struct nk_context*);
   2378 /*/// #### nk_layout_row_template_push_variable
   2379 /// Adds a variable column that dynamically grows but does not shrink below specified pixel width
   2380 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2381 /// void nk_layout_row_template_push_variable(struct nk_context*, float min_width);
   2382 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2383 ///
   2384 /// Parameter   | Description
   2385 /// ------------|-----------------------------------------------------------
   2386 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
   2387 /// __width__   | Holds the minimum pixel width the next column must always be
   2388 */
   2389 NK_API void nk_layout_row_template_push_variable(struct nk_context*, float min_width);
   2390 /*/// #### nk_layout_row_template_push_static
   2391 /// Adds a static column that does not grow and will always have the same size
   2392 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2393 /// void nk_layout_row_template_push_static(struct nk_context*, float width);
   2394 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2395 ///
   2396 /// Parameter   | Description
   2397 /// ------------|-----------------------------------------------------------
   2398 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
   2399 /// __width__   | Holds the absolute pixel width value the next column must be
   2400 */
   2401 NK_API void nk_layout_row_template_push_static(struct nk_context*, float width);
   2402 /*/// #### nk_layout_row_template_end
   2403 /// Marks the end of the row template
   2404 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2405 /// void nk_layout_row_template_end(struct nk_context*);
   2406 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2407 ///
   2408 /// Parameter   | Description
   2409 /// ------------|-----------------------------------------------------------
   2410 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
   2411 */
   2412 NK_API void nk_layout_row_template_end(struct nk_context*);
   2413 /*/// #### nk_layout_space_begin
   2414 /// Begins a new layouting space that allows to specify each widgets position and size.
   2415 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2416 /// void nk_layout_space_begin(struct nk_context*, enum nk_layout_format, float height, int widget_count);
   2417 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2418 ///
   2419 /// Parameter   | Description
   2420 /// ------------|-----------------------------------------------------------
   2421 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
   2422 /// __fmt__     | Either `NK_DYNAMIC` for window ratio or `NK_STATIC` for fixed size columns
   2423 /// __height__  | Holds height of each widget in row or zero for auto layouting
   2424 /// __columns__ | Number of widgets inside row
   2425 */
   2426 NK_API void nk_layout_space_begin(struct nk_context*, enum nk_layout_format, float height, int widget_count);
   2427 /*/// #### nk_layout_space_push
   2428 /// Pushes position and size of the next widget in own coordinate space either as pixel or ratio
   2429 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2430 /// void nk_layout_space_push(struct nk_context *ctx, struct nk_rect bounds);
   2431 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2432 ///
   2433 /// Parameter   | Description
   2434 /// ------------|-----------------------------------------------------------
   2435 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin`
   2436 /// __bounds__  | Position and size in laoyut space local coordinates
   2437 */
   2438 NK_API void nk_layout_space_push(struct nk_context*, struct nk_rect bounds);
   2439 /*/// #### nk_layout_space_end
   2440 /// Marks the end of the layout space
   2441 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2442 /// void nk_layout_space_end(struct nk_context*);
   2443 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2444 ///
   2445 /// Parameter   | Description
   2446 /// ------------|-----------------------------------------------------------
   2447 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin`
   2448 */
   2449 NK_API void nk_layout_space_end(struct nk_context*);
   2450 /*/// #### nk_layout_space_bounds
   2451 /// Utility function to calculate total space allocated for `nk_layout_space`
   2452 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2453 /// struct nk_rect nk_layout_space_bounds(struct nk_context*);
   2454 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2455 ///
   2456 /// Parameter   | Description
   2457 /// ------------|-----------------------------------------------------------
   2458 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin`
   2459 ///
   2460 /// Returns `nk_rect` holding the total space allocated
   2461 */
   2462 NK_API struct nk_rect nk_layout_space_bounds(struct nk_context*);
   2463 /*/// #### nk_layout_space_to_screen
   2464 /// Converts vector from nk_layout_space coordinate space into screen space
   2465 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2466 /// struct nk_vec2 nk_layout_space_to_screen(struct nk_context*, struct nk_vec2);
   2467 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2468 ///
   2469 /// Parameter   | Description
   2470 /// ------------|-----------------------------------------------------------
   2471 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin`
   2472 /// __vec__     | Position to convert from layout space into screen coordinate space
   2473 ///
   2474 /// Returns transformed `nk_vec2` in screen space coordinates
   2475 */
   2476 NK_API struct nk_vec2 nk_layout_space_to_screen(struct nk_context*, struct nk_vec2);
   2477 /*/// #### nk_layout_space_to_local
   2478 /// Converts vector from layout space into screen space
   2479 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2480 /// struct nk_vec2 nk_layout_space_to_local(struct nk_context*, struct nk_vec2);
   2481 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2482 ///
   2483 /// Parameter   | Description
   2484 /// ------------|-----------------------------------------------------------
   2485 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin`
   2486 /// __vec__     | Position to convert from screen space into layout coordinate space
   2487 ///
   2488 /// Returns transformed `nk_vec2` in layout space coordinates
   2489 */
   2490 NK_API struct nk_vec2 nk_layout_space_to_local(struct nk_context*, struct nk_vec2);
   2491 /*/// #### nk_layout_space_rect_to_screen
   2492 /// Converts rectangle from screen space into layout space
   2493 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2494 /// struct nk_rect nk_layout_space_rect_to_screen(struct nk_context*, struct nk_rect);
   2495 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2496 ///
   2497 /// Parameter   | Description
   2498 /// ------------|-----------------------------------------------------------
   2499 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin`
   2500 /// __bounds__  | Rectangle to convert from layout space into screen space
   2501 ///
   2502 /// Returns transformed `nk_rect` in screen space coordinates
   2503 */
   2504 NK_API struct nk_rect nk_layout_space_rect_to_screen(struct nk_context*, struct nk_rect);
   2505 /*/// #### nk_layout_space_rect_to_local
   2506 /// Converts rectangle from layout space into screen space
   2507 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2508 /// struct nk_rect nk_layout_space_rect_to_local(struct nk_context*, struct nk_rect);
   2509 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2510 ///
   2511 /// Parameter   | Description
   2512 /// ------------|-----------------------------------------------------------
   2513 /// __ctx__     | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin`
   2514 /// __bounds__  | Rectangle to convert from layout space into screen space
   2515 ///
   2516 /// Returns transformed `nk_rect` in layout space coordinates
   2517 */
   2518 NK_API struct nk_rect nk_layout_space_rect_to_local(struct nk_context*, struct nk_rect);
   2519 /* =============================================================================
   2520  *
   2521  *                                  GROUP
   2522  *
   2523  * =============================================================================
   2524 /// ### Groups
   2525 /// Groups are basically windows inside windows. They allow to subdivide space
   2526 /// in a window to layout widgets as a group. Almost all more complex widget
   2527 /// layouting requirements can be solved using groups and basic layouting
   2528 /// fuctionality. Groups just like windows are identified by an unique name and
   2529 /// internally keep track of scrollbar offsets by default. However additional
   2530 /// versions are provided to directly manage the scrollbar.
   2531 ///
   2532 /// #### Usage
   2533 /// To create a group you have to call one of the three `nk_group_begin_xxx`
   2534 /// functions to start group declarations and `nk_group_end` at the end. Furthermore it
   2535 /// is required to check the return value of `nk_group_begin_xxx` and only process
   2536 /// widgets inside the window if the value is not 0.
   2537 /// Nesting groups is possible and even encouraged since many layouting schemes
   2538 /// can only be achieved by nesting. Groups, unlike windows, need `nk_group_end`
   2539 /// to be only called if the corosponding `nk_group_begin_xxx` call does not return 0:
   2540 ///
   2541 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2542 /// if (nk_group_begin_xxx(ctx, ...) {
   2543 ///     // [... widgets ...]
   2544 ///     nk_group_end(ctx);
   2545 /// }
   2546 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2547 ///
   2548 /// In the grand concept groups can be called after starting a window
   2549 /// with `nk_begin_xxx` and before calling `nk_end`:
   2550 ///
   2551 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2552 /// struct nk_context ctx;
   2553 /// nk_init_xxx(&ctx, ...);
   2554 /// while (1) {
   2555 ///     // Input
   2556 ///     Event evt;
   2557 ///     nk_input_begin(&ctx);
   2558 ///     while (GetEvent(&evt)) {
   2559 ///         if (evt.type == MOUSE_MOVE)
   2560 ///             nk_input_motion(&ctx, evt.motion.x, evt.motion.y);
   2561 ///         else if (evt.type == [...]) {
   2562 ///             nk_input_xxx(...);
   2563 ///         }
   2564 ///     }
   2565 ///     nk_input_end(&ctx);
   2566 ///     //
   2567 ///     // Window
   2568 ///     if (nk_begin_xxx(...) {
   2569 ///         // [...widgets...]
   2570 ///         nk_layout_row_dynamic(...);
   2571 ///         if (nk_group_begin_xxx(ctx, ...) {
   2572 ///             //[... widgets ...]
   2573 ///             nk_group_end(ctx);
   2574 ///         }
   2575 ///     }
   2576 ///     nk_end(ctx);
   2577 ///     //
   2578 ///     // Draw
   2579 ///     const struct nk_command *cmd = 0;
   2580 ///     nk_foreach(cmd, &ctx) {
   2581 ///     switch (cmd->type) {
   2582 ///     case NK_COMMAND_LINE:
   2583 ///         your_draw_line_function(...)
   2584 ///         break;
   2585 ///     case NK_COMMAND_RECT
   2586 ///         your_draw_rect_function(...)
   2587 ///         break;
   2588 ///     case ...:
   2589 ///         // [...]
   2590 ///     }
   2591 //      nk_clear(&ctx);
   2592 /// }
   2593 /// nk_free(&ctx);
   2594 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2595 /// #### Reference
   2596 /// Function                        | Description
   2597 /// --------------------------------|-------------------------------------------
   2598 /// nk_group_begin                  | Start a new group with internal scrollbar handling
   2599 /// nk_group_begin_titled           | Start a new group with separeted name and title and internal scrollbar handling
   2600 /// nk_group_end                    | Ends a group. Should only be called if nk_group_begin returned non-zero
   2601 /// nk_group_scrolled_offset_begin  | Start a new group with manual separated handling of scrollbar x- and y-offset
   2602 /// nk_group_scrolled_begin         | Start a new group with manual scrollbar handling
   2603 /// nk_group_scrolled_end           | Ends a group with manual scrollbar handling. Should only be called if nk_group_begin returned non-zero
   2604 */
   2605 /*/// #### nk_group_begin
   2606 /// Starts a new widget group. Requires a previous layouting function to specify a pos/size.
   2607 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2608 /// int nk_group_begin(struct nk_context*, const char *title, nk_flags);
   2609 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2610 ///
   2611 /// Parameter   | Description
   2612 /// ------------|-----------------------------------------------------------
   2613 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   2614 /// __title__   | Must be an unique identifier for this group that is also used for the group header
   2615 /// __flags__   | Window flags defined in the nk_panel_flags section with a number of different group behaviors
   2616 ///
   2617 /// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
   2618 */
   2619 NK_API int nk_group_begin(struct nk_context*, const char *title, nk_flags);
   2620 /*/// #### nk_group_begin_titled
   2621 /// Starts a new widget group. Requires a previous layouting function to specify a pos/size.
   2622 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2623 /// int nk_group_begin_titled(struct nk_context*, const char *name, const char *title, nk_flags);
   2624 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2625 ///
   2626 /// Parameter   | Description
   2627 /// ------------|-----------------------------------------------------------
   2628 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   2629 /// __id__      | Must be an unique identifier for this group
   2630 /// __title__   | Group header title
   2631 /// __flags__   | Window flags defined in the nk_panel_flags section with a number of different group behaviors
   2632 ///
   2633 /// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
   2634 */
   2635 NK_API int nk_group_begin_titled(struct nk_context*, const char *name, const char *title, nk_flags);
   2636 /*/// #### nk_group_end
   2637 /// Ends a widget group
   2638 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2639 /// void nk_group_end(struct nk_context*);
   2640 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2641 ///
   2642 /// Parameter   | Description
   2643 /// ------------|-----------------------------------------------------------
   2644 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   2645 */
   2646 NK_API void nk_group_end(struct nk_context*);
   2647 /*/// #### nk_group_scrolled_offset_begin
   2648 /// starts a new widget group. requires a previous layouting function to specify
   2649 /// a size. Does not keep track of scrollbar.
   2650 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2651 /// int nk_group_scrolled_offset_begin(struct nk_context*, nk_uint *x_offset, nk_uint *y_offset, const char *title, nk_flags flags);
   2652 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2653 ///
   2654 /// Parameter   | Description
   2655 /// ------------|-----------------------------------------------------------
   2656 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   2657 /// __x_offset__| Scrollbar x-offset to offset all widgets inside the group horizontally.
   2658 /// __y_offset__| Scrollbar y-offset to offset all widgets inside the group vertically
   2659 /// __title__   | Window unique group title used to both identify and display in the group header
   2660 /// __flags__   | Window flags from the nk_panel_flags section
   2661 ///
   2662 /// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
   2663 */
   2664 NK_API int nk_group_scrolled_offset_begin(struct nk_context*, nk_uint *x_offset, nk_uint *y_offset, const char *title, nk_flags flags);
   2665 /*/// #### nk_group_scrolled_begin
   2666 /// Starts a new widget group. requires a previous
   2667 /// layouting function to specify a size. Does not keep track of scrollbar.
   2668 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2669 /// int nk_group_scrolled_begin(struct nk_context*, struct nk_scroll *off, const char *title, nk_flags);
   2670 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2671 ///
   2672 /// Parameter   | Description
   2673 /// ------------|-----------------------------------------------------------
   2674 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   2675 /// __off__     | Both x- and y- scroll offset. Allows for manual scrollbar control
   2676 /// __title__   | Window unique group title used to both identify and display in the group header
   2677 /// __flags__   | Window flags from nk_panel_flags section
   2678 ///
   2679 /// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
   2680 */
   2681 NK_API int nk_group_scrolled_begin(struct nk_context*, struct nk_scroll *off, const char *title, nk_flags);
   2682 /*/// #### nk_group_scrolled_end
   2683 /// Ends a widget group after calling nk_group_scrolled_offset_begin or nk_group_scrolled_begin.
   2684 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2685 /// void nk_group_scrolled_end(struct nk_context*);
   2686 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2687 ///
   2688 /// Parameter   | Description
   2689 /// ------------|-----------------------------------------------------------
   2690 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   2691 */
   2692 NK_API void nk_group_scrolled_end(struct nk_context*);
   2693 /* =============================================================================
   2694  *
   2695  *                                  TREE
   2696  *
   2697  * ============================================================================= 
   2698 /// ### Tree
   2699 /// Trees represent two different concept. First the concept of a collapsable
   2700 /// UI section that can be either in a hidden or visibile state. They allow the UI
   2701 /// user to selectively minimize the current set of visible UI to comprehend.
   2702 /// The second concept are tree widgets for visual UI representation of trees.<br /><br />
   2703 ///
   2704 /// Trees thereby can be nested for tree representations and multiple nested
   2705 /// collapsable UI sections. All trees are started by calling of the
   2706 /// `nk_tree_xxx_push_tree` functions and ended by calling one of the
   2707 /// `nk_tree_xxx_pop_xxx()` functions. Each starting functions takes a title label
   2708 /// and optionally an image to be displayed and the initial collapse state from
   2709 /// the nk_collapse_states section.<br /><br />
   2710 ///
   2711 /// The runtime state of the tree is either stored outside the library by the caller
   2712 /// or inside which requires a unique ID. The unique ID can either be generated
   2713 /// automatically from `__FILE__` and `__LINE__` with function `nk_tree_push`,
   2714 /// by `__FILE__` and a user provided ID generated for example by loop index with
   2715 /// function `nk_tree_push_id` or completely provided from outside by user with
   2716 /// function `nk_tree_push_hashed`.
   2717 ///
   2718 /// #### Usage
   2719 /// To create a tree you have to call one of the seven `nk_tree_xxx_push_xxx`
   2720 /// functions to start a collapsable UI section and `nk_tree_xxx_pop` to mark the
   2721 /// end.
   2722 /// Each starting function will either return `false(0)` if the tree is collapsed
   2723 /// or hidden and therefore does not need to be filled with content or `true(1)`
   2724 /// if visible and required to be filled.
   2725 ///
   2726 /// !!! Note
   2727 ///     The tree header does not require and layouting function and instead
   2728 ///     calculates a auto height based on the currently used font size
   2729 ///
   2730 /// The tree ending functions only need to be called if the tree content is
   2731 /// actually visible. So make sure the tree push function is guarded by `if`
   2732 /// and the pop call is only taken if the tree is visible.
   2733 ///
   2734 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2735 /// if (nk_tree_push(ctx, NK_TREE_TAB, "Tree", NK_MINIMIZED)) {
   2736 ///     nk_layout_row_dynamic(...);
   2737 ///     nk_widget(...);
   2738 ///     nk_tree_pop(ctx);
   2739 /// }
   2740 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2741 ///
   2742 /// #### Reference
   2743 /// Function                    | Description
   2744 /// ----------------------------|-------------------------------------------
   2745 /// nk_tree_push                | Start a collapsable UI section with internal state management
   2746 /// nk_tree_push_id             | Start a collapsable UI section with internal state management callable in a look
   2747 /// nk_tree_push_hashed         | Start a collapsable UI section with internal state management with full control over internal unique ID use to store state
   2748 /// nk_tree_image_push          | Start a collapsable UI section with image and label header
   2749 /// nk_tree_image_push_id       | Start a collapsable UI section with image and label header and internal state management callable in a look
   2750 /// nk_tree_image_push_hashed   | Start a collapsable UI section with image and label header and internal state management with full control over internal unique ID use to store state
   2751 /// nk_tree_pop                 | Ends a collapsable UI section
   2752 //
   2753 /// nk_tree_state_push          | Start a collapsable UI section with external state management
   2754 /// nk_tree_state_image_push    | Start a collapsable UI section with image and label header and external state management
   2755 /// nk_tree_state_pop           | Ends a collapsabale UI section
   2756 ///
   2757 /// #### nk_tree_type
   2758 /// Flag            | Description
   2759 /// ----------------|----------------------------------------
   2760 /// NK_TREE_NODE    | Highlighted tree header to mark a collapsable UI section
   2761 /// NK_TREE_TAB     | Non-highighted tree header closer to tree representations
   2762 */
   2763 /*/// #### nk_tree_push
   2764 /// Starts a collapsable UI section with internal state management
   2765 /// !!! WARNING
   2766 ///     To keep track of the runtime tree collapsable state this function uses
   2767 ///     defines `__FILE__` and `__LINE__` to generate a unique ID. If you want
   2768 ///     to call this function in a loop please use `nk_tree_push_id` or
   2769 ///     `nk_tree_push_hashed` instead.
   2770 ///
   2771 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2772 /// #define nk_tree_push(ctx, type, title, state)
   2773 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2774 ///
   2775 /// Parameter   | Description
   2776 /// ------------|-----------------------------------------------------------
   2777 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   2778 /// __type__    | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable UI section or tree node
   2779 /// __title__   | Label printed in the tree header
   2780 /// __state__   | Initial tree state value out of nk_collapse_states
   2781 ///
   2782 /// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
   2783 */
   2784 #define nk_tree_push(ctx, type, title, state) nk_tree_push_hashed(ctx, type, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),__LINE__)
   2785 /*/// #### nk_tree_push_id
   2786 /// Starts a collapsable UI section with internal state management callable in a look
   2787 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2788 /// #define nk_tree_push_id(ctx, type, title, state, id)
   2789 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2790 ///
   2791 /// Parameter   | Description
   2792 /// ------------|-----------------------------------------------------------
   2793 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   2794 /// __type__    | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable UI section or tree node
   2795 /// __title__   | Label printed in the tree header
   2796 /// __state__   | Initial tree state value out of nk_collapse_states
   2797 /// __id__      | Loop counter index if this function is called in a loop
   2798 ///
   2799 /// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
   2800 */
   2801 #define nk_tree_push_id(ctx, type, title, state, id) nk_tree_push_hashed(ctx, type, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),id)
   2802 /*/// #### nk_tree_push_hashed
   2803 /// Start a collapsable UI section with internal state management with full
   2804 /// control over internal unique ID used to store state
   2805 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2806 /// int nk_tree_push_hashed(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states initial_state, const char *hash, int len,int seed);
   2807 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2808 ///
   2809 /// Parameter   | Description
   2810 /// ------------|-----------------------------------------------------------
   2811 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   2812 /// __type__    | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable UI section or tree node
   2813 /// __title__   | Label printed in the tree header
   2814 /// __state__   | Initial tree state value out of nk_collapse_states
   2815 /// __hash__    | Memory block or string to generate the ID from
   2816 /// __len__     | Size of passed memory block or string in __hash__
   2817 /// __seed__    | Seeding value if this function is called in a loop or default to `0`
   2818 ///
   2819 /// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
   2820 */
   2821 NK_API int nk_tree_push_hashed(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states initial_state, const char *hash, int len,int seed);
   2822 /*/// #### nk_tree_image_push
   2823 /// Start a collapsable UI section with image and label header
   2824 /// !!! WARNING
   2825 ///     To keep track of the runtime tree collapsable state this function uses
   2826 ///     defines `__FILE__` and `__LINE__` to generate a unique ID. If you want
   2827 ///     to call this function in a loop please use `nk_tree_image_push_id` or
   2828 ///     `nk_tree_image_push_hashed` instead.
   2829 ///
   2830 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2831 /// #define nk_tree_image_push(ctx, type, img, title, state)
   2832 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2833 //
   2834 /// Parameter   | Description
   2835 /// ------------|-----------------------------------------------------------
   2836 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   2837 /// __type__    | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable UI section or tree node
   2838 /// __img__     | Image to display inside the header on the left of the label
   2839 /// __title__   | Label printed in the tree header
   2840 /// __state__   | Initial tree state value out of nk_collapse_states
   2841 ///
   2842 /// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
   2843 */
   2844 #define nk_tree_image_push(ctx, type, img, title, state) nk_tree_image_push_hashed(ctx, type, img, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),__LINE__)
   2845 /*/// #### nk_tree_image_push_id
   2846 /// Start a collapsable UI section with image and label header and internal state
   2847 /// management callable in a look
   2848 ///
   2849 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2850 /// #define nk_tree_image_push_id(ctx, type, img, title, state, id)
   2851 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2852 ///
   2853 /// Parameter   | Description
   2854 /// ------------|-----------------------------------------------------------
   2855 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   2856 /// __type__    | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable UI section or tree node
   2857 /// __img__     | Image to display inside the header on the left of the label
   2858 /// __title__   | Label printed in the tree header
   2859 /// __state__   | Initial tree state value out of nk_collapse_states
   2860 /// __id__      | Loop counter index if this function is called in a loop
   2861 ///
   2862 /// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
   2863 */
   2864 #define nk_tree_image_push_id(ctx, type, img, title, state, id) nk_tree_image_push_hashed(ctx, type, img, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),id)
   2865 /*/// #### nk_tree_image_push_hashed
   2866 /// Start a collapsable UI section with internal state management with full
   2867 /// control over internal unique ID used to store state
   2868 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2869 /// int nk_tree_image_push_hashed(struct nk_context*, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states initial_state, const char *hash, int len,int seed);
   2870 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2871 ///
   2872 /// Parameter   | Description
   2873 /// ------------|-----------------------------------------------------------
   2874 /// __ctx__     | Must point to an previously initialized `nk_context` struct
   2875 /// __type__    | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable UI section or tree node
   2876 /// __img__     | Image to display inside the header on the left of the label
   2877 /// __title__   | Label printed in the tree header
   2878 /// __state__   | Initial tree state value out of nk_collapse_states
   2879 /// __hash__    | Memory block or string to generate the ID from
   2880 /// __len__     | Size of passed memory block or string in __hash__
   2881 /// __seed__    | Seeding value if this function is called in a loop or default to `0`
   2882 ///
   2883 /// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
   2884 */
   2885 NK_API int nk_tree_image_push_hashed(struct nk_context*, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states initial_state, const char *hash, int len,int seed);
   2886 /*/// #### nk_tree_pop
   2887 /// Ends a collapsabale UI section
   2888 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2889 /// void nk_tree_pop(struct nk_context*);
   2890 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2891 ///
   2892 /// Parameter   | Description
   2893 /// ------------|-----------------------------------------------------------
   2894 /// __ctx__     | Must point to an previously initialized `nk_context` struct after calling `nk_tree_xxx_push_xxx`
   2895 */
   2896 NK_API void nk_tree_pop(struct nk_context*);
   2897 /*/// #### nk_tree_state_push
   2898 /// Start a collapsable UI section with external state management
   2899 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2900 /// int nk_tree_state_push(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states *state);
   2901 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2902 ///
   2903 /// Parameter   | Description
   2904 /// ------------|-----------------------------------------------------------
   2905 /// __ctx__     | Must point to an previously initialized `nk_context` struct after calling `nk_tree_xxx_push_xxx`
   2906 /// __type__    | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable UI section or tree node
   2907 /// __title__   | Label printed in the tree header
   2908 /// __state__   | Persistent state to update
   2909 ///
   2910 /// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
   2911 */
   2912 NK_API int nk_tree_state_push(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states *state);
   2913 /*/// #### nk_tree_state_image_push
   2914 /// Start a collapsable UI section with image and label header and external state management
   2915 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2916 /// int nk_tree_state_image_push(struct nk_context*, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states *state);
   2917 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2918 ///
   2919 /// Parameter   | Description
   2920 /// ------------|-----------------------------------------------------------
   2921 /// __ctx__     | Must point to an previously initialized `nk_context` struct after calling `nk_tree_xxx_push_xxx`
   2922 /// __img__     | Image to display inside the header on the left of the label
   2923 /// __type__    | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable UI section or tree node
   2924 /// __title__   | Label printed in the tree header
   2925 /// __state__   | Persistent state to update
   2926 ///
   2927 /// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
   2928 */
   2929 NK_API int nk_tree_state_image_push(struct nk_context*, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states *state);
   2930 /*/// #### nk_tree_state_pop
   2931 /// Ends a collapsabale UI section
   2932 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   2933 /// void nk_tree_state_pop(struct nk_context*);
   2934 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2935 ///
   2936 /// Parameter   | Description
   2937 /// ------------|-----------------------------------------------------------
   2938 /// __ctx__     | Must point to an previously initialized `nk_context` struct after calling `nk_tree_xxx_push_xxx`
   2939 */
   2940 NK_API void nk_tree_state_pop(struct nk_context*);
   2941 
   2942 #define nk_tree_element_push(ctx, type, title, state, sel) nk_tree_element_push_hashed(ctx, type, title, state, sel, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),__LINE__)
   2943 #define nk_tree_element_push_id(ctx, type, title, state, sel, id) nk_tree_element_push_hashed(ctx, type, title, state, sel, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),id)
   2944 NK_API int nk_tree_element_push_hashed(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states initial_state, int *selected, const char *hash, int len, int seed);
   2945 NK_API int nk_tree_element_image_push_hashed(struct nk_context*, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states initial_state, int *selected, const char *hash, int len,int seed);
   2946 NK_API void nk_tree_element_pop(struct nk_context*);
   2947 
   2948 /* =============================================================================
   2949  *
   2950  *                                  LIST VIEW
   2951  *
   2952  * ============================================================================= */
   2953 struct nk_list_view {
   2954 /* public: */
   2955     int begin, end, count;
   2956 /* private: */
   2957     int total_height;
   2958     struct nk_context *ctx;
   2959     nk_uint *scroll_pointer;
   2960     nk_uint scroll_value;
   2961 };
   2962 NK_API int nk_list_view_begin(struct nk_context*, struct nk_list_view *out, const char *id, nk_flags, int row_height, int row_count);
   2963 NK_API void nk_list_view_end(struct nk_list_view*);
   2964 /* =============================================================================
   2965  *
   2966  *                                  WIDGET
   2967  *
   2968  * ============================================================================= */
   2969 enum nk_widget_layout_states {
   2970     NK_WIDGET_INVALID, /* The widget cannot be seen and is completely out of view */
   2971     NK_WIDGET_VALID, /* The widget is completely inside the window and can be updated and drawn */
   2972     NK_WIDGET_ROM /* The widget is partially visible and cannot be updated */
   2973 };
   2974 enum nk_widget_states {
   2975     NK_WIDGET_STATE_MODIFIED    = NK_FLAG(1),
   2976     NK_WIDGET_STATE_INACTIVE    = NK_FLAG(2), /* widget is neither active nor hovered */
   2977     NK_WIDGET_STATE_ENTERED     = NK_FLAG(3), /* widget has been hovered on the current frame */
   2978     NK_WIDGET_STATE_HOVER       = NK_FLAG(4), /* widget is being hovered */
   2979     NK_WIDGET_STATE_ACTIVED     = NK_FLAG(5),/* widget is currently activated */
   2980     NK_WIDGET_STATE_LEFT        = NK_FLAG(6), /* widget is from this frame on not hovered anymore */
   2981     NK_WIDGET_STATE_HOVERED     = NK_WIDGET_STATE_HOVER|NK_WIDGET_STATE_MODIFIED, /* widget is being hovered */
   2982     NK_WIDGET_STATE_ACTIVE      = NK_WIDGET_STATE_ACTIVED|NK_WIDGET_STATE_MODIFIED /* widget is currently activated */
   2983 };
   2984 NK_API enum nk_widget_layout_states nk_widget(struct nk_rect*, const struct nk_context*);
   2985 NK_API enum nk_widget_layout_states nk_widget_fitting(struct nk_rect*, struct nk_context*, struct nk_vec2);
   2986 NK_API struct nk_rect nk_widget_bounds(struct nk_context*);
   2987 NK_API struct nk_vec2 nk_widget_position(struct nk_context*);
   2988 NK_API struct nk_vec2 nk_widget_size(struct nk_context*);
   2989 NK_API float nk_widget_width(struct nk_context*);
   2990 NK_API float nk_widget_height(struct nk_context*);
   2991 NK_API int nk_widget_is_hovered(struct nk_context*);
   2992 NK_API int nk_widget_is_mouse_clicked(struct nk_context*, enum nk_buttons);
   2993 NK_API int nk_widget_has_mouse_click_down(struct nk_context*, enum nk_buttons, int down);
   2994 NK_API void nk_spacing(struct nk_context*, int cols);
   2995 /* =============================================================================
   2996  *
   2997  *                                  TEXT
   2998  *
   2999  * ============================================================================= */
   3000 enum nk_text_align {
   3001     NK_TEXT_ALIGN_LEFT        = 0x01,
   3002     NK_TEXT_ALIGN_CENTERED    = 0x02,
   3003     NK_TEXT_ALIGN_RIGHT       = 0x04,
   3004     NK_TEXT_ALIGN_TOP         = 0x08,
   3005     NK_TEXT_ALIGN_MIDDLE      = 0x10,
   3006     NK_TEXT_ALIGN_BOTTOM      = 0x20
   3007 };
   3008 enum nk_text_alignment {
   3009     NK_TEXT_LEFT        = NK_TEXT_ALIGN_MIDDLE|NK_TEXT_ALIGN_LEFT,
   3010     NK_TEXT_CENTERED    = NK_TEXT_ALIGN_MIDDLE|NK_TEXT_ALIGN_CENTERED,
   3011     NK_TEXT_RIGHT       = NK_TEXT_ALIGN_MIDDLE|NK_TEXT_ALIGN_RIGHT
   3012 };
   3013 NK_API void nk_text(struct nk_context*, const char*, int, nk_flags);
   3014 NK_API void nk_text_colored(struct nk_context*, const char*, int, nk_flags, struct nk_color);
   3015 NK_API void nk_text_wrap(struct nk_context*, const char*, int);
   3016 NK_API void nk_text_wrap_colored(struct nk_context*, const char*, int, struct nk_color);
   3017 NK_API void nk_label(struct nk_context*, const char*, nk_flags align);
   3018 NK_API void nk_label_colored(struct nk_context*, const char*, nk_flags align, struct nk_color);
   3019 NK_API void nk_label_wrap(struct nk_context*, const char*);
   3020 NK_API void nk_label_colored_wrap(struct nk_context*, const char*, struct nk_color);
   3021 NK_API void nk_image(struct nk_context*, struct nk_image);
   3022 NK_API void nk_image_color(struct nk_context*, struct nk_image, struct nk_color);
   3023 #ifdef NK_INCLUDE_STANDARD_VARARGS
   3024 NK_API void nk_labelf(struct nk_context*, nk_flags, NK_PRINTF_FORMAT_STRING const char*, ...) NK_PRINTF_VARARG_FUNC(3);
   3025 NK_API void nk_labelf_colored(struct nk_context*, nk_flags, struct nk_color, NK_PRINTF_FORMAT_STRING const char*,...) NK_PRINTF_VARARG_FUNC(4);
   3026 NK_API void nk_labelf_wrap(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*,...) NK_PRINTF_VARARG_FUNC(2);
   3027 NK_API void nk_labelf_colored_wrap(struct nk_context*, struct nk_color, NK_PRINTF_FORMAT_STRING const char*,...) NK_PRINTF_VARARG_FUNC(3);
   3028 NK_API void nk_labelfv(struct nk_context*, nk_flags, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(3);
   3029 NK_API void nk_labelfv_colored(struct nk_context*, nk_flags, struct nk_color, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(4);
   3030 NK_API void nk_labelfv_wrap(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(2);
   3031 NK_API void nk_labelfv_colored_wrap(struct nk_context*, struct nk_color, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(3);
   3032 NK_API void nk_value_bool(struct nk_context*, const char *prefix, int);
   3033 NK_API void nk_value_int(struct nk_context*, const char *prefix, int);
   3034 NK_API void nk_value_uint(struct nk_context*, const char *prefix, unsigned int);
   3035 NK_API void nk_value_float(struct nk_context*, const char *prefix, float);
   3036 NK_API void nk_value_color_byte(struct nk_context*, const char *prefix, struct nk_color);
   3037 NK_API void nk_value_color_float(struct nk_context*, const char *prefix, struct nk_color);
   3038 NK_API void nk_value_color_hex(struct nk_context*, const char *prefix, struct nk_color);
   3039 #endif
   3040 /* =============================================================================
   3041  *
   3042  *                                  BUTTON
   3043  *
   3044  * ============================================================================= */
   3045 NK_API int nk_button_text(struct nk_context*, const char *title, int len);
   3046 NK_API int nk_button_label(struct nk_context*, const char *title);
   3047 NK_API int nk_button_color(struct nk_context*, struct nk_color);
   3048 NK_API int nk_button_symbol(struct nk_context*, enum nk_symbol_type);
   3049 NK_API int nk_button_image(struct nk_context*, struct nk_image img);
   3050 NK_API int nk_button_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags text_alignment);
   3051 NK_API int nk_button_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
   3052 NK_API int nk_button_image_label(struct nk_context*, struct nk_image img, const char*, nk_flags text_alignment);
   3053 NK_API int nk_button_image_text(struct nk_context*, struct nk_image img, const char*, int, nk_flags alignment);
   3054 NK_API int nk_button_text_styled(struct nk_context*, const struct nk_style_button*, const char *title, int len);
   3055 NK_API int nk_button_label_styled(struct nk_context*, const struct nk_style_button*, const char *title);
   3056 NK_API int nk_button_symbol_styled(struct nk_context*, const struct nk_style_button*, enum nk_symbol_type);
   3057 NK_API int nk_button_image_styled(struct nk_context*, const struct nk_style_button*, struct nk_image img);
   3058 NK_API int nk_button_symbol_text_styled(struct nk_context*,const struct nk_style_button*, enum nk_symbol_type, const char*, int, nk_flags alignment);
   3059 NK_API int nk_button_symbol_label_styled(struct nk_context *ctx, const struct nk_style_button *style, enum nk_symbol_type symbol, const char *title, nk_flags align);
   3060 NK_API int nk_button_image_label_styled(struct nk_context*,const struct nk_style_button*, struct nk_image img, const char*, nk_flags text_alignment);
   3061 NK_API int nk_button_image_text_styled(struct nk_context*,const struct nk_style_button*, struct nk_image img, const char*, int, nk_flags alignment);
   3062 NK_API void nk_button_set_behavior(struct nk_context*, enum nk_button_behavior);
   3063 NK_API int nk_button_push_behavior(struct nk_context*, enum nk_button_behavior);
   3064 NK_API int nk_button_pop_behavior(struct nk_context*);
   3065 /* =============================================================================
   3066  *
   3067  *                                  CHECKBOX
   3068  *
   3069  * ============================================================================= */
   3070 NK_API int nk_check_label(struct nk_context*, const char*, int active);
   3071 NK_API int nk_check_text(struct nk_context*, const char*, int,int active);
   3072 NK_API unsigned nk_check_flags_label(struct nk_context*, const char*, unsigned int flags, unsigned int value);
   3073 NK_API unsigned nk_check_flags_text(struct nk_context*, const char*, int, unsigned int flags, unsigned int value);
   3074 NK_API int nk_checkbox_label(struct nk_context*, const char*, int *active);
   3075 NK_API int nk_checkbox_text(struct nk_context*, const char*, int, int *active);
   3076 NK_API int nk_checkbox_flags_label(struct nk_context*, const char*, unsigned int *flags, unsigned int value);
   3077 NK_API int nk_checkbox_flags_text(struct nk_context*, const char*, int, unsigned int *flags, unsigned int value);
   3078 /* =============================================================================
   3079  *
   3080  *                                  RADIO BUTTON
   3081  *
   3082  * ============================================================================= */
   3083 NK_API int nk_radio_label(struct nk_context*, const char*, int *active);
   3084 NK_API int nk_radio_text(struct nk_context*, const char*, int, int *active);
   3085 NK_API int nk_option_label(struct nk_context*, const char*, int active);
   3086 NK_API int nk_option_text(struct nk_context*, const char*, int, int active);
   3087 /* =============================================================================
   3088  *
   3089  *                                  SELECTABLE
   3090  *
   3091  * ============================================================================= */
   3092 NK_API int nk_selectable_label(struct nk_context*, const char*, nk_flags align, int *value);
   3093 NK_API int nk_selectable_text(struct nk_context*, const char*, int, nk_flags align, int *value);
   3094 NK_API int nk_selectable_image_label(struct nk_context*,struct nk_image,  const char*, nk_flags align, int *value);
   3095 NK_API int nk_selectable_image_text(struct nk_context*,struct nk_image, const char*, int, nk_flags align, int *value);
   3096 NK_API int nk_selectable_symbol_label(struct nk_context*,enum nk_symbol_type,  const char*, nk_flags align, int *value);
   3097 NK_API int nk_selectable_symbol_text(struct nk_context*,enum nk_symbol_type, const char*, int, nk_flags align, int *value);
   3098 
   3099 NK_API int nk_select_label(struct nk_context*, const char*, nk_flags align, int value);
   3100 NK_API int nk_select_text(struct nk_context*, const char*, int, nk_flags align, int value);
   3101 NK_API int nk_select_image_label(struct nk_context*, struct nk_image,const char*, nk_flags align, int value);
   3102 NK_API int nk_select_image_text(struct nk_context*, struct nk_image,const char*, int, nk_flags align, int value);
   3103 NK_API int nk_select_symbol_label(struct nk_context*,enum nk_symbol_type,  const char*, nk_flags align, int value);
   3104 NK_API int nk_select_symbol_text(struct nk_context*,enum nk_symbol_type, const char*, int, nk_flags align, int value);
   3105 
   3106 /* =============================================================================
   3107  *
   3108  *                                  SLIDER
   3109  *
   3110  * ============================================================================= */
   3111 NK_API float nk_slide_float(struct nk_context*, float min, float val, float max, float step);
   3112 NK_API int nk_slide_int(struct nk_context*, int min, int val, int max, int step);
   3113 NK_API int nk_slider_float(struct nk_context*, float min, float *val, float max, float step);
   3114 NK_API int nk_slider_int(struct nk_context*, int min, int *val, int max, int step);
   3115 /* =============================================================================
   3116  *
   3117  *                                  PROGRESSBAR
   3118  *
   3119  * ============================================================================= */
   3120 NK_API int nk_progress(struct nk_context*, nk_size *cur, nk_size max, int modifyable);
   3121 NK_API nk_size nk_prog(struct nk_context*, nk_size cur, nk_size max, int modifyable);
   3122 
   3123 /* =============================================================================
   3124  *
   3125  *                                  COLOR PICKER
   3126  *
   3127  * ============================================================================= */
   3128 NK_API struct nk_colorf nk_color_picker(struct nk_context*, struct nk_colorf, enum nk_color_format);
   3129 NK_API int nk_color_pick(struct nk_context*, struct nk_colorf*, enum nk_color_format);
   3130 /* =============================================================================
   3131  *
   3132  *                                  PROPERTIES
   3133  *
   3134  * =============================================================================
   3135 /// ### Properties
   3136 /// Properties are the main value modification widgets in Nuklear. Changing a value
   3137 /// can be achieved by dragging, adding/removing incremental steps on button click
   3138 /// or by directly typing a number.
   3139 ///
   3140 /// #### Usage
   3141 /// Each property requires a unique name for identifaction that is also used for
   3142 /// displaying a label. If you want to use the same name multiple times make sure
   3143 /// add a '#' before your name. The '#' will not be shown but will generate a
   3144 /// unique ID. Each propery also takes in a minimum and maximum value. If you want
   3145 /// to make use of the complete number range of a type just use the provided
   3146 /// type limits from `limits.h`. For example `INT_MIN` and `INT_MAX` for
   3147 /// `nk_property_int` and `nk_propertyi`. In additional each property takes in
   3148 /// a increment value that will be added or subtracted if either the increment
   3149 /// decrement button is clicked. Finally there is a value for increment per pixel
   3150 /// dragged that is added or subtracted from the value.
   3151 ///
   3152 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   3153 /// int value = 0;
   3154 /// struct nk_context ctx;
   3155 /// nk_init_xxx(&ctx, ...);
   3156 /// while (1) {
   3157 ///     // Input
   3158 ///     Event evt;
   3159 ///     nk_input_begin(&ctx);
   3160 ///     while (GetEvent(&evt)) {
   3161 ///         if (evt.type == MOUSE_MOVE)
   3162 ///             nk_input_motion(&ctx, evt.motion.x, evt.motion.y);
   3163 ///         else if (evt.type == [...]) {
   3164 ///             nk_input_xxx(...);
   3165 ///         }
   3166 ///     }
   3167 ///     nk_input_end(&ctx);
   3168 ///     //
   3169 ///     // Window
   3170 ///     if (nk_begin_xxx(...) {
   3171 ///         // Property
   3172 ///         nk_layout_row_dynamic(...);
   3173 ///         nk_property_int(ctx, "ID", INT_MIN, &value, INT_MAX, 1, 1);
   3174 ///     }
   3175 ///     nk_end(ctx);
   3176 ///     //
   3177 ///     // Draw
   3178 ///     const struct nk_command *cmd = 0;
   3179 ///     nk_foreach(cmd, &ctx) {
   3180 ///     switch (cmd->type) {
   3181 ///     case NK_COMMAND_LINE:
   3182 ///         your_draw_line_function(...)
   3183 ///         break;
   3184 ///     case NK_COMMAND_RECT
   3185 ///         your_draw_rect_function(...)
   3186 ///         break;
   3187 ///     case ...:
   3188 ///         // [...]
   3189 ///     }
   3190 //      nk_clear(&ctx);
   3191 /// }
   3192 /// nk_free(&ctx);
   3193 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   3194 ///
   3195 /// #### Reference
   3196 /// Function            | Description
   3197 /// --------------------|-------------------------------------------
   3198 /// nk_property_int     | Integer property directly modifing a passed in value
   3199 /// nk_property_float   | Float property directly modifing a passed in value
   3200 /// nk_property_double  | Double property directly modifing a passed in value
   3201 /// nk_propertyi        | Integer property returning the modified int value
   3202 /// nk_propertyf        | Float property returning the modified float value
   3203 /// nk_propertyd        | Double property returning the modified double value
   3204 ///
   3205 */
   3206 /*/// #### nk_property_int
   3207 /// Integer property directly modifing a passed in value
   3208 /// !!! WARNING
   3209 ///     To generate a unique property ID using the same label make sure to insert
   3210 ///     a `#` at the beginning. It will not be shown but guarantees correct behavior.
   3211 ///
   3212 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   3213 /// void nk_property_int(struct nk_context *ctx, const char *name, int min, int *val, int max, int step, float inc_per_pixel);
   3214 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   3215 ///
   3216 /// Parameter           | Description
   3217 /// --------------------|-----------------------------------------------------------
   3218 /// __ctx__             | Must point to an previously initialized `nk_context` struct after calling a layouting function
   3219 /// __name__            | String used both as a label as well as a unique identifier
   3220 /// __min__             | Minimum value not allowed to be underflown
   3221 /// __val__             | Integer pointer to be modified
   3222 /// __max__             | Maximum value not allowed to be overflown
   3223 /// __step__            | Increment added and subtracted on increment and decrement button
   3224 /// __inc_per_pixel__   | Value per pixel added or subtracted on dragging
   3225 */
   3226 NK_API void nk_property_int(struct nk_context*, const char *name, int min, int *val, int max, int step, float inc_per_pixel);
   3227 /*/// #### nk_property_float
   3228 /// Float property directly modifing a passed in value
   3229 /// !!! WARNING
   3230 ///     To generate a unique property ID using the same label make sure to insert
   3231 ///     a `#` at the beginning. It will not be shown but guarantees correct behavior.
   3232 ///
   3233 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   3234 /// void nk_property_float(struct nk_context *ctx, const char *name, float min, float *val, float max, float step, float inc_per_pixel);
   3235 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   3236 ///
   3237 /// Parameter           | Description
   3238 /// --------------------|-----------------------------------------------------------
   3239 /// __ctx__             | Must point to an previously initialized `nk_context` struct after calling a layouting function
   3240 /// __name__            | String used both as a label as well as a unique identifier
   3241 /// __min__             | Minimum value not allowed to be underflown
   3242 /// __val__             | Float pointer to be modified
   3243 /// __max__             | Maximum value not allowed to be overflown
   3244 /// __step__            | Increment added and subtracted on increment and decrement button
   3245 /// __inc_per_pixel__   | Value per pixel added or subtracted on dragging
   3246 */
   3247 NK_API void nk_property_float(struct nk_context*, const char *name, float min, float *val, float max, float step, float inc_per_pixel);
   3248 /*/// #### nk_property_double
   3249 /// Double property directly modifing a passed in value
   3250 /// !!! WARNING
   3251 ///     To generate a unique property ID using the same label make sure to insert
   3252 ///     a `#` at the beginning. It will not be shown but guarantees correct behavior.
   3253 ///
   3254 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   3255 /// void nk_property_double(struct nk_context *ctx, const char *name, double min, double *val, double max, double step, double inc_per_pixel);
   3256 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   3257 ///
   3258 /// Parameter           | Description
   3259 /// --------------------|-----------------------------------------------------------
   3260 /// __ctx__             | Must point to an previously initialized `nk_context` struct after calling a layouting function
   3261 /// __name__            | String used both as a label as well as a unique identifier
   3262 /// __min__             | Minimum value not allowed to be underflown
   3263 /// __val__             | Double pointer to be modified
   3264 /// __max__             | Maximum value not allowed to be overflown
   3265 /// __step__            | Increment added and subtracted on increment and decrement button
   3266 /// __inc_per_pixel__   | Value per pixel added or subtracted on dragging
   3267 */
   3268 NK_API void nk_property_double(struct nk_context*, const char *name, double min, double *val, double max, double step, float inc_per_pixel);
   3269 /*/// #### nk_propertyi
   3270 /// Integer property modifing a passed in value and returning the new value
   3271 /// !!! WARNING
   3272 ///     To generate a unique property ID using the same label make sure to insert
   3273 ///     a `#` at the beginning. It will not be shown but guarantees correct behavior.
   3274 ///
   3275 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   3276 /// int nk_propertyi(struct nk_context *ctx, const char *name, int min, int val, int max, int step, float inc_per_pixel);
   3277 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   3278 ///
   3279 /// Parameter           | Description
   3280 /// --------------------|-----------------------------------------------------------
   3281 /// __ctx__             | Must point to an previously initialized `nk_context` struct after calling a layouting function
   3282 /// __name__            | String used both as a label as well as a unique identifier
   3283 /// __min__             | Minimum value not allowed to be underflown
   3284 /// __val__             | Current integer value to be modified and returned
   3285 /// __max__             | Maximum value not allowed to be overflown
   3286 /// __step__            | Increment added and subtracted on increment and decrement button
   3287 /// __inc_per_pixel__   | Value per pixel added or subtracted on dragging
   3288 ///
   3289 /// Returns the new modified integer value
   3290 */
   3291 NK_API int nk_propertyi(struct nk_context*, const char *name, int min, int val, int max, int step, float inc_per_pixel);
   3292 /*/// #### nk_propertyf
   3293 /// Float property modifing a passed in value and returning the new value
   3294 /// !!! WARNING
   3295 ///     To generate a unique property ID using the same label make sure to insert
   3296 ///     a `#` at the beginning. It will not be shown but guarantees correct behavior.
   3297 ///
   3298 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   3299 /// float nk_propertyf(struct nk_context *ctx, const char *name, float min, float val, float max, float step, float inc_per_pixel);
   3300 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   3301 ///
   3302 /// Parameter           | Description
   3303 /// --------------------|-----------------------------------------------------------
   3304 /// __ctx__             | Must point to an previously initialized `nk_context` struct after calling a layouting function
   3305 /// __name__            | String used both as a label as well as a unique identifier
   3306 /// __min__             | Minimum value not allowed to be underflown
   3307 /// __val__             | Current float value to be modified and returned
   3308 /// __max__             | Maximum value not allowed to be overflown
   3309 /// __step__            | Increment added and subtracted on increment and decrement button
   3310 /// __inc_per_pixel__   | Value per pixel added or subtracted on dragging
   3311 ///
   3312 /// Returns the new modified float value
   3313 */
   3314 NK_API float nk_propertyf(struct nk_context*, const char *name, float min, float val, float max, float step, float inc_per_pixel);
   3315 /*/// #### nk_propertyd
   3316 /// Float property modifing a passed in value and returning the new value
   3317 /// !!! WARNING
   3318 ///     To generate a unique property ID using the same label make sure to insert
   3319 ///     a `#` at the beginning. It will not be shown but guarantees correct behavior.
   3320 ///
   3321 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
   3322 /// float nk_propertyd(struct nk_context *ctx, const char *name, double min, double val, double max, double step, double inc_per_pixel);
   3323 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   3324 ///
   3325 /// Parameter           | Description
   3326 /// --------------------|-----------------------------------------------------------
   3327 /// __ctx__             | Must point to an previously initialized `nk_context` struct after calling a layouting function
   3328 /// __name__            | String used both as a label as well as a unique identifier
   3329 /// __min__             | Minimum value not allowed to be underflown
   3330 /// __val__             | Current double value to be modified and returned
   3331 /// __max__             | Maximum value not allowed to be overflown
   3332 /// __step__            | Increment added and subtracted on increment and decrement button
   3333 /// __inc_per_pixel__   | Value per pixel added or subtracted on dragging
   3334 ///
   3335 /// Returns the new modified double value
   3336 */
   3337 NK_API double nk_propertyd(struct nk_context*, const char *name, double min, double val, double max, double step, float inc_per_pixel);
   3338 /* =============================================================================
   3339  *
   3340  *                                  TEXT EDIT
   3341  *
   3342  * ============================================================================= */
   3343 enum nk_edit_flags {
   3344     NK_EDIT_DEFAULT                 = 0,
   3345     NK_EDIT_READ_ONLY               = NK_FLAG(0),
   3346     NK_EDIT_AUTO_SELECT             = NK_FLAG(1),
   3347     NK_EDIT_SIG_ENTER               = NK_FLAG(2),
   3348     NK_EDIT_ALLOW_TAB               = NK_FLAG(3),
   3349     NK_EDIT_NO_CURSOR               = NK_FLAG(4),
   3350     NK_EDIT_SELECTABLE              = NK_FLAG(5),
   3351     NK_EDIT_CLIPBOARD               = NK_FLAG(6),
   3352     NK_EDIT_CTRL_ENTER_NEWLINE      = NK_FLAG(7),
   3353     NK_EDIT_NO_HORIZONTAL_SCROLL    = NK_FLAG(8),
   3354     NK_EDIT_ALWAYS_INSERT_MODE      = NK_FLAG(9),
   3355     NK_EDIT_MULTILINE               = NK_FLAG(10),
   3356     NK_EDIT_GOTO_END_ON_ACTIVATE    = NK_FLAG(11)
   3357 };
   3358 enum nk_edit_types {
   3359     NK_EDIT_SIMPLE  = NK_EDIT_ALWAYS_INSERT_MODE,
   3360     NK_EDIT_FIELD   = NK_EDIT_SIMPLE|NK_EDIT_SELECTABLE|NK_EDIT_CLIPBOARD,
   3361     NK_EDIT_BOX     = NK_EDIT_ALWAYS_INSERT_MODE| NK_EDIT_SELECTABLE| NK_EDIT_MULTILINE|NK_EDIT_ALLOW_TAB|NK_EDIT_CLIPBOARD,
   3362     NK_EDIT_EDITOR  = NK_EDIT_SELECTABLE|NK_EDIT_MULTILINE|NK_EDIT_ALLOW_TAB| NK_EDIT_CLIPBOARD
   3363 };
   3364 enum nk_edit_events {
   3365     NK_EDIT_ACTIVE      = NK_FLAG(0), /* edit widget is currently being modified */
   3366     NK_EDIT_INACTIVE    = NK_FLAG(1), /* edit widget is not active and is not being modified */
   3367     NK_EDIT_ACTIVATED   = NK_FLAG(2), /* edit widget went from state inactive to state active */
   3368     NK_EDIT_DEACTIVATED = NK_FLAG(3), /* edit widget went from state active to state inactive */
   3369     NK_EDIT_COMMITED    = NK_FLAG(4) /* edit widget has received an enter and lost focus */
   3370 };
   3371 NK_API nk_flags nk_edit_string(struct nk_context*, nk_flags, char *buffer, int *len, int max, nk_plugin_filter);
   3372 NK_API nk_flags nk_edit_string_zero_terminated(struct nk_context*, nk_flags, char *buffer, int max, nk_plugin_filter);
   3373 NK_API nk_flags nk_edit_buffer(struct nk_context*, nk_flags, struct nk_text_edit*, nk_plugin_filter);
   3374 NK_API void nk_edit_focus(struct nk_context*, nk_flags flags);
   3375 NK_API void nk_edit_unfocus(struct nk_context*);
   3376 /* =============================================================================
   3377  *
   3378  *                                  CHART
   3379  *
   3380  * ============================================================================= */
   3381 NK_API int nk_chart_begin(struct nk_context*, enum nk_chart_type, int num, float min, float max);
   3382 NK_API int nk_chart_begin_colored(struct nk_context*, enum nk_chart_type, struct nk_color, struct nk_color active, int num, float min, float max);
   3383 NK_API void nk_chart_add_slot(struct nk_context *ctx, const enum nk_chart_type, int count, float min_value, float max_value);
   3384 NK_API void nk_chart_add_slot_colored(struct nk_context *ctx, const enum nk_chart_type, struct nk_color, struct nk_color active, int count, float min_value, float max_value);
   3385 NK_API nk_flags nk_chart_push(struct nk_context*, float);
   3386 NK_API nk_flags nk_chart_push_slot(struct nk_context*, float, int);
   3387 NK_API void nk_chart_end(struct nk_context*);
   3388 NK_API void nk_plot(struct nk_context*, enum nk_chart_type, const float *values, int count, int offset);
   3389 NK_API void nk_plot_function(struct nk_context*, enum nk_chart_type, void *userdata, float(*value_getter)(void* user, int index), int count, int offset);
   3390 /* =============================================================================
   3391  *
   3392  *                                  POPUP
   3393  *
   3394  * ============================================================================= */
   3395 NK_API int nk_popup_begin(struct nk_context*, enum nk_popup_type, const char*, nk_flags, struct nk_rect bounds);
   3396 NK_API void nk_popup_close(struct nk_context*);
   3397 NK_API void nk_popup_end(struct nk_context*);
   3398 /* =============================================================================
   3399  *
   3400  *                                  COMBOBOX
   3401  *
   3402  * ============================================================================= */
   3403 NK_API int nk_combo(struct nk_context*, const char **items, int count, int selected, int item_height, struct nk_vec2 size);
   3404 NK_API int nk_combo_separator(struct nk_context*, const char *items_separated_by_separator, int separator, int selected, int count, int item_height, struct nk_vec2 size);
   3405 NK_API int nk_combo_string(struct nk_context*, const char *items_separated_by_zeros, int selected, int count, int item_height, struct nk_vec2 size);
   3406 NK_API int nk_combo_callback(struct nk_context*, void(*item_getter)(void*, int, const char**), void *userdata, int selected, int count, int item_height, struct nk_vec2 size);
   3407 NK_API void nk_combobox(struct nk_context*, const char **items, int count, int *selected, int item_height, struct nk_vec2 size);
   3408 NK_API void nk_combobox_string(struct nk_context*, const char *items_separated_by_zeros, int *selected, int count, int item_height, struct nk_vec2 size);
   3409 NK_API void nk_combobox_separator(struct nk_context*, const char *items_separated_by_separator, int separator,int *selected, int count, int item_height, struct nk_vec2 size);
   3410 NK_API void nk_combobox_callback(struct nk_context*, void(*item_getter)(void*, int, const char**), void*, int *selected, int count, int item_height, struct nk_vec2 size);
   3411 /* =============================================================================
   3412  *
   3413  *                                  ABSTRACT COMBOBOX
   3414  *
   3415  * ============================================================================= */
   3416 NK_API int nk_combo_begin_text(struct nk_context*, const char *selected, int, struct nk_vec2 size);
   3417 NK_API int nk_combo_begin_label(struct nk_context*, const char *selected, struct nk_vec2 size);
   3418 NK_API int nk_combo_begin_color(struct nk_context*, struct nk_color color, struct nk_vec2 size);
   3419 NK_API int nk_combo_begin_symbol(struct nk_context*,  enum nk_symbol_type,  struct nk_vec2 size);
   3420 NK_API int nk_combo_begin_symbol_label(struct nk_context*, const char *selected, enum nk_symbol_type, struct nk_vec2 size);
   3421 NK_API int nk_combo_begin_symbol_text(struct nk_context*, const char *selected, int, enum nk_symbol_type, struct nk_vec2 size);
   3422 NK_API int nk_combo_begin_image(struct nk_context*, struct nk_image img,  struct nk_vec2 size);
   3423 NK_API int nk_combo_begin_image_label(struct nk_context*, const char *selected, struct nk_image, struct nk_vec2 size);
   3424 NK_API int nk_combo_begin_image_text(struct nk_context*,  const char *selected, int, struct nk_image, struct nk_vec2 size);
   3425 NK_API int nk_combo_item_label(struct nk_context*, const char*, nk_flags alignment);
   3426 NK_API int nk_combo_item_text(struct nk_context*, const char*,int, nk_flags alignment);
   3427 NK_API int nk_combo_item_image_label(struct nk_context*, struct nk_image, const char*, nk_flags alignment);
   3428 NK_API int nk_combo_item_image_text(struct nk_context*, struct nk_image, const char*, int,nk_flags alignment);
   3429 NK_API int nk_combo_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags alignment);
   3430 NK_API int nk_combo_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
   3431 NK_API void nk_combo_close(struct nk_context*);
   3432 NK_API void nk_combo_end(struct nk_context*);
   3433 /* =============================================================================
   3434  *
   3435  *                                  CONTEXTUAL
   3436  *
   3437  * ============================================================================= */
   3438 NK_API int nk_contextual_begin(struct nk_context*, nk_flags, struct nk_vec2, struct nk_rect trigger_bounds);
   3439 NK_API int nk_contextual_item_text(struct nk_context*, const char*, int,nk_flags align);
   3440 NK_API int nk_contextual_item_label(struct nk_context*, const char*, nk_flags align);
   3441 NK_API int nk_contextual_item_image_label(struct nk_context*, struct nk_image, const char*, nk_flags alignment);
   3442 NK_API int nk_contextual_item_image_text(struct nk_context*, struct nk_image, const char*, int len, nk_flags alignment);
   3443 NK_API int nk_contextual_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags alignment);
   3444 NK_API int nk_contextual_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
   3445 NK_API void nk_contextual_close(struct nk_context*);
   3446 NK_API void nk_contextual_end(struct nk_context*);
   3447 /* =============================================================================
   3448  *
   3449  *                                  TOOLTIP
   3450  *
   3451  * ============================================================================= */
   3452 NK_API void nk_tooltip(struct nk_context*, const char*);
   3453 #ifdef NK_INCLUDE_STANDARD_VARARGS
   3454 NK_API void nk_tooltipf(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*, ...) NK_PRINTF_VARARG_FUNC(2);
   3455 NK_API void nk_tooltipfv(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(2);
   3456 #endif
   3457 NK_API int nk_tooltip_begin(struct nk_context*, float width);
   3458 NK_API void nk_tooltip_end(struct nk_context*);
   3459 /* =============================================================================
   3460  *
   3461  *                                  MENU
   3462  *
   3463  * ============================================================================= */
   3464 NK_API void nk_menubar_begin(struct nk_context*);
   3465 NK_API void nk_menubar_end(struct nk_context*);
   3466 NK_API int nk_menu_begin_text(struct nk_context*, const char* title, int title_len, nk_flags align, struct nk_vec2 size);
   3467 NK_API int nk_menu_begin_label(struct nk_context*, const char*, nk_flags align, struct nk_vec2 size);
   3468 NK_API int nk_menu_begin_image(struct nk_context*, const char*, struct nk_image, struct nk_vec2 size);
   3469 NK_API int nk_menu_begin_image_text(struct nk_context*, const char*, int,nk_flags align,struct nk_image, struct nk_vec2 size);
   3470 NK_API int nk_menu_begin_image_label(struct nk_context*, const char*, nk_flags align,struct nk_image, struct nk_vec2 size);
   3471 NK_API int nk_menu_begin_symbol(struct nk_context*, const char*, enum nk_symbol_type, struct nk_vec2 size);
   3472 NK_API int nk_menu_begin_symbol_text(struct nk_context*, const char*, int,nk_flags align,enum nk_symbol_type, struct nk_vec2 size);
   3473 NK_API int nk_menu_begin_symbol_label(struct nk_context*, const char*, nk_flags align,enum nk_symbol_type, struct nk_vec2 size);
   3474 NK_API int nk_menu_item_text(struct nk_context*, const char*, int,nk_flags align);
   3475 NK_API int nk_menu_item_label(struct nk_context*, const char*, nk_flags alignment);
   3476 NK_API int nk_menu_item_image_label(struct nk_context*, struct nk_image, const char*, nk_flags alignment);
   3477 NK_API int nk_menu_item_image_text(struct nk_context*, struct nk_image, const char*, int len, nk_flags alignment);
   3478 NK_API int nk_menu_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
   3479 NK_API int nk_menu_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags alignment);
   3480 NK_API void nk_menu_close(struct nk_context*);
   3481 NK_API void nk_menu_end(struct nk_context*);
   3482 /* =============================================================================
   3483  *
   3484  *                                  STYLE
   3485  *
   3486  * ============================================================================= */
   3487 enum nk_style_colors {
   3488     NK_COLOR_TEXT,
   3489     NK_COLOR_WINDOW,
   3490     NK_COLOR_HEADER,
   3491     NK_COLOR_BORDER,
   3492     NK_COLOR_BUTTON,
   3493     NK_COLOR_BUTTON_HOVER,
   3494     NK_COLOR_BUTTON_ACTIVE,
   3495     NK_COLOR_TOGGLE,
   3496     NK_COLOR_TOGGLE_HOVER,
   3497     NK_COLOR_TOGGLE_CURSOR,
   3498     NK_COLOR_SELECT,
   3499     NK_COLOR_SELECT_ACTIVE,
   3500     NK_COLOR_SLIDER,
   3501     NK_COLOR_SLIDER_CURSOR,
   3502     NK_COLOR_SLIDER_CURSOR_HOVER,
   3503     NK_COLOR_SLIDER_CURSOR_ACTIVE,
   3504     NK_COLOR_PROPERTY,
   3505     NK_COLOR_EDIT,
   3506     NK_COLOR_EDIT_CURSOR,
   3507     NK_COLOR_COMBO,
   3508     NK_COLOR_CHART,
   3509     NK_COLOR_CHART_COLOR,
   3510     NK_COLOR_CHART_COLOR_HIGHLIGHT,
   3511     NK_COLOR_SCROLLBAR,
   3512     NK_COLOR_SCROLLBAR_CURSOR,
   3513     NK_COLOR_SCROLLBAR_CURSOR_HOVER,
   3514     NK_COLOR_SCROLLBAR_CURSOR_ACTIVE,
   3515     NK_COLOR_TAB_HEADER,
   3516     NK_COLOR_COUNT
   3517 };
   3518 enum nk_style_cursor {
   3519     NK_CURSOR_ARROW,
   3520     NK_CURSOR_TEXT,
   3521     NK_CURSOR_MOVE,
   3522     NK_CURSOR_RESIZE_VERTICAL,
   3523     NK_CURSOR_RESIZE_HORIZONTAL,
   3524     NK_CURSOR_RESIZE_TOP_LEFT_DOWN_RIGHT,
   3525     NK_CURSOR_RESIZE_TOP_RIGHT_DOWN_LEFT,
   3526     NK_CURSOR_COUNT
   3527 };
   3528 NK_API void nk_style_default(struct nk_context*);
   3529 NK_API void nk_style_from_table(struct nk_context*, const struct nk_color*);
   3530 NK_API void nk_style_load_cursor(struct nk_context*, enum nk_style_cursor, const struct nk_cursor*);
   3531 NK_API void nk_style_load_all_cursors(struct nk_context*, struct nk_cursor*);
   3532 NK_API const char* nk_style_get_color_by_name(enum nk_style_colors);
   3533 NK_API void nk_style_set_font(struct nk_context*, const struct nk_user_font*);
   3534 NK_API int nk_style_set_cursor(struct nk_context*, enum nk_style_cursor);
   3535 NK_API void nk_style_show_cursor(struct nk_context*);
   3536 NK_API void nk_style_hide_cursor(struct nk_context*);
   3537 
   3538 NK_API int nk_style_push_font(struct nk_context*, const struct nk_user_font*);
   3539 NK_API int nk_style_push_float(struct nk_context*, float*, float);
   3540 NK_API int nk_style_push_vec2(struct nk_context*, struct nk_vec2*, struct nk_vec2);
   3541 NK_API int nk_style_push_style_item(struct nk_context*, struct nk_style_item*, struct nk_style_item);
   3542 NK_API int nk_style_push_flags(struct nk_context*, nk_flags*, nk_flags);
   3543 NK_API int nk_style_push_color(struct nk_context*, struct nk_color*, struct nk_color);
   3544 
   3545 NK_API int nk_style_pop_font(struct nk_context*);
   3546 NK_API int nk_style_pop_float(struct nk_context*);
   3547 NK_API int nk_style_pop_vec2(struct nk_context*);
   3548 NK_API int nk_style_pop_style_item(struct nk_context*);
   3549 NK_API int nk_style_pop_flags(struct nk_context*);
   3550 NK_API int nk_style_pop_color(struct nk_context*);
   3551 /* =============================================================================
   3552  *
   3553  *                                  COLOR
   3554  *
   3555  * ============================================================================= */
   3556 NK_API struct nk_color nk_rgb(int r, int g, int b);
   3557 NK_API struct nk_color nk_rgb_iv(const int *rgb);
   3558 NK_API struct nk_color nk_rgb_bv(const nk_byte* rgb);
   3559 NK_API struct nk_color nk_rgb_f(float r, float g, float b);
   3560 NK_API struct nk_color nk_rgb_fv(const float *rgb);
   3561 NK_API struct nk_color nk_rgb_cf(struct nk_colorf c);
   3562 NK_API struct nk_color nk_rgb_hex(const char *rgb);
   3563 
   3564 NK_API struct nk_color nk_rgba(int r, int g, int b, int a);
   3565 NK_API struct nk_color nk_rgba_u32(nk_uint);
   3566 NK_API struct nk_color nk_rgba_iv(const int *rgba);
   3567 NK_API struct nk_color nk_rgba_bv(const nk_byte *rgba);
   3568 NK_API struct nk_color nk_rgba_f(float r, float g, float b, float a);
   3569 NK_API struct nk_color nk_rgba_fv(const float *rgba);
   3570 NK_API struct nk_color nk_rgba_cf(struct nk_colorf c);
   3571 NK_API struct nk_color nk_rgba_hex(const char *rgb);
   3572 
   3573 NK_API struct nk_colorf nk_hsva_colorf(float h, float s, float v, float a);
   3574 NK_API struct nk_colorf nk_hsva_colorfv(float *c);
   3575 NK_API void nk_colorf_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_colorf in);
   3576 NK_API void nk_colorf_hsva_fv(float *hsva, struct nk_colorf in);
   3577 
   3578 NK_API struct nk_color nk_hsv(int h, int s, int v);
   3579 NK_API struct nk_color nk_hsv_iv(const int *hsv);
   3580 NK_API struct nk_color nk_hsv_bv(const nk_byte *hsv);
   3581 NK_API struct nk_color nk_hsv_f(float h, float s, float v);
   3582 NK_API struct nk_color nk_hsv_fv(const float *hsv);
   3583 
   3584 NK_API struct nk_color nk_hsva(int h, int s, int v, int a);
   3585 NK_API struct nk_color nk_hsva_iv(const int *hsva);
   3586 NK_API struct nk_color nk_hsva_bv(const nk_byte *hsva);
   3587 NK_API struct nk_color nk_hsva_f(float h, float s, float v, float a);
   3588 NK_API struct nk_color nk_hsva_fv(const float *hsva);
   3589 
   3590 /* color (conversion nuklear --> user) */
   3591 NK_API void nk_color_f(float *r, float *g, float *b, float *a, struct nk_color);
   3592 NK_API void nk_color_fv(float *rgba_out, struct nk_color);
   3593 NK_API struct nk_colorf nk_color_cf(struct nk_color);
   3594 NK_API void nk_color_d(double *r, double *g, double *b, double *a, struct nk_color);
   3595 NK_API void nk_color_dv(double *rgba_out, struct nk_color);
   3596 
   3597 NK_API nk_uint nk_color_u32(struct nk_color);
   3598 NK_API void nk_color_hex_rgba(char *output, struct nk_color);
   3599 NK_API void nk_color_hex_rgb(char *output, struct nk_color);
   3600 
   3601 NK_API void nk_color_hsv_i(int *out_h, int *out_s, int *out_v, struct nk_color);
   3602 NK_API void nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v, struct nk_color);
   3603 NK_API void nk_color_hsv_iv(int *hsv_out, struct nk_color);
   3604 NK_API void nk_color_hsv_bv(nk_byte *hsv_out, struct nk_color);
   3605 NK_API void nk_color_hsv_f(float *out_h, float *out_s, float *out_v, struct nk_color);
   3606 NK_API void nk_color_hsv_fv(float *hsv_out, struct nk_color);
   3607 
   3608 NK_API void nk_color_hsva_i(int *h, int *s, int *v, int *a, struct nk_color);
   3609 NK_API void nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a, struct nk_color);
   3610 NK_API void nk_color_hsva_iv(int *hsva_out, struct nk_color);
   3611 NK_API void nk_color_hsva_bv(nk_byte *hsva_out, struct nk_color);
   3612 NK_API void nk_color_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_color);
   3613 NK_API void nk_color_hsva_fv(float *hsva_out, struct nk_color);
   3614 /* =============================================================================
   3615  *
   3616  *                                  IMAGE
   3617  *
   3618  * ============================================================================= */
   3619 NK_API nk_handle nk_handle_ptr(void*);
   3620 NK_API nk_handle nk_handle_id(int);
   3621 NK_API struct nk_image nk_image_handle(nk_handle);
   3622 NK_API struct nk_image nk_image_ptr(void*);
   3623 NK_API struct nk_image nk_image_id(int);
   3624 NK_API int nk_image_is_subimage(const struct nk_image* img);
   3625 NK_API struct nk_image nk_subimage_ptr(void*, unsigned short w, unsigned short h, struct nk_rect sub_region);
   3626 NK_API struct nk_image nk_subimage_id(int, unsigned short w, unsigned short h, struct nk_rect sub_region);
   3627 NK_API struct nk_image nk_subimage_handle(nk_handle, unsigned short w, unsigned short h, struct nk_rect sub_region);
   3628 /* =============================================================================
   3629  *
   3630  *                                  MATH
   3631  *
   3632  * ============================================================================= */
   3633 NK_API nk_hash nk_murmur_hash(const void *key, int len, nk_hash seed);
   3634 NK_API void nk_triangle_from_direction(struct nk_vec2 *result, struct nk_rect r, float pad_x, float pad_y, enum nk_heading);
   3635 
   3636 NK_API struct nk_vec2 nk_vec2(float x, float y);
   3637 NK_API struct nk_vec2 nk_vec2i(int x, int y);
   3638 NK_API struct nk_vec2 nk_vec2v(const float *xy);
   3639 NK_API struct nk_vec2 nk_vec2iv(const int *xy);
   3640 
   3641 NK_API struct nk_rect nk_get_null_rect(void);
   3642 NK_API struct nk_rect nk_rect(float x, float y, float w, float h);
   3643 NK_API struct nk_rect nk_recti(int x, int y, int w, int h);
   3644 NK_API struct nk_rect nk_recta(struct nk_vec2 pos, struct nk_vec2 size);
   3645 NK_API struct nk_rect nk_rectv(const float *xywh);
   3646 NK_API struct nk_rect nk_rectiv(const int *xywh);
   3647 NK_API struct nk_vec2 nk_rect_pos(struct nk_rect);
   3648 NK_API struct nk_vec2 nk_rect_size(struct nk_rect);
   3649 /* =============================================================================
   3650  *
   3651  *                                  STRING
   3652  *
   3653  * ============================================================================= */
   3654 NK_API int nk_strlen(const char *str);
   3655 NK_API int nk_stricmp(const char *s1, const char *s2);
   3656 NK_API int nk_stricmpn(const char *s1, const char *s2, int n);
   3657 NK_API int nk_strtoi(const char *str, const char **endptr);
   3658 NK_API float nk_strtof(const char *str, const char **endptr);
   3659 NK_API double nk_strtod(const char *str, const char **endptr);
   3660 NK_API int nk_strfilter(const char *text, const char *regexp);
   3661 NK_API int nk_strmatch_fuzzy_string(char const *str, char const *pattern, int *out_score);
   3662 NK_API int nk_strmatch_fuzzy_text(const char *txt, int txt_len, const char *pattern, int *out_score);
   3663 /* =============================================================================
   3664  *
   3665  *                                  UTF-8
   3666  *
   3667  * ============================================================================= */
   3668 NK_API int nk_utf_decode(const char*, nk_rune*, int);
   3669 NK_API int nk_utf_encode(nk_rune, char*, int);
   3670 NK_API int nk_utf_len(const char*, int byte_len);
   3671 NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune *unicode, int *len);
   3672 /* ===============================================================
   3673  *
   3674  *                          FONT
   3675  *
   3676  * ===============================================================*/
   3677 /*  Font handling in this library was designed to be quite customizable and lets
   3678     you decide what you want to use and what you want to provide. There are three
   3679     different ways to use the font atlas. The first two will use your font
   3680     handling scheme and only requires essential data to run nuklear. The next
   3681     slightly more advanced features is font handling with vertex buffer output.
   3682     Finally the most complex API wise is using nuklear's font baking API.
   3683 
   3684     1.) Using your own implementation without vertex buffer output
   3685     --------------------------------------------------------------
   3686     So first up the easiest way to do font handling is by just providing a
   3687     `nk_user_font` struct which only requires the height in pixel of the used
   3688     font and a callback to calculate the width of a string. This way of handling
   3689     fonts is best fitted for using the normal draw shape command API where you
   3690     do all the text drawing yourself and the library does not require any kind
   3691     of deeper knowledge about which font handling mechanism you use.
   3692     IMPORTANT: the `nk_user_font` pointer provided to nuklear has to persist
   3693     over the complete life time! I know this sucks but it is currently the only
   3694     way to switch between fonts.
   3695 
   3696         float your_text_width_calculation(nk_handle handle, float height, const char *text, int len)
   3697         {
   3698             your_font_type *type = handle.ptr;
   3699             float text_width = ...;
   3700             return text_width;
   3701         }
   3702 
   3703         struct nk_user_font font;
   3704         font.userdata.ptr = &your_font_class_or_struct;
   3705         font.height = your_font_height;
   3706         font.width = your_text_width_calculation;
   3707 
   3708         struct nk_context ctx;
   3709         nk_init_default(&ctx, &font);
   3710 
   3711     2.) Using your own implementation with vertex buffer output
   3712     --------------------------------------------------------------
   3713     While the first approach works fine if you don't want to use the optional
   3714     vertex buffer output it is not enough if you do. To get font handling working
   3715     for these cases you have to provide two additional parameters inside the
   3716     `nk_user_font`. First a texture atlas handle used to draw text as subimages
   3717     of a bigger font atlas texture and a callback to query a character's glyph
   3718     information (offset, size, ...). So it is still possible to provide your own
   3719     font and use the vertex buffer output.
   3720 
   3721         float your_text_width_calculation(nk_handle handle, float height, const char *text, int len)
   3722         {
   3723             your_font_type *type = handle.ptr;
   3724             float text_width = ...;
   3725             return text_width;
   3726         }
   3727         void query_your_font_glyph(nk_handle handle, float font_height, struct nk_user_font_glyph *glyph, nk_rune codepoint, nk_rune next_codepoint)
   3728         {
   3729             your_font_type *type = handle.ptr;
   3730             glyph.width = ...;
   3731             glyph.height = ...;
   3732             glyph.xadvance = ...;
   3733             glyph.uv[0].x = ...;
   3734             glyph.uv[0].y = ...;
   3735             glyph.uv[1].x = ...;
   3736             glyph.uv[1].y = ...;
   3737             glyph.offset.x = ...;
   3738             glyph.offset.y = ...;
   3739         }
   3740 
   3741         struct nk_user_font font;
   3742         font.userdata.ptr = &your_font_class_or_struct;
   3743         font.height = your_font_height;
   3744         font.width = your_text_width_calculation;
   3745         font.query = query_your_font_glyph;
   3746         font.texture.id = your_font_texture;
   3747 
   3748         struct nk_context ctx;
   3749         nk_init_default(&ctx, &font);
   3750 
   3751     3.) Nuklear font baker
   3752     ------------------------------------
   3753     The final approach if you do not have a font handling functionality or don't
   3754     want to use it in this library is by using the optional font baker.
   3755     The font baker APIs can be used to create a font plus font atlas texture
   3756     and can be used with or without the vertex buffer output.
   3757 
   3758     It still uses the `nk_user_font` struct and the two different approaches
   3759     previously stated still work. The font baker is not located inside
   3760     `nk_context` like all other systems since it can be understood as more of
   3761     an extension to nuklear and does not really depend on any `nk_context` state.
   3762 
   3763     Font baker need to be initialized first by one of the nk_font_atlas_init_xxx
   3764     functions. If you don't care about memory just call the default version
   3765     `nk_font_atlas_init_default` which will allocate all memory from the standard library.
   3766     If you want to control memory allocation but you don't care if the allocated
   3767     memory is temporary and therefore can be freed directly after the baking process
   3768     is over or permanent you can call `nk_font_atlas_init`.
   3769 
   3770     After successfully initializing the font baker you can add Truetype(.ttf) fonts from
   3771     different sources like memory or from file by calling one of the `nk_font_atlas_add_xxx`.
   3772     functions. Adding font will permanently store each font, font config and ttf memory block(!)
   3773     inside the font atlas and allows to reuse the font atlas. If you don't want to reuse
   3774     the font baker by for example adding additional fonts you can call
   3775     `nk_font_atlas_cleanup` after the baking process is over (after calling nk_font_atlas_end).
   3776 
   3777     As soon as you added all fonts you wanted you can now start the baking process
   3778     for every selected glyph to image by calling `nk_font_atlas_bake`.
   3779     The baking process returns image memory, width and height which can be used to
   3780     either create your own image object or upload it to any graphics library.
   3781     No matter which case you finally have to call `nk_font_atlas_end` which
   3782     will free all temporary memory including the font atlas image so make sure
   3783     you created our texture beforehand. `nk_font_atlas_end` requires a handle
   3784     to your font texture or object and optionally fills a `struct nk_draw_null_texture`
   3785     which can be used for the optional vertex output. If you don't want it just
   3786     set the argument to `NULL`.
   3787 
   3788     At this point you are done and if you don't want to reuse the font atlas you
   3789     can call `nk_font_atlas_cleanup` to free all truetype blobs and configuration
   3790     memory. Finally if you don't use the font atlas and any of it's fonts anymore
   3791     you need to call `nk_font_atlas_clear` to free all memory still being used.
   3792 
   3793         struct nk_font_atlas atlas;
   3794         nk_font_atlas_init_default(&atlas);
   3795         nk_font_atlas_begin(&atlas);
   3796         nk_font *font = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font.ttf", 13, 0);
   3797         nk_font *font2 = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font2.ttf", 16, 0);
   3798         const void* img = nk_font_atlas_bake(&atlas, &img_width, &img_height, NK_FONT_ATLAS_RGBA32);
   3799         nk_font_atlas_end(&atlas, nk_handle_id(texture), 0);
   3800 
   3801         struct nk_context ctx;
   3802         nk_init_default(&ctx, &font->handle);
   3803         while (1) {
   3804 
   3805         }
   3806         nk_font_atlas_clear(&atlas);
   3807 
   3808     The font baker API is probably the most complex API inside this library and
   3809     I would suggest reading some of my examples `example/` to get a grip on how
   3810     to use the font atlas. There are a number of details I left out. For example
   3811     how to merge fonts, configure a font with `nk_font_config` to use other languages,
   3812     use another texture coordinate format and a lot more:
   3813 
   3814         struct nk_font_config cfg = nk_font_config(font_pixel_height);
   3815         cfg.merge_mode = nk_false or nk_true;
   3816         cfg.range = nk_font_korean_glyph_ranges();
   3817         cfg.coord_type = NK_COORD_PIXEL;
   3818         nk_font *font = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font.ttf", 13, &cfg);
   3819 
   3820 */
   3821 struct nk_user_font_glyph;
   3822 typedef float(*nk_text_width_f)(nk_handle, float h, const char*, int len);
   3823 typedef void(*nk_query_font_glyph_f)(nk_handle handle, float font_height,
   3824                                     struct nk_user_font_glyph *glyph,
   3825                                     nk_rune codepoint, nk_rune next_codepoint);
   3826 
   3827 #if defined(NK_INCLUDE_VERTEX_BUFFER_OUTPUT) || defined(NK_INCLUDE_SOFTWARE_FONT)
   3828 struct nk_user_font_glyph {
   3829     struct nk_vec2 uv[2];
   3830     /* texture coordinates */
   3831     struct nk_vec2 offset;
   3832     /* offset between top left and glyph */
   3833     float width, height;
   3834     /* size of the glyph  */
   3835     float xadvance;
   3836     /* offset to the next glyph */
   3837 };
   3838 #endif
   3839 
   3840 struct nk_user_font {
   3841     nk_handle userdata;
   3842     /* user provided font handle */
   3843     float height;
   3844     /* max height of the font */
   3845     nk_text_width_f width;
   3846     /* font string width in pixel callback */
   3847 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
   3848     nk_query_font_glyph_f query;
   3849     /* font glyph callback to query drawing info */
   3850     nk_handle texture;
   3851     /* texture handle to the used font atlas or texture */
   3852 #endif
   3853 };
   3854 
   3855 #ifdef NK_INCLUDE_FONT_BAKING
   3856 enum nk_font_coord_type {
   3857     NK_COORD_UV, /* texture coordinates inside font glyphs are clamped between 0-1 */
   3858     NK_COORD_PIXEL /* texture coordinates inside font glyphs are in absolute pixel */
   3859 };
   3860 
   3861 struct nk_font;
   3862 struct nk_baked_font {
   3863     float height;
   3864     /* height of the font  */
   3865     float ascent, descent;
   3866     /* font glyphs ascent and descent  */
   3867     nk_rune glyph_offset;
   3868     /* glyph array offset inside the font glyph baking output array  */
   3869     nk_rune glyph_count;
   3870     /* number of glyphs of this font inside the glyph baking array output */
   3871     const nk_rune *ranges;
   3872     /* font codepoint ranges as pairs of (from/to) and 0 as last element */
   3873 };
   3874 
   3875 struct nk_font_config {
   3876     struct nk_font_config *next;
   3877     /* NOTE: only used internally */
   3878     void *ttf_blob;
   3879     /* pointer to loaded TTF file memory block.
   3880      * NOTE: not needed for nk_font_atlas_add_from_memory and nk_font_atlas_add_from_file. */
   3881     nk_size ttf_size;
   3882     /* size of the loaded TTF file memory block
   3883      * NOTE: not needed for nk_font_atlas_add_from_memory and nk_font_atlas_add_from_file. */
   3884 
   3885     unsigned char ttf_data_owned_by_atlas;
   3886     /* used inside font atlas: default to: 0*/
   3887     unsigned char merge_mode;
   3888     /* merges this font into the last font */
   3889     unsigned char pixel_snap;
   3890     /* align every character to pixel boundary (if true set oversample (1,1)) */
   3891     unsigned char oversample_v, oversample_h;
   3892     /* rasterize at hight quality for sub-pixel position */
   3893     unsigned char padding[3];
   3894 
   3895     float size;
   3896     /* baked pixel height of the font */
   3897     enum nk_font_coord_type coord_type;
   3898     /* texture coordinate format with either pixel or UV coordinates */
   3899     struct nk_vec2 spacing;
   3900     /* extra pixel spacing between glyphs  */
   3901     const nk_rune *range;
   3902     /* list of unicode ranges (2 values per range, zero terminated) */
   3903     struct nk_baked_font *font;
   3904     /* font to setup in the baking process: NOTE: not needed for font atlas */
   3905     nk_rune fallback_glyph;
   3906     /* fallback glyph to use if a given rune is not found */
   3907     struct nk_font_config *n;
   3908     struct nk_font_config *p;
   3909 };
   3910 
   3911 struct nk_font_glyph {
   3912     nk_rune codepoint;
   3913     float xadvance;
   3914     float x0, y0, x1, y1, w, h;
   3915     float u0, v0, u1, v1;
   3916 };
   3917 
   3918 struct nk_font {
   3919     struct nk_font *next;
   3920     struct nk_user_font handle;
   3921     struct nk_baked_font info;
   3922     float scale;
   3923     struct nk_font_glyph *glyphs;
   3924     const struct nk_font_glyph *fallback;
   3925     nk_rune fallback_codepoint;
   3926     nk_handle texture;
   3927     struct nk_font_config *config;
   3928 };
   3929 
   3930 enum nk_font_atlas_format {
   3931     NK_FONT_ATLAS_ALPHA8,
   3932     NK_FONT_ATLAS_RGBA32
   3933 };
   3934 
   3935 struct nk_font_atlas {
   3936     void *pixel;
   3937     int tex_width;
   3938     int tex_height;
   3939 
   3940     struct nk_allocator permanent;
   3941     struct nk_allocator temporary;
   3942 
   3943     struct nk_recti custom;
   3944     struct nk_cursor cursors[NK_CURSOR_COUNT];
   3945 
   3946     int glyph_count;
   3947     struct nk_font_glyph *glyphs;
   3948     struct nk_font *default_font;
   3949     struct nk_font *fonts;
   3950     struct nk_font_config *config;
   3951     int font_num;
   3952 };
   3953 
   3954 /* some language glyph codepoint ranges */
   3955 NK_API const nk_rune *nk_font_default_glyph_ranges(void);
   3956 NK_API const nk_rune *nk_font_chinese_glyph_ranges(void);
   3957 NK_API const nk_rune *nk_font_cyrillic_glyph_ranges(void);
   3958 NK_API const nk_rune *nk_font_korean_glyph_ranges(void);
   3959 
   3960 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
   3961 NK_API void nk_font_atlas_init_default(struct nk_font_atlas*);
   3962 #endif
   3963 NK_API void nk_font_atlas_init(struct nk_font_atlas*, struct nk_allocator*);
   3964 NK_API void nk_font_atlas_init_custom(struct nk_font_atlas*, struct nk_allocator *persistent, struct nk_allocator *transient);
   3965 NK_API void nk_font_atlas_begin(struct nk_font_atlas*);
   3966 NK_API struct nk_font_config nk_font_config(float pixel_height);
   3967 NK_API struct nk_font *nk_font_atlas_add(struct nk_font_atlas*, const struct nk_font_config*);
   3968 #ifdef NK_INCLUDE_DEFAULT_FONT
   3969 NK_API struct nk_font* nk_font_atlas_add_default(struct nk_font_atlas*, float height, const struct nk_font_config*);
   3970 #endif
   3971 NK_API struct nk_font* nk_font_atlas_add_from_memory(struct nk_font_atlas *atlas, void *memory, nk_size size, float height, const struct nk_font_config *config);
   3972 #ifdef NK_INCLUDE_STANDARD_IO
   3973 NK_API struct nk_font* nk_font_atlas_add_from_file(struct nk_font_atlas *atlas, const char *file_path, float height, const struct nk_font_config*);
   3974 #endif
   3975 NK_API struct nk_font *nk_font_atlas_add_compressed(struct nk_font_atlas*, void *memory, nk_size size, float height, const struct nk_font_config*);
   3976 NK_API struct nk_font* nk_font_atlas_add_compressed_base85(struct nk_font_atlas*, const char *data, float height, const struct nk_font_config *config);
   3977 NK_API const void* nk_font_atlas_bake(struct nk_font_atlas*, int *width, int *height, enum nk_font_atlas_format);
   3978 NK_API void nk_font_atlas_end(struct nk_font_atlas*, nk_handle tex, struct nk_draw_null_texture*);
   3979 NK_API const struct nk_font_glyph* nk_font_find_glyph(struct nk_font*, nk_rune unicode);
   3980 NK_API void nk_font_atlas_cleanup(struct nk_font_atlas *atlas);
   3981 NK_API void nk_font_atlas_clear(struct nk_font_atlas*);
   3982 
   3983 #endif
   3984 
   3985 /* ==============================================================
   3986  *
   3987  *                          MEMORY BUFFER
   3988  *
   3989  * ===============================================================*/
   3990 /*  A basic (double)-buffer with linear allocation and resetting as only
   3991     freeing policy. The buffer's main purpose is to control all memory management
   3992     inside the GUI toolkit and still leave memory control as much as possible in
   3993     the hand of the user while also making sure the library is easy to use if
   3994     not as much control is needed.
   3995     In general all memory inside this library can be provided from the user in
   3996     three different ways.
   3997 
   3998     The first way and the one providing most control is by just passing a fixed
   3999     size memory block. In this case all control lies in the hand of the user
   4000     since he can exactly control where the memory comes from and how much memory
   4001     the library should consume. Of course using the fixed size API removes the
   4002     ability to automatically resize a buffer if not enough memory is provided so
   4003     you have to take over the resizing. While being a fixed sized buffer sounds
   4004     quite limiting, it is very effective in this library since the actual memory
   4005     consumption is quite stable and has a fixed upper bound for a lot of cases.
   4006 
   4007     If you don't want to think about how much memory the library should allocate
   4008     at all time or have a very dynamic UI with unpredictable memory consumption
   4009     habits but still want control over memory allocation you can use the dynamic
   4010     allocator based API. The allocator consists of two callbacks for allocating
   4011     and freeing memory and optional userdata so you can plugin your own allocator.
   4012 
   4013     The final and easiest way can be used by defining
   4014     NK_INCLUDE_DEFAULT_ALLOCATOR which uses the standard library memory
   4015     allocation functions malloc and free and takes over complete control over
   4016     memory in this library.
   4017 */
   4018 struct nk_memory_status {
   4019     void *memory;
   4020     unsigned int type;
   4021     nk_size size;
   4022     nk_size allocated;
   4023     nk_size needed;
   4024     nk_size calls;
   4025 };
   4026 
   4027 enum nk_allocation_type {
   4028     NK_BUFFER_FIXED,
   4029     NK_BUFFER_DYNAMIC
   4030 };
   4031 
   4032 enum nk_buffer_allocation_type {
   4033     NK_BUFFER_FRONT,
   4034     NK_BUFFER_BACK,
   4035     NK_BUFFER_MAX
   4036 };
   4037 
   4038 struct nk_buffer_marker {
   4039     int active;
   4040     nk_size offset;
   4041 };
   4042 
   4043 struct nk_memory {void *ptr;nk_size size;};
   4044 struct nk_buffer {
   4045     struct nk_buffer_marker marker[NK_BUFFER_MAX];
   4046     /* buffer marker to free a buffer to a certain offset */
   4047     struct nk_allocator pool;
   4048     /* allocator callback for dynamic buffers */
   4049     enum nk_allocation_type type;
   4050     /* memory management type */
   4051     struct nk_memory memory;
   4052     /* memory and size of the current memory block */
   4053     float grow_factor;
   4054     /* growing factor for dynamic memory management */
   4055     nk_size allocated;
   4056     /* total amount of memory allocated */
   4057     nk_size needed;
   4058     /* totally consumed memory given that enough memory is present */
   4059     nk_size calls;
   4060     /* number of allocation calls */
   4061     nk_size size;
   4062     /* current size of the buffer */
   4063 };
   4064 
   4065 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
   4066 NK_API void nk_buffer_init_default(struct nk_buffer*);
   4067 #endif
   4068 NK_API void nk_buffer_init(struct nk_buffer*, const struct nk_allocator*, nk_size size);
   4069 NK_API void nk_buffer_init_fixed(struct nk_buffer*, void *memory, nk_size size);
   4070 NK_API void nk_buffer_info(struct nk_memory_status*, struct nk_buffer*);
   4071 NK_API void nk_buffer_push(struct nk_buffer*, enum nk_buffer_allocation_type type, const void *memory, nk_size size, nk_size align);
   4072 NK_API void nk_buffer_mark(struct nk_buffer*, enum nk_buffer_allocation_type type);
   4073 NK_API void nk_buffer_reset(struct nk_buffer*, enum nk_buffer_allocation_type type);
   4074 NK_API void nk_buffer_clear(struct nk_buffer*);
   4075 NK_API void nk_buffer_free(struct nk_buffer*);
   4076 NK_API void *nk_buffer_memory(struct nk_buffer*);
   4077 NK_API const void *nk_buffer_memory_const(const struct nk_buffer*);
   4078 NK_API nk_size nk_buffer_total(struct nk_buffer*);
   4079 
   4080 /* ==============================================================
   4081  *
   4082  *                          STRING
   4083  *
   4084  * ===============================================================*/
   4085 /*  Basic string buffer which is only used in context with the text editor
   4086  *  to manage and manipulate dynamic or fixed size string content. This is _NOT_
   4087  *  the default string handling method. The only instance you should have any contact
   4088  *  with this API is if you interact with an `nk_text_edit` object inside one of the
   4089  *  copy and paste functions and even there only for more advanced cases. */
   4090 struct nk_str {
   4091     struct nk_buffer buffer;
   4092     int len; /* in codepoints/runes/glyphs */
   4093 };
   4094 
   4095 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
   4096 NK_API void nk_str_init_default(struct nk_str*);
   4097 #endif
   4098 NK_API void nk_str_init(struct nk_str*, const struct nk_allocator*, nk_size size);
   4099 NK_API void nk_str_init_fixed(struct nk_str*, void *memory, nk_size size);
   4100 NK_API void nk_str_clear(struct nk_str*);
   4101 NK_API void nk_str_free(struct nk_str*);
   4102 
   4103 NK_API int nk_str_append_text_char(struct nk_str*, const char*, int);
   4104 NK_API int nk_str_append_str_char(struct nk_str*, const char*);
   4105 NK_API int nk_str_append_text_utf8(struct nk_str*, const char*, int);
   4106 NK_API int nk_str_append_str_utf8(struct nk_str*, const char*);
   4107 NK_API int nk_str_append_text_runes(struct nk_str*, const nk_rune*, int);
   4108 NK_API int nk_str_append_str_runes(struct nk_str*, const nk_rune*);
   4109 
   4110 NK_API int nk_str_insert_at_char(struct nk_str*, int pos, const char*, int);
   4111 NK_API int nk_str_insert_at_rune(struct nk_str*, int pos, const char*, int);
   4112 
   4113 NK_API int nk_str_insert_text_char(struct nk_str*, int pos, const char*, int);
   4114 NK_API int nk_str_insert_str_char(struct nk_str*, int pos, const char*);
   4115 NK_API int nk_str_insert_text_utf8(struct nk_str*, int pos, const char*, int);
   4116 NK_API int nk_str_insert_str_utf8(struct nk_str*, int pos, const char*);
   4117 NK_API int nk_str_insert_text_runes(struct nk_str*, int pos, const nk_rune*, int);
   4118 NK_API int nk_str_insert_str_runes(struct nk_str*, int pos, const nk_rune*);
   4119 
   4120 NK_API void nk_str_remove_chars(struct nk_str*, int len);
   4121 NK_API void nk_str_remove_runes(struct nk_str *str, int len);
   4122 NK_API void nk_str_delete_chars(struct nk_str*, int pos, int len);
   4123 NK_API void nk_str_delete_runes(struct nk_str*, int pos, int len);
   4124 
   4125 NK_API char *nk_str_at_char(struct nk_str*, int pos);
   4126 NK_API char *nk_str_at_rune(struct nk_str*, int pos, nk_rune *unicode, int *len);
   4127 NK_API nk_rune nk_str_rune_at(const struct nk_str*, int pos);
   4128 NK_API const char *nk_str_at_char_const(const struct nk_str*, int pos);
   4129 NK_API const char *nk_str_at_const(const struct nk_str*, int pos, nk_rune *unicode, int *len);
   4130 
   4131 NK_API char *nk_str_get(struct nk_str*);
   4132 NK_API const char *nk_str_get_const(const struct nk_str*);
   4133 NK_API int nk_str_len(struct nk_str*);
   4134 NK_API int nk_str_len_char(struct nk_str*);
   4135 
   4136 /*===============================================================
   4137  *
   4138  *                      TEXT EDITOR
   4139  *
   4140  * ===============================================================*/
   4141 /* Editing text in this library is handled by either `nk_edit_string` or
   4142  * `nk_edit_buffer`. But like almost everything in this library there are multiple
   4143  * ways of doing it and a balance between control and ease of use with memory
   4144  * as well as functionality controlled by flags.
   4145  *
   4146  * This library generally allows three different levels of memory control:
   4147  * First of is the most basic way of just providing a simple char array with
   4148  * string length. This method is probably the easiest way of handling simple
   4149  * user text input. Main upside is complete control over memory while the biggest
   4150  * downside in comparison with the other two approaches is missing undo/redo.
   4151  *
   4152  * For UIs that require undo/redo the second way was created. It is based on
   4153  * a fixed size nk_text_edit struct, which has an internal undo/redo stack.
   4154  * This is mainly useful if you want something more like a text editor but don't want
   4155  * to have a dynamically growing buffer.
   4156  *
   4157  * The final way is using a dynamically growing nk_text_edit struct, which
   4158  * has both a default version if you don't care where memory comes from and an
   4159  * allocator version if you do. While the text editor is quite powerful for its
   4160  * complexity I would not recommend editing gigabytes of data with it.
   4161  * It is rather designed for uses cases which make sense for a GUI library not for
   4162  * an full blown text editor.
   4163  */
   4164 #ifndef NK_TEXTEDIT_UNDOSTATECOUNT
   4165 #define NK_TEXTEDIT_UNDOSTATECOUNT     99
   4166 #endif
   4167 
   4168 #ifndef NK_TEXTEDIT_UNDOCHARCOUNT
   4169 #define NK_TEXTEDIT_UNDOCHARCOUNT      999
   4170 #endif
   4171 
   4172 struct nk_text_edit;
   4173 struct nk_clipboard {
   4174     nk_handle userdata;
   4175     nk_plugin_paste paste;
   4176     nk_plugin_copy copy;
   4177 };
   4178 
   4179 struct nk_text_undo_record {
   4180    int where;
   4181    short insert_length;
   4182    short delete_length;
   4183    short char_storage;
   4184 };
   4185 
   4186 struct nk_text_undo_state {
   4187    struct nk_text_undo_record undo_rec[NK_TEXTEDIT_UNDOSTATECOUNT];
   4188    nk_rune undo_char[NK_TEXTEDIT_UNDOCHARCOUNT];
   4189    short undo_point;
   4190    short redo_point;
   4191    short undo_char_point;
   4192    short redo_char_point;
   4193 };
   4194 
   4195 enum nk_text_edit_type {
   4196     NK_TEXT_EDIT_SINGLE_LINE,
   4197     NK_TEXT_EDIT_MULTI_LINE
   4198 };
   4199 
   4200 enum nk_text_edit_mode {
   4201     NK_TEXT_EDIT_MODE_VIEW,
   4202     NK_TEXT_EDIT_MODE_INSERT,
   4203     NK_TEXT_EDIT_MODE_REPLACE
   4204 };
   4205 
   4206 struct nk_text_edit {
   4207     struct nk_clipboard clip;
   4208     struct nk_str string;
   4209     nk_plugin_filter filter;
   4210     struct nk_vec2 scrollbar;
   4211 
   4212     int cursor;
   4213     int select_start;
   4214     int select_end;
   4215     unsigned char mode;
   4216     unsigned char cursor_at_end_of_line;
   4217     unsigned char initialized;
   4218     unsigned char has_preferred_x;
   4219     unsigned char single_line;
   4220     unsigned char active;
   4221     unsigned char padding1;
   4222     float preferred_x;
   4223     struct nk_text_undo_state undo;
   4224 };
   4225 
   4226 /* filter function */
   4227 NK_API int nk_filter_default(const struct nk_text_edit*, nk_rune unicode);
   4228 NK_API int nk_filter_ascii(const struct nk_text_edit*, nk_rune unicode);
   4229 NK_API int nk_filter_float(const struct nk_text_edit*, nk_rune unicode);
   4230 NK_API int nk_filter_decimal(const struct nk_text_edit*, nk_rune unicode);
   4231 NK_API int nk_filter_hex(const struct nk_text_edit*, nk_rune unicode);
   4232 NK_API int nk_filter_oct(const struct nk_text_edit*, nk_rune unicode);
   4233 NK_API int nk_filter_binary(const struct nk_text_edit*, nk_rune unicode);
   4234 
   4235 /* text editor */
   4236 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
   4237 NK_API void nk_textedit_init_default(struct nk_text_edit*);
   4238 #endif
   4239 NK_API void nk_textedit_init(struct nk_text_edit*, struct nk_allocator*, nk_size size);
   4240 NK_API void nk_textedit_init_fixed(struct nk_text_edit*, void *memory, nk_size size);
   4241 NK_API void nk_textedit_free(struct nk_text_edit*);
   4242 NK_API void nk_textedit_text(struct nk_text_edit*, const char*, int total_len);
   4243 NK_API void nk_textedit_delete(struct nk_text_edit*, int where, int len);
   4244 NK_API void nk_textedit_delete_selection(struct nk_text_edit*);
   4245 NK_API void nk_textedit_select_all(struct nk_text_edit*);
   4246 NK_API int nk_textedit_cut(struct nk_text_edit*);
   4247 NK_API int nk_textedit_paste(struct nk_text_edit*, char const*, int len);
   4248 NK_API void nk_textedit_undo(struct nk_text_edit*);
   4249 NK_API void nk_textedit_redo(struct nk_text_edit*);
   4250 
   4251 /* ===============================================================
   4252  *
   4253  *                          DRAWING
   4254  *
   4255  * ===============================================================*/
   4256 /*  This library was designed to be render backend agnostic so it does
   4257     not draw anything to screen. Instead all drawn shapes, widgets
   4258     are made of, are buffered into memory and make up a command queue.
   4259     Each frame therefore fills the command buffer with draw commands
   4260     that then need to be executed by the user and his own render backend.
   4261     After that the command buffer needs to be cleared and a new frame can be
   4262     started. It is probably important to note that the command buffer is the main
   4263     drawing API and the optional vertex buffer API only takes this format and
   4264     converts it into a hardware accessible format.
   4265 
   4266     To use the command queue to draw your own widgets you can access the
   4267     command buffer of each window by calling `nk_window_get_canvas` after
   4268     previously having called `nk_begin`:
   4269 
   4270         void draw_red_rectangle_widget(struct nk_context *ctx)
   4271         {
   4272             struct nk_command_buffer *canvas;
   4273             struct nk_input *input = &ctx->input;
   4274             canvas = nk_window_get_canvas(ctx);
   4275 
   4276             struct nk_rect space;
   4277             enum nk_widget_layout_states state;
   4278             state = nk_widget(&space, ctx);
   4279             if (!state) return;
   4280 
   4281             if (state != NK_WIDGET_ROM)
   4282                 update_your_widget_by_user_input(...);
   4283             nk_fill_rect(canvas, space, 0, nk_rgb(255,0,0));
   4284         }
   4285 
   4286         if (nk_begin(...)) {
   4287             nk_layout_row_dynamic(ctx, 25, 1);
   4288             draw_red_rectangle_widget(ctx);
   4289         }
   4290         nk_end(..)
   4291 
   4292     Important to know if you want to create your own widgets is the `nk_widget`
   4293     call. It allocates space on the panel reserved for this widget to be used,
   4294     but also returns the state of the widget space. If your widget is not seen and does
   4295     not have to be updated it is '0' and you can just return. If it only has
   4296     to be drawn the state will be `NK_WIDGET_ROM` otherwise you can do both
   4297     update and draw your widget. The reason for separating is to only draw and
   4298     update what is actually necessary which is crucial for performance.
   4299 */
   4300 enum nk_command_type {
   4301     NK_COMMAND_NOP,
   4302     NK_COMMAND_SCISSOR,
   4303     NK_COMMAND_LINE,
   4304     NK_COMMAND_CURVE,
   4305     NK_COMMAND_RECT,
   4306     NK_COMMAND_RECT_FILLED,
   4307     NK_COMMAND_RECT_MULTI_COLOR,
   4308     NK_COMMAND_CIRCLE,
   4309     NK_COMMAND_CIRCLE_FILLED,
   4310     NK_COMMAND_ARC,
   4311     NK_COMMAND_ARC_FILLED,
   4312     NK_COMMAND_TRIANGLE,
   4313     NK_COMMAND_TRIANGLE_FILLED,
   4314     NK_COMMAND_POLYGON,
   4315     NK_COMMAND_POLYGON_FILLED,
   4316     NK_COMMAND_POLYLINE,
   4317     NK_COMMAND_TEXT,
   4318     NK_COMMAND_IMAGE,
   4319     NK_COMMAND_CUSTOM
   4320 };
   4321 
   4322 /* command base and header of every command inside the buffer */
   4323 struct nk_command {
   4324     enum nk_command_type type;
   4325     nk_size next;
   4326 #ifdef NK_INCLUDE_COMMAND_USERDATA
   4327     nk_handle userdata;
   4328 #endif
   4329 };
   4330 
   4331 struct nk_command_scissor {
   4332     struct nk_command header;
   4333     short x, y;
   4334     unsigned short w, h;
   4335 };
   4336 
   4337 struct nk_command_line {
   4338     struct nk_command header;
   4339     unsigned short line_thickness;
   4340     struct nk_vec2i begin;
   4341     struct nk_vec2i end;
   4342     struct nk_color color;
   4343 };
   4344 
   4345 struct nk_command_curve {
   4346     struct nk_command header;
   4347     unsigned short line_thickness;
   4348     struct nk_vec2i begin;
   4349     struct nk_vec2i end;
   4350     struct nk_vec2i ctrl[2];
   4351     struct nk_color color;
   4352 };
   4353 
   4354 struct nk_command_rect {
   4355     struct nk_command header;
   4356     unsigned short rounding;
   4357     unsigned short line_thickness;
   4358     short x, y;
   4359     unsigned short w, h;
   4360     struct nk_color color;
   4361 };
   4362 
   4363 struct nk_command_rect_filled {
   4364     struct nk_command header;
   4365     unsigned short rounding;
   4366     short x, y;
   4367     unsigned short w, h;
   4368     struct nk_color color;
   4369 };
   4370 
   4371 struct nk_command_rect_multi_color {
   4372     struct nk_command header;
   4373     short x, y;
   4374     unsigned short w, h;
   4375     struct nk_color left;
   4376     struct nk_color top;
   4377     struct nk_color bottom;
   4378     struct nk_color right;
   4379 };
   4380 
   4381 struct nk_command_triangle {
   4382     struct nk_command header;
   4383     unsigned short line_thickness;
   4384     struct nk_vec2i a;
   4385     struct nk_vec2i b;
   4386     struct nk_vec2i c;
   4387     struct nk_color color;
   4388 };
   4389 
   4390 struct nk_command_triangle_filled {
   4391     struct nk_command header;
   4392     struct nk_vec2i a;
   4393     struct nk_vec2i b;
   4394     struct nk_vec2i c;
   4395     struct nk_color color;
   4396 };
   4397 
   4398 struct nk_command_circle {
   4399     struct nk_command header;
   4400     short x, y;
   4401     unsigned short line_thickness;
   4402     unsigned short w, h;
   4403     struct nk_color color;
   4404 };
   4405 
   4406 struct nk_command_circle_filled {
   4407     struct nk_command header;
   4408     short x, y;
   4409     unsigned short w, h;
   4410     struct nk_color color;
   4411 };
   4412 
   4413 struct nk_command_arc {
   4414     struct nk_command header;
   4415     short cx, cy;
   4416     unsigned short r;
   4417     unsigned short line_thickness;
   4418     float a[2];
   4419     struct nk_color color;
   4420 };
   4421 
   4422 struct nk_command_arc_filled {
   4423     struct nk_command header;
   4424     short cx, cy;
   4425     unsigned short r;
   4426     float a[2];
   4427     struct nk_color color;
   4428 };
   4429 
   4430 struct nk_command_polygon {
   4431     struct nk_command header;
   4432     struct nk_color color;
   4433     unsigned short line_thickness;
   4434     unsigned short point_count;
   4435     struct nk_vec2i points[1];
   4436 };
   4437 
   4438 struct nk_command_polygon_filled {
   4439     struct nk_command header;
   4440     struct nk_color color;
   4441     unsigned short point_count;
   4442     struct nk_vec2i points[1];
   4443 };
   4444 
   4445 struct nk_command_polyline {
   4446     struct nk_command header;
   4447     struct nk_color color;
   4448     unsigned short line_thickness;
   4449     unsigned short point_count;
   4450     struct nk_vec2i points[1];
   4451 };
   4452 
   4453 struct nk_command_image {
   4454     struct nk_command header;
   4455     short x, y;
   4456     unsigned short w, h;
   4457     struct nk_image img;
   4458     struct nk_color col;
   4459 };
   4460 
   4461 typedef void (*nk_command_custom_callback)(void *canvas, short x,short y,
   4462     unsigned short w, unsigned short h, nk_handle callback_data);
   4463 struct nk_command_custom {
   4464     struct nk_command header;
   4465     short x, y;
   4466     unsigned short w, h;
   4467     nk_handle callback_data;
   4468     nk_command_custom_callback callback;
   4469 };
   4470 
   4471 struct nk_command_text {
   4472     struct nk_command header;
   4473     const struct nk_user_font *font;
   4474     struct nk_color background;
   4475     struct nk_color foreground;
   4476     short x, y;
   4477     unsigned short w, h;
   4478     float height;
   4479     int length;
   4480     char string[1];
   4481 };
   4482 
   4483 enum nk_command_clipping {
   4484     NK_CLIPPING_OFF = nk_false,
   4485     NK_CLIPPING_ON = nk_true
   4486 };
   4487 
   4488 struct nk_command_buffer {
   4489     struct nk_buffer *base;
   4490     struct nk_rect clip;
   4491     int use_clipping;
   4492     nk_handle userdata;
   4493     nk_size begin, end, last;
   4494 };
   4495 
   4496 /* shape outlines */
   4497 NK_API void nk_stroke_line(struct nk_command_buffer *b, float x0, float y0, float x1, float y1, float line_thickness, struct nk_color);
   4498 NK_API void nk_stroke_curve(struct nk_command_buffer*, float, float, float, float, float, float, float, float, float line_thickness, struct nk_color);
   4499 NK_API void nk_stroke_rect(struct nk_command_buffer*, struct nk_rect, float rounding, float line_thickness, struct nk_color);
   4500 NK_API void nk_stroke_circle(struct nk_command_buffer*, struct nk_rect, float line_thickness, struct nk_color);
   4501 NK_API void nk_stroke_arc(struct nk_command_buffer*, float cx, float cy, float radius, float a_min, float a_max, float line_thickness, struct nk_color);
   4502 NK_API void nk_stroke_triangle(struct nk_command_buffer*, float, float, float, float, float, float, float line_thichness, struct nk_color);
   4503 NK_API void nk_stroke_polyline(struct nk_command_buffer*, float *points, int point_count, float line_thickness, struct nk_color col);
   4504 NK_API void nk_stroke_polygon(struct nk_command_buffer*, float*, int point_count, float line_thickness, struct nk_color);
   4505 
   4506 /* filled shades */
   4507 NK_API void nk_fill_rect(struct nk_command_buffer*, struct nk_rect, float rounding, struct nk_color);
   4508 NK_API void nk_fill_rect_multi_color(struct nk_command_buffer*, struct nk_rect, struct nk_color left, struct nk_color top, struct nk_color right, struct nk_color bottom);
   4509 NK_API void nk_fill_circle(struct nk_command_buffer*, struct nk_rect, struct nk_color);
   4510 NK_API void nk_fill_arc(struct nk_command_buffer*, float cx, float cy, float radius, float a_min, float a_max, struct nk_color);
   4511 NK_API void nk_fill_triangle(struct nk_command_buffer*, float x0, float y0, float x1, float y1, float x2, float y2, struct nk_color);
   4512 NK_API void nk_fill_polygon(struct nk_command_buffer*, float*, int point_count, struct nk_color);
   4513 
   4514 /* misc */
   4515 NK_API void nk_draw_image(struct nk_command_buffer*, struct nk_rect, const struct nk_image*, struct nk_color);
   4516 NK_API void nk_draw_text(struct nk_command_buffer*, struct nk_rect, const char *text, int len, const struct nk_user_font*, struct nk_color, struct nk_color);
   4517 NK_API void nk_push_scissor(struct nk_command_buffer*, struct nk_rect);
   4518 NK_API void nk_push_custom(struct nk_command_buffer*, struct nk_rect, nk_command_custom_callback, nk_handle usr);
   4519 
   4520 /* ===============================================================
   4521  *
   4522  *                          INPUT
   4523  *
   4524  * ===============================================================*/
   4525 struct nk_mouse_button {
   4526     int down;
   4527     unsigned int clicked;
   4528     struct nk_vec2 clicked_pos;
   4529 };
   4530 struct nk_mouse {
   4531     struct nk_mouse_button buttons[NK_BUTTON_MAX];
   4532     struct nk_vec2 pos;
   4533     struct nk_vec2 prev;
   4534     struct nk_vec2 delta;
   4535     struct nk_vec2 scroll_delta;
   4536     unsigned char grab;
   4537     unsigned char grabbed;
   4538     unsigned char ungrab;
   4539 };
   4540 
   4541 struct nk_key {
   4542     int down;
   4543     unsigned int clicked;
   4544 };
   4545 struct nk_keyboard {
   4546     struct nk_key keys[NK_KEY_MAX];
   4547     char text[NK_INPUT_MAX];
   4548     int text_len;
   4549 };
   4550 
   4551 struct nk_input {
   4552     struct nk_keyboard keyboard;
   4553     struct nk_mouse mouse;
   4554 };
   4555 
   4556 NK_API int nk_input_has_mouse_click(const struct nk_input*, enum nk_buttons);
   4557 NK_API int nk_input_has_mouse_click_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect);
   4558 NK_API int nk_input_has_mouse_click_down_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect, int down);
   4559 NK_API int nk_input_is_mouse_click_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect);
   4560 NK_API int nk_input_is_mouse_click_down_in_rect(const struct nk_input *i, enum nk_buttons id, struct nk_rect b, int down);
   4561 NK_API int nk_input_any_mouse_click_in_rect(const struct nk_input*, struct nk_rect);
   4562 NK_API int nk_input_is_mouse_prev_hovering_rect(const struct nk_input*, struct nk_rect);
   4563 NK_API int nk_input_is_mouse_hovering_rect(const struct nk_input*, struct nk_rect);
   4564 NK_API int nk_input_mouse_clicked(const struct nk_input*, enum nk_buttons, struct nk_rect);
   4565 NK_API int nk_input_is_mouse_down(const struct nk_input*, enum nk_buttons);
   4566 NK_API int nk_input_is_mouse_pressed(const struct nk_input*, enum nk_buttons);
   4567 NK_API int nk_input_is_mouse_released(const struct nk_input*, enum nk_buttons);
   4568 NK_API int nk_input_is_key_pressed(const struct nk_input*, enum nk_keys);
   4569 NK_API int nk_input_is_key_released(const struct nk_input*, enum nk_keys);
   4570 NK_API int nk_input_is_key_down(const struct nk_input*, enum nk_keys);
   4571 
   4572 /* ===============================================================
   4573  *
   4574  *                          DRAW LIST
   4575  *
   4576  * ===============================================================*/
   4577 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
   4578 /*  The optional vertex buffer draw list provides a 2D drawing context
   4579     with antialiasing functionality which takes basic filled or outlined shapes
   4580     or a path and outputs vertexes, elements and draw commands.
   4581     The actual draw list API is not required to be used directly while using this
   4582     library since converting the default library draw command output is done by
   4583     just calling `nk_convert` but I decided to still make this library accessible
   4584     since it can be useful.
   4585 
   4586     The draw list is based on a path buffering and polygon and polyline
   4587     rendering API which allows a lot of ways to draw 2D content to screen.
   4588     In fact it is probably more powerful than needed but allows even more crazy
   4589     things than this library provides by default.
   4590 */
   4591 typedef nk_ushort nk_draw_index;
   4592 enum nk_draw_list_stroke {
   4593     NK_STROKE_OPEN = nk_false,
   4594     /* build up path has no connection back to the beginning */
   4595     NK_STROKE_CLOSED = nk_true
   4596     /* build up path has a connection back to the beginning */
   4597 };
   4598 
   4599 enum nk_draw_vertex_layout_attribute {
   4600     NK_VERTEX_POSITION,
   4601     NK_VERTEX_COLOR,
   4602     NK_VERTEX_TEXCOORD,
   4603     NK_VERTEX_ATTRIBUTE_COUNT
   4604 };
   4605 
   4606 enum nk_draw_vertex_layout_format {
   4607     NK_FORMAT_SCHAR,
   4608     NK_FORMAT_SSHORT,
   4609     NK_FORMAT_SINT,
   4610     NK_FORMAT_UCHAR,
   4611     NK_FORMAT_USHORT,
   4612     NK_FORMAT_UINT,
   4613     NK_FORMAT_FLOAT,
   4614     NK_FORMAT_DOUBLE,
   4615 
   4616 NK_FORMAT_COLOR_BEGIN,
   4617     NK_FORMAT_R8G8B8 = NK_FORMAT_COLOR_BEGIN,
   4618     NK_FORMAT_R16G15B16,
   4619     NK_FORMAT_R32G32B32,
   4620 
   4621     NK_FORMAT_R8G8B8A8,
   4622     NK_FORMAT_B8G8R8A8,
   4623     NK_FORMAT_R16G15B16A16,
   4624     NK_FORMAT_R32G32B32A32,
   4625     NK_FORMAT_R32G32B32A32_FLOAT,
   4626     NK_FORMAT_R32G32B32A32_DOUBLE,
   4627 
   4628     NK_FORMAT_RGB32,
   4629     NK_FORMAT_RGBA32,
   4630 NK_FORMAT_COLOR_END = NK_FORMAT_RGBA32,
   4631     NK_FORMAT_COUNT
   4632 };
   4633 
   4634 #define NK_VERTEX_LAYOUT_END NK_VERTEX_ATTRIBUTE_COUNT,NK_FORMAT_COUNT,0
   4635 struct nk_draw_vertex_layout_element {
   4636     enum nk_draw_vertex_layout_attribute attribute;
   4637     enum nk_draw_vertex_layout_format format;
   4638     nk_size offset;
   4639 };
   4640 
   4641 struct nk_draw_command {
   4642     unsigned int elem_count;
   4643     /* number of elements in the current draw batch */
   4644     struct nk_rect clip_rect;
   4645     /* current screen clipping rectangle */
   4646     nk_handle texture;
   4647     /* current texture to set */
   4648 #ifdef NK_INCLUDE_COMMAND_USERDATA
   4649     nk_handle userdata;
   4650 #endif
   4651 };
   4652 
   4653 struct nk_draw_list {
   4654     struct nk_rect clip_rect;
   4655     struct nk_vec2 circle_vtx[12];
   4656     struct nk_convert_config config;
   4657 
   4658     struct nk_buffer *buffer;
   4659     struct nk_buffer *vertices;
   4660     struct nk_buffer *elements;
   4661 
   4662     unsigned int element_count;
   4663     unsigned int vertex_count;
   4664     unsigned int cmd_count;
   4665     nk_size cmd_offset;
   4666 
   4667     unsigned int path_count;
   4668     unsigned int path_offset;
   4669 
   4670     enum nk_anti_aliasing line_AA;
   4671     enum nk_anti_aliasing shape_AA;
   4672 
   4673 #ifdef NK_INCLUDE_COMMAND_USERDATA
   4674     nk_handle userdata;
   4675 #endif
   4676 };
   4677 
   4678 /* draw list */
   4679 NK_API void nk_draw_list_init(struct nk_draw_list*);
   4680 NK_API void nk_draw_list_setup(struct nk_draw_list*, const struct nk_convert_config*, struct nk_buffer *cmds, struct nk_buffer *vertices, struct nk_buffer *elements, enum nk_anti_aliasing line_aa,enum nk_anti_aliasing shape_aa);
   4681 
   4682 /* drawing */
   4683 #define nk_draw_list_foreach(cmd, can, b) for((cmd)=nk__draw_list_begin(can, b); (cmd)!=0; (cmd)=nk__draw_list_next(cmd, b, can))
   4684 NK_API const struct nk_draw_command* nk__draw_list_begin(const struct nk_draw_list*, const struct nk_buffer*);
   4685 NK_API const struct nk_draw_command* nk__draw_list_next(const struct nk_draw_command*, const struct nk_buffer*, const struct nk_draw_list*);
   4686 NK_API const struct nk_draw_command* nk__draw_list_end(const struct nk_draw_list*, const struct nk_buffer*);
   4687 
   4688 /* path */
   4689 NK_API void nk_draw_list_path_clear(struct nk_draw_list*);
   4690 NK_API void nk_draw_list_path_line_to(struct nk_draw_list*, struct nk_vec2 pos);
   4691 NK_API void nk_draw_list_path_arc_to_fast(struct nk_draw_list*, struct nk_vec2 center, float radius, int a_min, int a_max);
   4692 NK_API void nk_draw_list_path_arc_to(struct nk_draw_list*, struct nk_vec2 center, float radius, float a_min, float a_max, unsigned int segments);
   4693 NK_API void nk_draw_list_path_rect_to(struct nk_draw_list*, struct nk_vec2 a, struct nk_vec2 b, float rounding);
   4694 NK_API void nk_draw_list_path_curve_to(struct nk_draw_list*, struct nk_vec2 p2, struct nk_vec2 p3, struct nk_vec2 p4, unsigned int num_segments);
   4695 NK_API void nk_draw_list_path_fill(struct nk_draw_list*, struct nk_color);
   4696 NK_API void nk_draw_list_path_stroke(struct nk_draw_list*, struct nk_color, enum nk_draw_list_stroke closed, float thickness);
   4697 
   4698 /* stroke */
   4699 NK_API void nk_draw_list_stroke_line(struct nk_draw_list*, struct nk_vec2 a, struct nk_vec2 b, struct nk_color, float thickness);
   4700 NK_API void nk_draw_list_stroke_rect(struct nk_draw_list*, struct nk_rect rect, struct nk_color, float rounding, float thickness);
   4701 NK_API void nk_draw_list_stroke_triangle(struct nk_draw_list*, struct nk_vec2 a, struct nk_vec2 b, struct nk_vec2 c, struct nk_color, float thickness);
   4702 NK_API void nk_draw_list_stroke_circle(struct nk_draw_list*, struct nk_vec2 center, float radius, struct nk_color, unsigned int segs, float thickness);
   4703 NK_API void nk_draw_list_stroke_curve(struct nk_draw_list*, struct nk_vec2 p0, struct nk_vec2 cp0, struct nk_vec2 cp1, struct nk_vec2 p1, struct nk_color, unsigned int segments, float thickness);
   4704 NK_API void nk_draw_list_stroke_poly_line(struct nk_draw_list*, const struct nk_vec2 *pnts, const unsigned int cnt, struct nk_color, enum nk_draw_list_stroke, float thickness, enum nk_anti_aliasing);
   4705 
   4706 /* fill */
   4707 NK_API void nk_draw_list_fill_rect(struct nk_draw_list*, struct nk_rect rect, struct nk_color, float rounding);
   4708 NK_API void nk_draw_list_fill_rect_multi_color(struct nk_draw_list*, struct nk_rect rect, struct nk_color left, struct nk_color top, struct nk_color right, struct nk_color bottom);
   4709 NK_API void nk_draw_list_fill_triangle(struct nk_draw_list*, struct nk_vec2 a, struct nk_vec2 b, struct nk_vec2 c, struct nk_color);
   4710 NK_API void nk_draw_list_fill_circle(struct nk_draw_list*, struct nk_vec2 center, float radius, struct nk_color col, unsigned int segs);
   4711 NK_API void nk_draw_list_fill_poly_convex(struct nk_draw_list*, const struct nk_vec2 *points, const unsigned int count, struct nk_color, enum nk_anti_aliasing);
   4712 
   4713 /* misc */
   4714 NK_API void nk_draw_list_add_image(struct nk_draw_list*, struct nk_image texture, struct nk_rect rect, struct nk_color);
   4715 NK_API void nk_draw_list_add_text(struct nk_draw_list*, const struct nk_user_font*, struct nk_rect, const char *text, int len, float font_height, struct nk_color);
   4716 #ifdef NK_INCLUDE_COMMAND_USERDATA
   4717 NK_API void nk_draw_list_push_userdata(struct nk_draw_list*, nk_handle userdata);
   4718 #endif
   4719 
   4720 #endif
   4721 
   4722 /* ===============================================================
   4723  *
   4724  *                          GUI
   4725  *
   4726  * ===============================================================*/
   4727 enum nk_style_item_type {
   4728     NK_STYLE_ITEM_COLOR,
   4729     NK_STYLE_ITEM_IMAGE
   4730 };
   4731 
   4732 union nk_style_item_data {
   4733     struct nk_image image;
   4734     struct nk_color color;
   4735 };
   4736 
   4737 struct nk_style_item {
   4738     enum nk_style_item_type type;
   4739     union nk_style_item_data data;
   4740 };
   4741 
   4742 struct nk_style_text {
   4743     struct nk_color color;
   4744     struct nk_vec2 padding;
   4745 };
   4746 
   4747 struct nk_style_button {
   4748     /* background */
   4749     struct nk_style_item normal;
   4750     struct nk_style_item hover;
   4751     struct nk_style_item active;
   4752     struct nk_color border_color;
   4753 
   4754     /* text */
   4755     struct nk_color text_background;
   4756     struct nk_color text_normal;
   4757     struct nk_color text_hover;
   4758     struct nk_color text_active;
   4759     nk_flags text_alignment;
   4760 
   4761     /* properties */
   4762     float border;
   4763     float rounding;
   4764     struct nk_vec2 padding;
   4765     struct nk_vec2 image_padding;
   4766     struct nk_vec2 touch_padding;
   4767 
   4768     /* optional user callbacks */
   4769     nk_handle userdata;
   4770     void(*draw_begin)(struct nk_command_buffer*, nk_handle userdata);
   4771     void(*draw_end)(struct nk_command_buffer*, nk_handle userdata);
   4772 };
   4773 
   4774 struct nk_style_toggle {
   4775     /* background */
   4776     struct nk_style_item normal;
   4777     struct nk_style_item hover;
   4778     struct nk_style_item active;
   4779     struct nk_color border_color;
   4780 
   4781     /* cursor */
   4782     struct nk_style_item cursor_normal;
   4783     struct nk_style_item cursor_hover;
   4784 
   4785     /* text */
   4786     struct nk_color text_normal;
   4787     struct nk_color text_hover;
   4788     struct nk_color text_active;
   4789     struct nk_color text_background;
   4790     nk_flags text_alignment;
   4791 
   4792     /* properties */
   4793     struct nk_vec2 padding;
   4794     struct nk_vec2 touch_padding;
   4795     float spacing;
   4796     float border;
   4797 
   4798     /* optional user callbacks */
   4799     nk_handle userdata;
   4800     void(*draw_begin)(struct nk_command_buffer*, nk_handle);
   4801     void(*draw_end)(struct nk_command_buffer*, nk_handle);
   4802 };
   4803 
   4804 struct nk_style_selectable {
   4805     /* background (inactive) */
   4806     struct nk_style_item normal;
   4807     struct nk_style_item hover;
   4808     struct nk_style_item pressed;
   4809 
   4810     /* background (active) */
   4811     struct nk_style_item normal_active;
   4812     struct nk_style_item hover_active;
   4813     struct nk_style_item pressed_active;
   4814 
   4815     /* text color (inactive) */
   4816     struct nk_color text_normal;
   4817     struct nk_color text_hover;
   4818     struct nk_color text_pressed;
   4819 
   4820     /* text color (active) */
   4821     struct nk_color text_normal_active;
   4822     struct nk_color text_hover_active;
   4823     struct nk_color text_pressed_active;
   4824     struct nk_color text_background;
   4825     nk_flags text_alignment;
   4826 
   4827     /* properties */
   4828     float rounding;
   4829     struct nk_vec2 padding;
   4830     struct nk_vec2 touch_padding;
   4831     struct nk_vec2 image_padding;
   4832 
   4833     /* optional user callbacks */
   4834     nk_handle userdata;
   4835     void(*draw_begin)(struct nk_command_buffer*, nk_handle);
   4836     void(*draw_end)(struct nk_command_buffer*, nk_handle);
   4837 };
   4838 
   4839 struct nk_style_slider {
   4840     /* background */
   4841     struct nk_style_item normal;
   4842     struct nk_style_item hover;
   4843     struct nk_style_item active;
   4844     struct nk_color border_color;
   4845 
   4846     /* background bar */
   4847     struct nk_color bar_normal;
   4848     struct nk_color bar_hover;
   4849     struct nk_color bar_active;
   4850     struct nk_color bar_filled;
   4851 
   4852     /* cursor */
   4853     struct nk_style_item cursor_normal;
   4854     struct nk_style_item cursor_hover;
   4855     struct nk_style_item cursor_active;
   4856 
   4857     /* properties */
   4858     float border;
   4859     float rounding;
   4860     float bar_height;
   4861     struct nk_vec2 padding;
   4862     struct nk_vec2 spacing;
   4863     struct nk_vec2 cursor_size;
   4864 
   4865     /* optional buttons */
   4866     int show_buttons;
   4867     struct nk_style_button inc_button;
   4868     struct nk_style_button dec_button;
   4869     enum nk_symbol_type inc_symbol;
   4870     enum nk_symbol_type dec_symbol;
   4871 
   4872     /* optional user callbacks */
   4873     nk_handle userdata;
   4874     void(*draw_begin)(struct nk_command_buffer*, nk_handle);
   4875     void(*draw_end)(struct nk_command_buffer*, nk_handle);
   4876 };
   4877 
   4878 struct nk_style_progress {
   4879     /* background */
   4880     struct nk_style_item normal;
   4881     struct nk_style_item hover;
   4882     struct nk_style_item active;
   4883     struct nk_color border_color;
   4884 
   4885     /* cursor */
   4886     struct nk_style_item cursor_normal;
   4887     struct nk_style_item cursor_hover;
   4888     struct nk_style_item cursor_active;
   4889     struct nk_color cursor_border_color;
   4890 
   4891     /* properties */
   4892     float rounding;
   4893     float border;
   4894     float cursor_border;
   4895     float cursor_rounding;
   4896     struct nk_vec2 padding;
   4897 
   4898     /* optional user callbacks */
   4899     nk_handle userdata;
   4900     void(*draw_begin)(struct nk_command_buffer*, nk_handle);
   4901     void(*draw_end)(struct nk_command_buffer*, nk_handle);
   4902 };
   4903 
   4904 struct nk_style_scrollbar {
   4905     /* background */
   4906     struct nk_style_item normal;
   4907     struct nk_style_item hover;
   4908     struct nk_style_item active;
   4909     struct nk_color border_color;
   4910 
   4911     /* cursor */
   4912     struct nk_style_item cursor_normal;
   4913     struct nk_style_item cursor_hover;
   4914     struct nk_style_item cursor_active;
   4915     struct nk_color cursor_border_color;
   4916 
   4917     /* properties */
   4918     float border;
   4919     float rounding;
   4920     float border_cursor;
   4921     float rounding_cursor;
   4922     struct nk_vec2 padding;
   4923 
   4924     /* optional buttons */
   4925     int show_buttons;
   4926     struct nk_style_button inc_button;
   4927     struct nk_style_button dec_button;
   4928     enum nk_symbol_type inc_symbol;
   4929     enum nk_symbol_type dec_symbol;
   4930 
   4931     /* optional user callbacks */
   4932     nk_handle userdata;
   4933     void(*draw_begin)(struct nk_command_buffer*, nk_handle);
   4934     void(*draw_end)(struct nk_command_buffer*, nk_handle);
   4935 };
   4936 
   4937 struct nk_style_edit {
   4938     /* background */
   4939     struct nk_style_item normal;
   4940     struct nk_style_item hover;
   4941     struct nk_style_item active;
   4942     struct nk_color border_color;
   4943     struct nk_style_scrollbar scrollbar;
   4944 
   4945     /* cursor  */
   4946     struct nk_color cursor_normal;
   4947     struct nk_color cursor_hover;
   4948     struct nk_color cursor_text_normal;
   4949     struct nk_color cursor_text_hover;
   4950 
   4951     /* text (unselected) */
   4952     struct nk_color text_normal;
   4953     struct nk_color text_hover;
   4954     struct nk_color text_active;
   4955 
   4956     /* text (selected) */
   4957     struct nk_color selected_normal;
   4958     struct nk_color selected_hover;
   4959     struct nk_color selected_text_normal;
   4960     struct nk_color selected_text_hover;
   4961 
   4962     /* properties */
   4963     float border;
   4964     float rounding;
   4965     float cursor_size;
   4966     struct nk_vec2 scrollbar_size;
   4967     struct nk_vec2 padding;
   4968     float row_padding;
   4969 };
   4970 
   4971 struct nk_style_property {
   4972     /* background */
   4973     struct nk_style_item normal;
   4974     struct nk_style_item hover;
   4975     struct nk_style_item active;
   4976     struct nk_color border_color;
   4977 
   4978     /* text */
   4979     struct nk_color label_normal;
   4980     struct nk_color label_hover;
   4981     struct nk_color label_active;
   4982 
   4983     /* symbols */
   4984     enum nk_symbol_type sym_left;
   4985     enum nk_symbol_type sym_right;
   4986 
   4987     /* properties */
   4988     float border;
   4989     float rounding;
   4990     struct nk_vec2 padding;
   4991 
   4992     struct nk_style_edit edit;
   4993     struct nk_style_button inc_button;
   4994     struct nk_style_button dec_button;
   4995 
   4996     /* optional user callbacks */
   4997     nk_handle userdata;
   4998     void(*draw_begin)(struct nk_command_buffer*, nk_handle);
   4999     void(*draw_end)(struct nk_command_buffer*, nk_handle);
   5000 };
   5001 
   5002 struct nk_style_chart {
   5003     /* colors */
   5004     struct nk_style_item background;
   5005     struct nk_color border_color;
   5006     struct nk_color selected_color;
   5007     struct nk_color color;
   5008 
   5009     /* properties */
   5010     float border;
   5011     float rounding;
   5012     struct nk_vec2 padding;
   5013 };
   5014 
   5015 struct nk_style_combo {
   5016     /* background */
   5017     struct nk_style_item normal;
   5018     struct nk_style_item hover;
   5019     struct nk_style_item active;
   5020     struct nk_color border_color;
   5021 
   5022     /* label */
   5023     struct nk_color label_normal;
   5024     struct nk_color label_hover;
   5025     struct nk_color label_active;
   5026 
   5027     /* symbol */
   5028     struct nk_color symbol_normal;
   5029     struct nk_color symbol_hover;
   5030     struct nk_color symbol_active;
   5031 
   5032     /* button */
   5033     struct nk_style_button button;
   5034     enum nk_symbol_type sym_normal;
   5035     enum nk_symbol_type sym_hover;
   5036     enum nk_symbol_type sym_active;
   5037 
   5038     /* properties */
   5039     float border;
   5040     float rounding;
   5041     struct nk_vec2 content_padding;
   5042     struct nk_vec2 button_padding;
   5043     struct nk_vec2 spacing;
   5044 };
   5045 
   5046 struct nk_style_tab {
   5047     /* background */
   5048     struct nk_style_item background;
   5049     struct nk_color border_color;
   5050     struct nk_color text;
   5051 
   5052     /* button */
   5053     struct nk_style_button tab_maximize_button;
   5054     struct nk_style_button tab_minimize_button;
   5055     struct nk_style_button node_maximize_button;
   5056     struct nk_style_button node_minimize_button;
   5057     enum nk_symbol_type sym_minimize;
   5058     enum nk_symbol_type sym_maximize;
   5059 
   5060     /* properties */
   5061     float border;
   5062     float rounding;
   5063     float indent;
   5064     struct nk_vec2 padding;
   5065     struct nk_vec2 spacing;
   5066 };
   5067 
   5068 enum nk_style_header_align {
   5069     NK_HEADER_LEFT,
   5070     NK_HEADER_RIGHT
   5071 };
   5072 struct nk_style_window_header {
   5073     /* background */
   5074     struct nk_style_item normal;
   5075     struct nk_style_item hover;
   5076     struct nk_style_item active;
   5077 
   5078     /* button */
   5079     struct nk_style_button close_button;
   5080     struct nk_style_button minimize_button;
   5081     enum nk_symbol_type close_symbol;
   5082     enum nk_symbol_type minimize_symbol;
   5083     enum nk_symbol_type maximize_symbol;
   5084 
   5085     /* title */
   5086     struct nk_color label_normal;
   5087     struct nk_color label_hover;
   5088     struct nk_color label_active;
   5089 
   5090     /* properties */
   5091     enum nk_style_header_align align;
   5092     struct nk_vec2 padding;
   5093     struct nk_vec2 label_padding;
   5094     struct nk_vec2 spacing;
   5095 };
   5096 
   5097 struct nk_style_window {
   5098     struct nk_style_window_header header;
   5099     struct nk_style_item fixed_background;
   5100     struct nk_color background;
   5101 
   5102     struct nk_color border_color;
   5103     struct nk_color popup_border_color;
   5104     struct nk_color combo_border_color;
   5105     struct nk_color contextual_border_color;
   5106     struct nk_color menu_border_color;
   5107     struct nk_color group_border_color;
   5108     struct nk_color tooltip_border_color;
   5109     struct nk_style_item scaler;
   5110 
   5111     float border;
   5112     float combo_border;
   5113     float contextual_border;
   5114     float menu_border;
   5115     float group_border;
   5116     float tooltip_border;
   5117     float popup_border;
   5118     float min_row_height_padding;
   5119 
   5120     float rounding;
   5121     struct nk_vec2 spacing;
   5122     struct nk_vec2 scrollbar_size;
   5123     struct nk_vec2 min_size;
   5124 
   5125     struct nk_vec2 padding;
   5126     struct nk_vec2 group_padding;
   5127     struct nk_vec2 popup_padding;
   5128     struct nk_vec2 combo_padding;
   5129     struct nk_vec2 contextual_padding;
   5130     struct nk_vec2 menu_padding;
   5131     struct nk_vec2 tooltip_padding;
   5132 };
   5133 
   5134 struct nk_style {
   5135     const struct nk_user_font *font;
   5136     const struct nk_cursor *cursors[NK_CURSOR_COUNT];
   5137     const struct nk_cursor *cursor_active;
   5138     struct nk_cursor *cursor_last;
   5139     int cursor_visible;
   5140 
   5141     struct nk_style_text text;
   5142     struct nk_style_button button;
   5143     struct nk_style_button contextual_button;
   5144     struct nk_style_button menu_button;
   5145     struct nk_style_toggle option;
   5146     struct nk_style_toggle checkbox;
   5147     struct nk_style_selectable selectable;
   5148     struct nk_style_slider slider;
   5149     struct nk_style_progress progress;
   5150     struct nk_style_property property;
   5151     struct nk_style_edit edit;
   5152     struct nk_style_chart chart;
   5153     struct nk_style_scrollbar scrollh;
   5154     struct nk_style_scrollbar scrollv;
   5155     struct nk_style_tab tab;
   5156     struct nk_style_combo combo;
   5157     struct nk_style_window window;
   5158 };
   5159 
   5160 NK_API struct nk_style_item nk_style_item_image(struct nk_image img);
   5161 NK_API struct nk_style_item nk_style_item_color(struct nk_color);
   5162 NK_API struct nk_style_item nk_style_item_hide(void);
   5163 
   5164 /*==============================================================
   5165  *                          PANEL
   5166  * =============================================================*/
   5167 #ifndef NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS
   5168 #define NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS 16
   5169 #endif
   5170 #ifndef NK_CHART_MAX_SLOT
   5171 #define NK_CHART_MAX_SLOT 4
   5172 #endif
   5173 
   5174 enum nk_panel_type {
   5175     NK_PANEL_NONE       = 0,
   5176     NK_PANEL_WINDOW     = NK_FLAG(0),
   5177     NK_PANEL_GROUP      = NK_FLAG(1),
   5178     NK_PANEL_POPUP      = NK_FLAG(2),
   5179     NK_PANEL_CONTEXTUAL = NK_FLAG(4),
   5180     NK_PANEL_COMBO      = NK_FLAG(5),
   5181     NK_PANEL_MENU       = NK_FLAG(6),
   5182     NK_PANEL_TOOLTIP    = NK_FLAG(7)
   5183 };
   5184 enum nk_panel_set {
   5185     NK_PANEL_SET_NONBLOCK = NK_PANEL_CONTEXTUAL|NK_PANEL_COMBO|NK_PANEL_MENU|NK_PANEL_TOOLTIP,
   5186     NK_PANEL_SET_POPUP = NK_PANEL_SET_NONBLOCK|NK_PANEL_POPUP,
   5187     NK_PANEL_SET_SUB = NK_PANEL_SET_POPUP|NK_PANEL_GROUP
   5188 };
   5189 
   5190 struct nk_chart_slot {
   5191     enum nk_chart_type type;
   5192     struct nk_color color;
   5193     struct nk_color highlight;
   5194     float min, max, range;
   5195     int count;
   5196     struct nk_vec2 last;
   5197     int index;
   5198 };
   5199 
   5200 struct nk_chart {
   5201     int slot;
   5202     float x, y, w, h;
   5203     struct nk_chart_slot slots[NK_CHART_MAX_SLOT];
   5204 };
   5205 
   5206 enum nk_panel_row_layout_type {
   5207     NK_LAYOUT_DYNAMIC_FIXED = 0,
   5208     NK_LAYOUT_DYNAMIC_ROW,
   5209     NK_LAYOUT_DYNAMIC_FREE,
   5210     NK_LAYOUT_DYNAMIC,
   5211     NK_LAYOUT_STATIC_FIXED,
   5212     NK_LAYOUT_STATIC_ROW,
   5213     NK_LAYOUT_STATIC_FREE,
   5214     NK_LAYOUT_STATIC,
   5215     NK_LAYOUT_TEMPLATE,
   5216     NK_LAYOUT_COUNT
   5217 };
   5218 struct nk_row_layout {
   5219     enum nk_panel_row_layout_type type;
   5220     int index;
   5221     float height;
   5222     float min_height;
   5223     int columns;
   5224     const float *ratio;
   5225     float item_width;
   5226     float item_height;
   5227     float item_offset;
   5228     float filled;
   5229     struct nk_rect item;
   5230     int tree_depth;
   5231     float templates[NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS];
   5232 };
   5233 
   5234 struct nk_popup_buffer {
   5235     nk_size begin;
   5236     nk_size parent;
   5237     nk_size last;
   5238     nk_size end;
   5239     int active;
   5240 };
   5241 
   5242 struct nk_menu_state {
   5243     float x, y, w, h;
   5244     struct nk_scroll offset;
   5245 };
   5246 
   5247 struct nk_panel {
   5248     enum nk_panel_type type;
   5249     nk_flags flags;
   5250     struct nk_rect bounds;
   5251     nk_uint *offset_x;
   5252     nk_uint *offset_y;
   5253     float at_x, at_y, max_x;
   5254     float footer_height;
   5255     float header_height;
   5256     float border;
   5257     unsigned int has_scrolling;
   5258     struct nk_rect clip;
   5259     struct nk_menu_state menu;
   5260     struct nk_row_layout row;
   5261     struct nk_chart chart;
   5262     struct nk_command_buffer *buffer;
   5263     struct nk_panel *parent;
   5264 };
   5265 
   5266 /*==============================================================
   5267  *                          WINDOW
   5268  * =============================================================*/
   5269 #ifndef NK_WINDOW_MAX_NAME
   5270 #define NK_WINDOW_MAX_NAME 64
   5271 #endif
   5272 
   5273 struct nk_table;
   5274 enum nk_window_flags {
   5275     NK_WINDOW_PRIVATE       = NK_FLAG(11),
   5276     NK_WINDOW_DYNAMIC       = NK_WINDOW_PRIVATE,
   5277     /* special window type growing up in height while being filled to a certain maximum height */
   5278     NK_WINDOW_ROM           = NK_FLAG(12),
   5279     /* sets window widgets into a read only mode and does not allow input changes */
   5280     NK_WINDOW_NOT_INTERACTIVE = NK_WINDOW_ROM|NK_WINDOW_NO_INPUT,
   5281     /* prevents all interaction caused by input to either window or widgets inside */
   5282     NK_WINDOW_HIDDEN        = NK_FLAG(13),
   5283     /* Hides window and stops any window interaction and drawing */
   5284     NK_WINDOW_CLOSED        = NK_FLAG(14),
   5285     /* Directly closes and frees the window at the end of the frame */
   5286     NK_WINDOW_MINIMIZED     = NK_FLAG(15),
   5287     /* marks the window as minimized */
   5288     NK_WINDOW_REMOVE_ROM    = NK_FLAG(16)
   5289     /* Removes read only mode at the end of the window */
   5290 };
   5291 
   5292 struct nk_popup_state {
   5293     struct nk_window *win;
   5294     enum nk_panel_type type;
   5295     struct nk_popup_buffer buf;
   5296     nk_hash name;
   5297     int active;
   5298     unsigned combo_count;
   5299     unsigned con_count, con_old;
   5300     unsigned active_con;
   5301     struct nk_rect header;
   5302 };
   5303 
   5304 struct nk_edit_state {
   5305     nk_hash name;
   5306     unsigned int seq;
   5307     unsigned int old;
   5308     int active, prev;
   5309     int cursor;
   5310     int sel_start;
   5311     int sel_end;
   5312     struct nk_scroll scrollbar;
   5313     unsigned char mode;
   5314     unsigned char single_line;
   5315 };
   5316 
   5317 struct nk_property_state {
   5318     int active, prev;
   5319     char buffer[NK_MAX_NUMBER_BUFFER];
   5320     int length;
   5321     int cursor;
   5322     int select_start;
   5323     int select_end;
   5324     nk_hash name;
   5325     unsigned int seq;
   5326     unsigned int old;
   5327     int state;
   5328 };
   5329 
   5330 struct nk_window {
   5331     unsigned int seq;
   5332     nk_hash name;
   5333     char name_string[NK_WINDOW_MAX_NAME];
   5334     nk_flags flags;
   5335 
   5336     struct nk_rect bounds;
   5337     struct nk_scroll scrollbar;
   5338     struct nk_command_buffer buffer;
   5339     struct nk_panel *layout;
   5340     float scrollbar_hiding_timer;
   5341 
   5342     /* persistent widget state */
   5343     struct nk_property_state property;
   5344     struct nk_popup_state popup;
   5345     struct nk_edit_state edit;
   5346     unsigned int scrolled;
   5347 
   5348     struct nk_table *tables;
   5349     unsigned int table_count;
   5350 
   5351     /* window list hooks */
   5352     struct nk_window *next;
   5353     struct nk_window *prev;
   5354     struct nk_window *parent;
   5355 };
   5356 
   5357 /*==============================================================
   5358  *                          STACK
   5359  * =============================================================*/
   5360 /* The style modifier stack can be used to temporarily change a
   5361  * property inside `nk_style`. For example if you want a special
   5362  * red button you can temporarily push the old button color onto a stack
   5363  * draw the button with a red color and then you just pop the old color
   5364  * back from the stack:
   5365  *
   5366  *      nk_style_push_style_item(ctx, &ctx->style.button.normal, nk_style_item_color(nk_rgb(255,0,0)));
   5367  *      nk_style_push_style_item(ctx, &ctx->style.button.hover, nk_style_item_color(nk_rgb(255,0,0)));
   5368  *      nk_style_push_style_item(ctx, &ctx->style.button.active, nk_style_item_color(nk_rgb(255,0,0)));
   5369  *      nk_style_push_vec2(ctx, &cx->style.button.padding, nk_vec2(2,2));
   5370  *
   5371  *      nk_button(...);
   5372  *
   5373  *      nk_style_pop_style_item(ctx);
   5374  *      nk_style_pop_style_item(ctx);
   5375  *      nk_style_pop_style_item(ctx);
   5376  *      nk_style_pop_vec2(ctx);
   5377  *
   5378  * Nuklear has a stack for style_items, float properties, vector properties,
   5379  * flags, colors, fonts and for button_behavior. Each has it's own fixed size stack
   5380  * which can be changed at compile time.
   5381  */
   5382 #ifndef NK_BUTTON_BEHAVIOR_STACK_SIZE
   5383 #define NK_BUTTON_BEHAVIOR_STACK_SIZE 8
   5384 #endif
   5385 
   5386 #ifndef NK_FONT_STACK_SIZE
   5387 #define NK_FONT_STACK_SIZE 8
   5388 #endif
   5389 
   5390 #ifndef NK_STYLE_ITEM_STACK_SIZE
   5391 #define NK_STYLE_ITEM_STACK_SIZE 16
   5392 #endif
   5393 
   5394 #ifndef NK_FLOAT_STACK_SIZE
   5395 #define NK_FLOAT_STACK_SIZE 32
   5396 #endif
   5397 
   5398 #ifndef NK_VECTOR_STACK_SIZE
   5399 #define NK_VECTOR_STACK_SIZE 16
   5400 #endif
   5401 
   5402 #ifndef NK_FLAGS_STACK_SIZE
   5403 #define NK_FLAGS_STACK_SIZE 32
   5404 #endif
   5405 
   5406 #ifndef NK_COLOR_STACK_SIZE
   5407 #define NK_COLOR_STACK_SIZE 32
   5408 #endif
   5409 
   5410 #define NK_CONFIGURATION_STACK_TYPE(prefix, name, type)\
   5411     struct nk_config_stack_##name##_element {\
   5412         prefix##_##type *address;\
   5413         prefix##_##type old_value;\
   5414     }
   5415 #define NK_CONFIG_STACK(type,size)\
   5416     struct nk_config_stack_##type {\
   5417         int head;\
   5418         struct nk_config_stack_##type##_element elements[size];\
   5419     }
   5420 
   5421 #define nk_float float
   5422 NK_CONFIGURATION_STACK_TYPE(struct nk, style_item, style_item);
   5423 NK_CONFIGURATION_STACK_TYPE(nk ,float, float);
   5424 NK_CONFIGURATION_STACK_TYPE(struct nk, vec2, vec2);
   5425 NK_CONFIGURATION_STACK_TYPE(nk ,flags, flags);
   5426 NK_CONFIGURATION_STACK_TYPE(struct nk, color, color);
   5427 NK_CONFIGURATION_STACK_TYPE(const struct nk, user_font, user_font*);
   5428 NK_CONFIGURATION_STACK_TYPE(enum nk, button_behavior, button_behavior);
   5429 
   5430 NK_CONFIG_STACK(style_item, NK_STYLE_ITEM_STACK_SIZE);
   5431 NK_CONFIG_STACK(float, NK_FLOAT_STACK_SIZE);
   5432 NK_CONFIG_STACK(vec2, NK_VECTOR_STACK_SIZE);
   5433 NK_CONFIG_STACK(flags, NK_FLAGS_STACK_SIZE);
   5434 NK_CONFIG_STACK(color, NK_COLOR_STACK_SIZE);
   5435 NK_CONFIG_STACK(user_font, NK_FONT_STACK_SIZE);
   5436 NK_CONFIG_STACK(button_behavior, NK_BUTTON_BEHAVIOR_STACK_SIZE);
   5437 
   5438 struct nk_configuration_stacks {
   5439     struct nk_config_stack_style_item style_items;
   5440     struct nk_config_stack_float floats;
   5441     struct nk_config_stack_vec2 vectors;
   5442     struct nk_config_stack_flags flags;
   5443     struct nk_config_stack_color colors;
   5444     struct nk_config_stack_user_font fonts;
   5445     struct nk_config_stack_button_behavior button_behaviors;
   5446 };
   5447 
   5448 /*==============================================================
   5449  *                          CONTEXT
   5450  * =============================================================*/
   5451 #define NK_VALUE_PAGE_CAPACITY \
   5452     (((NK_MAX(sizeof(struct nk_window),sizeof(struct nk_panel)) / sizeof(nk_uint))) / 2)
   5453 
   5454 struct nk_table {
   5455     unsigned int seq;
   5456     unsigned int size;
   5457     nk_hash keys[NK_VALUE_PAGE_CAPACITY];
   5458     nk_uint values[NK_VALUE_PAGE_CAPACITY];
   5459     struct nk_table *next, *prev;
   5460 };
   5461 
   5462 union nk_page_data {
   5463     struct nk_table tbl;
   5464     struct nk_panel pan;
   5465     struct nk_window win;
   5466 };
   5467 
   5468 struct nk_page_element {
   5469     union nk_page_data data;
   5470     struct nk_page_element *next;
   5471     struct nk_page_element *prev;
   5472 };
   5473 
   5474 struct nk_page {
   5475     unsigned int size;
   5476     struct nk_page *next;
   5477     struct nk_page_element win[1];
   5478 };
   5479 
   5480 struct nk_pool {
   5481     struct nk_allocator alloc;
   5482     enum nk_allocation_type type;
   5483     unsigned int page_count;
   5484     struct nk_page *pages;
   5485     struct nk_page_element *freelist;
   5486     unsigned capacity;
   5487     nk_size size;
   5488     nk_size cap;
   5489 };
   5490 
   5491 struct nk_context {
   5492 /* public: can be accessed freely */
   5493     struct nk_input input;
   5494     struct nk_style style;
   5495     struct nk_buffer memory;
   5496     struct nk_clipboard clip;
   5497     nk_flags last_widget_state;
   5498     enum nk_button_behavior button_behavior;
   5499     struct nk_configuration_stacks stacks;
   5500     float delta_time_seconds;
   5501 
   5502 /* private:
   5503     should only be accessed if you
   5504     know what you are doing */
   5505 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
   5506     struct nk_draw_list draw_list;
   5507 #endif
   5508 #ifdef NK_INCLUDE_COMMAND_USERDATA
   5509     nk_handle userdata;
   5510 #endif
   5511     /* text editor objects are quite big because of an internal
   5512      * undo/redo stack. Therefore it does not make sense to have one for
   5513      * each window for temporary use cases, so I only provide *one* instance
   5514      * for all windows. This works because the content is cleared anyway */
   5515     struct nk_text_edit text_edit;
   5516     /* draw buffer used for overlay drawing operation like cursor */
   5517     struct nk_command_buffer overlay;
   5518 
   5519     /* windows */
   5520     int build;
   5521     int use_pool;
   5522     struct nk_pool pool;
   5523     struct nk_window *begin;
   5524     struct nk_window *end;
   5525     struct nk_window *active;
   5526     struct nk_window *current;
   5527     struct nk_page_element *freelist;
   5528     unsigned int count;
   5529     unsigned int seq;
   5530 };
   5531 
   5532 /* ==============================================================
   5533  *                          MATH
   5534  * =============================================================== */
   5535 #define NK_PI 3.141592654f
   5536 #define NK_UTF_INVALID 0xFFFD
   5537 #define NK_MAX_FLOAT_PRECISION 2
   5538 
   5539 #define NK_UNUSED(x) ((void)(x))
   5540 #define NK_SATURATE(x) (NK_MAX(0, NK_MIN(1.0f, x)))
   5541 #define NK_LEN(a) (sizeof(a)/sizeof(a)[0])
   5542 #define NK_ABS(a) (((a) < 0) ? -(a) : (a))
   5543 #define NK_BETWEEN(x, a, b) ((a) <= (x) && (x) < (b))
   5544 #define NK_INBOX(px, py, x, y, w, h)\
   5545     (NK_BETWEEN(px,x,x+w) && NK_BETWEEN(py,y,y+h))
   5546 #define NK_INTERSECT(x0, y0, w0, h0, x1, y1, w1, h1) \
   5547     (!(((x1 > (x0 + w0)) || ((x1 + w1) < x0) || (y1 > (y0 + h0)) || (y1 + h1) < y0)))
   5548 #define NK_CONTAINS(x, y, w, h, bx, by, bw, bh)\
   5549     (NK_INBOX(x,y, bx, by, bw, bh) && NK_INBOX(x+w,y+h, bx, by, bw, bh))
   5550 
   5551 #define nk_vec2_sub(a, b) nk_vec2((a).x - (b).x, (a).y - (b).y)
   5552 #define nk_vec2_add(a, b) nk_vec2((a).x + (b).x, (a).y + (b).y)
   5553 #define nk_vec2_len_sqr(a) ((a).x*(a).x+(a).y*(a).y)
   5554 #define nk_vec2_muls(a, t) nk_vec2((a).x * (t), (a).y * (t))
   5555 
   5556 #define nk_ptr_add(t, p, i) ((t*)((void*)((nk_byte*)(p) + (i))))
   5557 #define nk_ptr_add_const(t, p, i) ((const t*)((const void*)((const nk_byte*)(p) + (i))))
   5558 #define nk_zero_struct(s) nk_zero(&s, sizeof(s))
   5559 
   5560 /* ==============================================================
   5561  *                          ALIGNMENT
   5562  * =============================================================== */
   5563 /* Pointer to Integer type conversion for pointer alignment */
   5564 #if defined(__PTRDIFF_TYPE__) /* This case should work for GCC*/
   5565 # define NK_UINT_TO_PTR(x) ((void*)(__PTRDIFF_TYPE__)(x))
   5566 # define NK_PTR_TO_UINT(x) ((nk_size)(__PTRDIFF_TYPE__)(x))
   5567 #elif !defined(__GNUC__) /* works for compilers other than LLVM */
   5568 # define NK_UINT_TO_PTR(x) ((void*)&((char*)0)[x])
   5569 # define NK_PTR_TO_UINT(x) ((nk_size)(((char*)x)-(char*)0))
   5570 #elif defined(NK_USE_FIXED_TYPES) /* used if we have <stdint.h> */
   5571 # define NK_UINT_TO_PTR(x) ((void*)(uintptr_t)(x))
   5572 # define NK_PTR_TO_UINT(x) ((uintptr_t)(x))
   5573 #else /* generates warning but works */
   5574 # define NK_UINT_TO_PTR(x) ((void*)(x))
   5575 # define NK_PTR_TO_UINT(x) ((nk_size)(x))
   5576 #endif
   5577 
   5578 #define NK_ALIGN_PTR(x, mask)\
   5579     (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte*)(x) + (mask-1)) & ~(mask-1))))
   5580 #define NK_ALIGN_PTR_BACK(x, mask)\
   5581     (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte*)(x)) & ~(mask-1))))
   5582 
   5583 #define NK_OFFSETOF(st,m) ((nk_ptr)&(((st*)0)->m))
   5584 #define NK_CONTAINER_OF(ptr,type,member)\
   5585     (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member)))
   5586 
   5587 #ifdef __cplusplus
   5588 }
   5589 #endif
   5590 
   5591 #ifdef __cplusplus
   5592 template<typename T> struct nk_alignof;
   5593 template<typename T, int size_diff> struct nk_helper{enum {value = size_diff};};
   5594 template<typename T> struct nk_helper<T,0>{enum {value = nk_alignof<T>::value};};
   5595 template<typename T> struct nk_alignof{struct Big {T x; char c;}; enum {
   5596     diff = sizeof(Big) - sizeof(T), value = nk_helper<Big, diff>::value};};
   5597 #define NK_ALIGNOF(t) (nk_alignof<t>::value)
   5598 #elif defined(_MSC_VER)
   5599 #define NK_ALIGNOF(t) (__alignof(t))
   5600 #else
   5601 #define NK_ALIGNOF(t) ((char*)(&((struct {char c; t _h;}*)0)->_h) - (char*)0)
   5602 #endif
   5603 
   5604 #endif /* NK_NUKLEAR_H_ */
   5605 
   5606 
   5607 #ifdef NK_IMPLEMENTATION
   5608 
   5609 #ifndef NK_INTERNAL_H
   5610 #define NK_INTERNAL_H
   5611 
   5612 #ifndef NK_POOL_DEFAULT_CAPACITY
   5613 #define NK_POOL_DEFAULT_CAPACITY 16
   5614 #endif
   5615 
   5616 #ifndef NK_DEFAULT_COMMAND_BUFFER_SIZE
   5617 #define NK_DEFAULT_COMMAND_BUFFER_SIZE (4*1024)
   5618 #endif
   5619 
   5620 #ifndef NK_BUFFER_DEFAULT_INITIAL_SIZE
   5621 #define NK_BUFFER_DEFAULT_INITIAL_SIZE (4*1024)
   5622 #endif
   5623 
   5624 /* standard library headers */
   5625 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
   5626 #include <stdlib.h> /* malloc, free */
   5627 #endif
   5628 #ifdef NK_INCLUDE_STANDARD_IO
   5629 #include <stdio.h> /* fopen, fclose,... */
   5630 #endif
   5631 #ifndef NK_ASSERT
   5632 #include <assert.h>
   5633 #define NK_ASSERT(expr) assert(expr)
   5634 #endif
   5635 
   5636 #ifndef NK_MEMSET
   5637 #define NK_MEMSET nk_memset
   5638 #endif
   5639 #ifndef NK_MEMCPY
   5640 #define NK_MEMCPY nk_memcopy
   5641 #endif
   5642 #ifndef NK_SQRT
   5643 #define NK_SQRT nk_sqrt
   5644 #endif
   5645 #ifndef NK_SIN
   5646 #define NK_SIN nk_sin
   5647 #endif
   5648 #ifndef NK_COS
   5649 #define NK_COS nk_cos
   5650 #endif
   5651 #ifndef NK_STRTOD
   5652 #define NK_STRTOD nk_strtod
   5653 #endif
   5654 #ifndef NK_DTOA
   5655 #define NK_DTOA nk_dtoa
   5656 #endif
   5657 
   5658 #define NK_DEFAULT (-1)
   5659 
   5660 #ifndef NK_VSNPRINTF
   5661 /* If your compiler does support `vsnprintf` I would highly recommend
   5662  * defining this to vsnprintf instead since `vsprintf` is basically
   5663  * unbelievable unsafe and should *NEVER* be used. But I have to support
   5664  * it since C89 only provides this unsafe version. */
   5665   #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) ||\
   5666       (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
   5667       (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) ||\
   5668       (defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)) ||\
   5669        defined(_ISOC99_SOURCE) || defined(_BSD_SOURCE)
   5670       #define NK_VSNPRINTF(s,n,f,a) vsnprintf(s,n,f,a)
   5671   #else
   5672     #define NK_VSNPRINTF(s,n,f,a) vsprintf(s,f,a)
   5673   #endif
   5674 #endif
   5675 
   5676 #define NK_SCHAR_MIN (-127)
   5677 #define NK_SCHAR_MAX 127
   5678 #define NK_UCHAR_MIN 0
   5679 #define NK_UCHAR_MAX 256
   5680 #define NK_SSHORT_MIN (-32767)
   5681 #define NK_SSHORT_MAX 32767
   5682 #define NK_USHORT_MIN 0
   5683 #define NK_USHORT_MAX 65535
   5684 #define NK_SINT_MIN (-2147483647)
   5685 #define NK_SINT_MAX 2147483647
   5686 #define NK_UINT_MIN 0
   5687 #define NK_UINT_MAX 4294967295u
   5688 
   5689 /* Make sure correct type size:
   5690  * This will fire with a negative subscript error if the type sizes
   5691  * are set incorrectly by the compiler, and compile out if not */
   5692 NK_STATIC_ASSERT(sizeof(nk_size) >= sizeof(void*));
   5693 NK_STATIC_ASSERT(sizeof(nk_ptr) == sizeof(void*));
   5694 NK_STATIC_ASSERT(sizeof(nk_flags) >= 4);
   5695 NK_STATIC_ASSERT(sizeof(nk_rune) >= 4);
   5696 NK_STATIC_ASSERT(sizeof(nk_ushort) == 2);
   5697 NK_STATIC_ASSERT(sizeof(nk_short) == 2);
   5698 NK_STATIC_ASSERT(sizeof(nk_uint) == 4);
   5699 NK_STATIC_ASSERT(sizeof(nk_int) == 4);
   5700 NK_STATIC_ASSERT(sizeof(nk_byte) == 1);
   5701 
   5702 NK_GLOBAL const struct nk_rect nk_null_rect = {-8192.0f, -8192.0f, 16384, 16384};
   5703 #define NK_FLOAT_PRECISION 0.00000000000001
   5704 
   5705 NK_GLOBAL const struct nk_color nk_red = {255,0,0,255};
   5706 NK_GLOBAL const struct nk_color nk_green = {0,255,0,255};
   5707 NK_GLOBAL const struct nk_color nk_blue = {0,0,255,255};
   5708 NK_GLOBAL const struct nk_color nk_white = {255,255,255,255};
   5709 NK_GLOBAL const struct nk_color nk_black = {0,0,0,255};
   5710 NK_GLOBAL const struct nk_color nk_yellow = {255,255,0,255};
   5711 
   5712 /* widget */
   5713 #define nk_widget_state_reset(s)\
   5714     if ((*(s)) & NK_WIDGET_STATE_MODIFIED)\
   5715         (*(s)) = NK_WIDGET_STATE_INACTIVE|NK_WIDGET_STATE_MODIFIED;\
   5716     else (*(s)) = NK_WIDGET_STATE_INACTIVE;
   5717 
   5718 /* math */
   5719 NK_LIB float nk_inv_sqrt(float n);
   5720 NK_LIB float nk_sqrt(float x);
   5721 NK_LIB float nk_sin(float x);
   5722 NK_LIB float nk_cos(float x);
   5723 NK_LIB nk_uint nk_round_up_pow2(nk_uint v);
   5724 NK_LIB struct nk_rect nk_shrink_rect(struct nk_rect r, float amount);
   5725 NK_LIB struct nk_rect nk_pad_rect(struct nk_rect r, struct nk_vec2 pad);
   5726 NK_LIB void nk_unify(struct nk_rect *clip, const struct nk_rect *a, float x0, float y0, float x1, float y1);
   5727 NK_LIB double nk_pow(double x, int n);
   5728 NK_LIB int nk_ifloord(double x);
   5729 NK_LIB int nk_ifloorf(float x);
   5730 NK_LIB int nk_iceilf(float x);
   5731 NK_LIB int nk_log10(double n);
   5732 
   5733 /* util */
   5734 enum {NK_DO_NOT_STOP_ON_NEW_LINE, NK_STOP_ON_NEW_LINE};
   5735 NK_LIB int nk_is_lower(int c);
   5736 NK_LIB int nk_is_upper(int c);
   5737 NK_LIB int nk_to_upper(int c);
   5738 NK_LIB int nk_to_lower(int c);
   5739 NK_LIB void* nk_memcopy(void *dst, const void *src, nk_size n);
   5740 NK_LIB void nk_memset(void *ptr, int c0, nk_size size);
   5741 NK_LIB void nk_zero(void *ptr, nk_size size);
   5742 NK_LIB char *nk_itoa(char *s, long n);
   5743 NK_LIB int nk_string_float_limit(char *string, int prec);
   5744 NK_LIB char *nk_dtoa(char *s, double n);
   5745 NK_LIB int nk_text_clamp(const struct nk_user_font *font, const char *text, int text_len, float space, int *glyphs, float *text_width, nk_rune *sep_list, int sep_count);
   5746 NK_LIB struct nk_vec2 nk_text_calculate_text_bounds(const struct nk_user_font *font, const char *begin, int byte_len, float row_height, const char **remaining, struct nk_vec2 *out_offset, int *glyphs, int op);
   5747 #ifdef NK_INCLUDE_STANDARD_VARARGS
   5748 NK_LIB int nk_strfmt(char *buf, int buf_size, const char *fmt, va_list args);
   5749 #endif
   5750 #ifdef NK_INCLUDE_STANDARD_IO
   5751 NK_LIB char *nk_file_load(const char* path, nk_size* siz, struct nk_allocator *alloc);
   5752 #endif
   5753 
   5754 /* buffer */
   5755 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
   5756 NK_LIB void* nk_malloc(nk_handle unused, void *old,nk_size size);
   5757 NK_LIB void nk_mfree(nk_handle unused, void *ptr);
   5758 #endif
   5759 NK_LIB void* nk_buffer_align(void *unaligned, nk_size align, nk_size *alignment, enum nk_buffer_allocation_type type);
   5760 NK_LIB void* nk_buffer_alloc(struct nk_buffer *b, enum nk_buffer_allocation_type type, nk_size size, nk_size align);
   5761 NK_LIB void* nk_buffer_realloc(struct nk_buffer *b, nk_size capacity, nk_size *size);
   5762 
   5763 /* draw */
   5764 NK_LIB void nk_command_buffer_init(struct nk_command_buffer *cb, struct nk_buffer *b, enum nk_command_clipping clip);
   5765 NK_LIB void nk_command_buffer_reset(struct nk_command_buffer *b);
   5766 NK_LIB void* nk_command_buffer_push(struct nk_command_buffer* b, enum nk_command_type t, nk_size size);
   5767 NK_LIB void nk_draw_symbol(struct nk_command_buffer *out, enum nk_symbol_type type, struct nk_rect content, struct nk_color background, struct nk_color foreground, float border_width, const struct nk_user_font *font);
   5768 
   5769 /* buffering */
   5770 NK_LIB void nk_start_buffer(struct nk_context *ctx, struct nk_command_buffer *b);
   5771 NK_LIB void nk_start(struct nk_context *ctx, struct nk_window *win);
   5772 NK_LIB void nk_start_popup(struct nk_context *ctx, struct nk_window *win);
   5773 NK_LIB void nk_finish_popup(struct nk_context *ctx, struct nk_window*);
   5774 NK_LIB void nk_finish_buffer(struct nk_context *ctx, struct nk_command_buffer *b);
   5775 NK_LIB void nk_finish(struct nk_context *ctx, struct nk_window *w);
   5776 NK_LIB void nk_build(struct nk_context *ctx);
   5777 
   5778 /* text editor */
   5779 NK_LIB void nk_textedit_clear_state(struct nk_text_edit *state, enum nk_text_edit_type type, nk_plugin_filter filter);
   5780 NK_LIB void nk_textedit_click(struct nk_text_edit *state, float x, float y, const struct nk_user_font *font, float row_height);
   5781 NK_LIB void nk_textedit_drag(struct nk_text_edit *state, float x, float y, const struct nk_user_font *font, float row_height);
   5782 NK_LIB void nk_textedit_key(struct nk_text_edit *state, enum nk_keys key, int shift_mod, const struct nk_user_font *font, float row_height);
   5783 
   5784 /* window */
   5785 enum nk_window_insert_location {
   5786     NK_INSERT_BACK, /* inserts window into the back of list (front of screen) */
   5787     NK_INSERT_FRONT /* inserts window into the front of list (back of screen) */
   5788 };
   5789 NK_LIB void *nk_create_window(struct nk_context *ctx);
   5790 NK_LIB void nk_remove_window(struct nk_context*, struct nk_window*);
   5791 NK_LIB void nk_free_window(struct nk_context *ctx, struct nk_window *win);
   5792 NK_LIB struct nk_window *nk_find_window(struct nk_context *ctx, nk_hash hash, const char *name);
   5793 NK_LIB void nk_insert_window(struct nk_context *ctx, struct nk_window *win, enum nk_window_insert_location loc);
   5794 
   5795 /* pool */
   5796 NK_LIB void nk_pool_init(struct nk_pool *pool, struct nk_allocator *alloc, unsigned int capacity);
   5797 NK_LIB void nk_pool_free(struct nk_pool *pool);
   5798 NK_LIB void nk_pool_init_fixed(struct nk_pool *pool, void *memory, nk_size size);
   5799 NK_LIB struct nk_page_element *nk_pool_alloc(struct nk_pool *pool);
   5800 
   5801 /* page-element */
   5802 NK_LIB struct nk_page_element* nk_create_page_element(struct nk_context *ctx);
   5803 NK_LIB void nk_link_page_element_into_freelist(struct nk_context *ctx, struct nk_page_element *elem);
   5804 NK_LIB void nk_free_page_element(struct nk_context *ctx, struct nk_page_element *elem);
   5805 
   5806 /* table */
   5807 NK_LIB struct nk_table* nk_create_table(struct nk_context *ctx);
   5808 NK_LIB void nk_remove_table(struct nk_window *win, struct nk_table *tbl);
   5809 NK_LIB void nk_free_table(struct nk_context *ctx, struct nk_table *tbl);
   5810 NK_LIB void nk_push_table(struct nk_window *win, struct nk_table *tbl);
   5811 NK_LIB nk_uint *nk_add_value(struct nk_context *ctx, struct nk_window *win, nk_hash name, nk_uint value);
   5812 NK_LIB nk_uint *nk_find_value(struct nk_window *win, nk_hash name);
   5813 
   5814 /* panel */
   5815 NK_LIB void *nk_create_panel(struct nk_context *ctx);
   5816 NK_LIB void nk_free_panel(struct nk_context*, struct nk_panel *pan);
   5817 NK_LIB int nk_panel_has_header(nk_flags flags, const char *title);
   5818 NK_LIB struct nk_vec2 nk_panel_get_padding(const struct nk_style *style, enum nk_panel_type type);
   5819 NK_LIB float nk_panel_get_border(const struct nk_style *style, nk_flags flags, enum nk_panel_type type);
   5820 NK_LIB struct nk_color nk_panel_get_border_color(const struct nk_style *style, enum nk_panel_type type);
   5821 NK_LIB int nk_panel_is_sub(enum nk_panel_type type);
   5822 NK_LIB int nk_panel_is_nonblock(enum nk_panel_type type);
   5823 NK_LIB int nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type panel_type);
   5824 NK_LIB void nk_panel_end(struct nk_context *ctx);
   5825 
   5826 /* layout */
   5827 NK_LIB float nk_layout_row_calculate_usable_space(const struct nk_style *style, enum nk_panel_type type, float total_space, int columns);
   5828 NK_LIB void nk_panel_layout(const struct nk_context *ctx, struct nk_window *win, float height, int cols);
   5829 NK_LIB void nk_row_layout(struct nk_context *ctx, enum nk_layout_format fmt, float height, int cols, int width);
   5830 NK_LIB void nk_panel_alloc_row(const struct nk_context *ctx, struct nk_window *win);
   5831 NK_LIB void nk_layout_widget_space(struct nk_rect *bounds, const struct nk_context *ctx, struct nk_window *win, int modify);
   5832 NK_LIB void nk_panel_alloc_space(struct nk_rect *bounds, const struct nk_context *ctx);
   5833 NK_LIB void nk_layout_peek(struct nk_rect *bounds, struct nk_context *ctx);
   5834 
   5835 /* popup */
   5836 NK_LIB int nk_nonblock_begin(struct nk_context *ctx, nk_flags flags, struct nk_rect body, struct nk_rect header, enum nk_panel_type panel_type);
   5837 
   5838 /* text */
   5839 struct nk_text {
   5840     struct nk_vec2 padding;
   5841     struct nk_color background;
   5842     struct nk_color text;
   5843 };
   5844 NK_LIB void nk_widget_text(struct nk_command_buffer *o, struct nk_rect b, const char *string, int len, const struct nk_text *t, nk_flags a, const struct nk_user_font *f);
   5845 NK_LIB void nk_widget_text_wrap(struct nk_command_buffer *o, struct nk_rect b, const char *string, int len, const struct nk_text *t, const struct nk_user_font *f);
   5846 
   5847 /* button */
   5848 NK_LIB int nk_button_behavior(nk_flags *state, struct nk_rect r, const struct nk_input *i, enum nk_button_behavior behavior);
   5849 NK_LIB const struct nk_style_item* nk_draw_button(struct nk_command_buffer *out, const struct nk_rect *bounds, nk_flags state, const struct nk_style_button *style);
   5850 NK_LIB int nk_do_button(nk_flags *state, struct nk_command_buffer *out, struct nk_rect r, const struct nk_style_button *style, const struct nk_input *in, enum nk_button_behavior behavior, struct nk_rect *content);
   5851 NK_LIB void nk_draw_button_text(struct nk_command_buffer *out, const struct nk_rect *bounds, const struct nk_rect *content, nk_flags state, const struct nk_style_button *style, const char *txt, int len, nk_flags text_alignment, const struct nk_user_font *font);
   5852 NK_LIB int nk_do_button_text(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, const char *string, int len, nk_flags align, enum nk_button_behavior behavior, const struct nk_style_button *style, const struct nk_input *in, const struct nk_user_font *font);
   5853 NK_LIB void nk_draw_button_symbol(struct nk_command_buffer *out, const struct nk_rect *bounds, const struct nk_rect *content, nk_flags state, const struct nk_style_button *style, enum nk_symbol_type type, const struct nk_user_font *font);
   5854 NK_LIB int nk_do_button_symbol(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, enum nk_symbol_type symbol, enum nk_button_behavior behavior, const struct nk_style_button *style, const struct nk_input *in, const struct nk_user_font *font);
   5855 NK_LIB void nk_draw_button_image(struct nk_command_buffer *out, const struct nk_rect *bounds, const struct nk_rect *content, nk_flags state, const struct nk_style_button *style, const struct nk_image *img);
   5856 NK_LIB int nk_do_button_image(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, struct nk_image img, enum nk_button_behavior b, const struct nk_style_button *style, const struct nk_input *in);
   5857 NK_LIB void nk_draw_button_text_symbol(struct nk_command_buffer *out, const struct nk_rect *bounds, const struct nk_rect *label, const struct nk_rect *symbol, nk_flags state, const struct nk_style_button *style, const char *str, int len, enum nk_symbol_type type, const struct nk_user_font *font);
   5858 NK_LIB int nk_do_button_text_symbol(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, enum nk_symbol_type symbol, const char *str, int len, nk_flags align, enum nk_button_behavior behavior, const struct nk_style_button *style, const struct nk_user_font *font, const struct nk_input *in);
   5859 NK_LIB void nk_draw_button_text_image(struct nk_command_buffer *out, const struct nk_rect *bounds, const struct nk_rect *label, const struct nk_rect *image, nk_flags state, const struct nk_style_button *style, const char *str, int len, const struct nk_user_font *font, const struct nk_image *img);
   5860 NK_LIB int nk_do_button_text_image(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, struct nk_image img, const char* str, int len, nk_flags align, enum nk_button_behavior behavior, const struct nk_style_button *style, const struct nk_user_font *font, const struct nk_input *in);
   5861 
   5862 /* toggle */
   5863 enum nk_toggle_type {
   5864     NK_TOGGLE_CHECK,
   5865     NK_TOGGLE_OPTION
   5866 };
   5867 NK_LIB int nk_toggle_behavior(const struct nk_input *in, struct nk_rect select, nk_flags *state, int active);
   5868 NK_LIB void nk_draw_checkbox(struct nk_command_buffer *out, nk_flags state, const struct nk_style_toggle *style, int active, const struct nk_rect *label, const struct nk_rect *selector, const struct nk_rect *cursors, const char *string, int len, const struct nk_user_font *font);
   5869 NK_LIB void nk_draw_option(struct nk_command_buffer *out, nk_flags state, const struct nk_style_toggle *style, int active, const struct nk_rect *label, const struct nk_rect *selector, const struct nk_rect *cursors, const char *string, int len, const struct nk_user_font *font);
   5870 NK_LIB int nk_do_toggle(nk_flags *state, struct nk_command_buffer *out, struct nk_rect r, int *active, const char *str, int len, enum nk_toggle_type type, const struct nk_style_toggle *style, const struct nk_input *in, const struct nk_user_font *font);
   5871 
   5872 /* progress */
   5873 NK_LIB nk_size nk_progress_behavior(nk_flags *state, struct nk_input *in, struct nk_rect r, struct nk_rect cursor, nk_size max, nk_size value, int modifiable);
   5874 NK_LIB void nk_draw_progress(struct nk_command_buffer *out, nk_flags state, const struct nk_style_progress *style, const struct nk_rect *bounds, const struct nk_rect *scursor, nk_size value, nk_size max);
   5875 NK_LIB nk_size nk_do_progress(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, nk_size value, nk_size max, int modifiable, const struct nk_style_progress *style, struct nk_input *in);
   5876 
   5877 /* slider */
   5878 NK_LIB float nk_slider_behavior(nk_flags *state, struct nk_rect *logical_cursor, struct nk_rect *visual_cursor, struct nk_input *in, struct nk_rect bounds, float slider_min, float slider_max, float slider_value, float slider_step, float slider_steps);
   5879 NK_LIB void nk_draw_slider(struct nk_command_buffer *out, nk_flags state, const struct nk_style_slider *style, const struct nk_rect *bounds, const struct nk_rect *visual_cursor, float min, float value, float max);
   5880 NK_LIB float nk_do_slider(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, float min, float val, float max, float step, const struct nk_style_slider *style, struct nk_input *in, const struct nk_user_font *font);
   5881 
   5882 /* scrollbar */
   5883 NK_LIB float nk_scrollbar_behavior(nk_flags *state, struct nk_input *in, int has_scrolling, const struct nk_rect *scroll, const struct nk_rect *cursor, const struct nk_rect *empty0, const struct nk_rect *empty1, float scroll_offset, float target, float scroll_step, enum nk_orientation o);
   5884 NK_LIB void nk_draw_scrollbar(struct nk_command_buffer *out, nk_flags state, const struct nk_style_scrollbar *style, const struct nk_rect *bounds, const struct nk_rect *scroll);
   5885 NK_LIB float nk_do_scrollbarv(nk_flags *state, struct nk_command_buffer *out, struct nk_rect scroll, int has_scrolling, float offset, float target, float step, float button_pixel_inc, const struct nk_style_scrollbar *style, struct nk_input *in, const struct nk_user_font *font);
   5886 NK_LIB float nk_do_scrollbarh(nk_flags *state, struct nk_command_buffer *out, struct nk_rect scroll, int has_scrolling, float offset, float target, float step, float button_pixel_inc, const struct nk_style_scrollbar *style, struct nk_input *in, const struct nk_user_font *font);
   5887 
   5888 /* selectable */
   5889 NK_LIB void nk_draw_selectable(struct nk_command_buffer *out, nk_flags state, const struct nk_style_selectable *style, int active, const struct nk_rect *bounds, const struct nk_rect *icon, const struct nk_image *img, enum nk_symbol_type sym, const char *string, int len, nk_flags align, const struct nk_user_font *font);
   5890 NK_LIB int nk_do_selectable(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, const char *str, int len, nk_flags align, int *value, const struct nk_style_selectable *style, const struct nk_input *in, const struct nk_user_font *font);
   5891 NK_LIB int nk_do_selectable_image(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, const char *str, int len, nk_flags align, int *value, const struct nk_image *img, const struct nk_style_selectable *style, const struct nk_input *in, const struct nk_user_font *font);
   5892 
   5893 /* edit */
   5894 NK_LIB void nk_edit_draw_text(struct nk_command_buffer *out, const struct nk_style_edit *style, float pos_x, float pos_y, float x_offset, const char *text, int byte_len, float row_height, const struct nk_user_font *font, struct nk_color background, struct nk_color foreground, int is_selected);
   5895 NK_LIB nk_flags nk_do_edit(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, nk_flags flags, nk_plugin_filter filter, struct nk_text_edit *edit, const struct nk_style_edit *style, struct nk_input *in, const struct nk_user_font *font);
   5896 
   5897 /* color-picker */
   5898 NK_LIB int nk_color_picker_behavior(nk_flags *state, const struct nk_rect *bounds, const struct nk_rect *matrix, const struct nk_rect *hue_bar, const struct nk_rect *alpha_bar, struct nk_colorf *color, const struct nk_input *in);
   5899 NK_LIB void nk_draw_color_picker(struct nk_command_buffer *o, const struct nk_rect *matrix, const struct nk_rect *hue_bar, const struct nk_rect *alpha_bar, struct nk_colorf col);
   5900 NK_LIB int nk_do_color_picker(nk_flags *state, struct nk_command_buffer *out, struct nk_colorf *col, enum nk_color_format fmt, struct nk_rect bounds, struct nk_vec2 padding, const struct nk_input *in, const struct nk_user_font *font);
   5901 
   5902 /* property */
   5903 enum nk_property_status {
   5904     NK_PROPERTY_DEFAULT,
   5905     NK_PROPERTY_EDIT,
   5906     NK_PROPERTY_DRAG
   5907 };
   5908 enum nk_property_filter {
   5909     NK_FILTER_INT,
   5910     NK_FILTER_FLOAT
   5911 };
   5912 enum nk_property_kind {
   5913     NK_PROPERTY_INT,
   5914     NK_PROPERTY_FLOAT,
   5915     NK_PROPERTY_DOUBLE
   5916 };
   5917 union nk_property {
   5918     int i;
   5919     float f;
   5920     double d;
   5921 };
   5922 struct nk_property_variant {
   5923     enum nk_property_kind kind;
   5924     union nk_property value;
   5925     union nk_property min_value;
   5926     union nk_property max_value;
   5927     union nk_property step;
   5928 };
   5929 NK_LIB struct nk_property_variant nk_property_variant_int(int value, int min_value, int max_value, int step);
   5930 NK_LIB struct nk_property_variant nk_property_variant_float(float value, float min_value, float max_value, float step);
   5931 NK_LIB struct nk_property_variant nk_property_variant_double(double value, double min_value, double max_value, double step);
   5932 
   5933 NK_LIB void nk_drag_behavior(nk_flags *state, const struct nk_input *in, struct nk_rect drag, struct nk_property_variant *variant, float inc_per_pixel);
   5934 NK_LIB void nk_property_behavior(nk_flags *ws, const struct nk_input *in, struct nk_rect property,  struct nk_rect label, struct nk_rect edit, struct nk_rect empty, int *state, struct nk_property_variant *variant, float inc_per_pixel);
   5935 NK_LIB void nk_draw_property(struct nk_command_buffer *out, const struct nk_style_property *style, const struct nk_rect *bounds, const struct nk_rect *label, nk_flags state, const char *name, int len, const struct nk_user_font *font);
   5936 NK_LIB void nk_do_property(nk_flags *ws, struct nk_command_buffer *out, struct nk_rect property, const char *name, struct nk_property_variant *variant, float inc_per_pixel, char *buffer, int *len, int *state, int *cursor, int *select_begin, int *select_end, const struct nk_style_property *style, enum nk_property_filter filter, struct nk_input *in, const struct nk_user_font *font, struct nk_text_edit *text_edit, enum nk_button_behavior behavior);
   5937 NK_LIB void nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant *variant, float inc_per_pixel, const enum nk_property_filter filter);
   5938 
   5939 #endif
   5940 
   5941 
   5942 
   5943 
   5944 
   5945 /* ===============================================================
   5946  *
   5947  *                              MATH
   5948  *
   5949  * ===============================================================*/
   5950 /*  Since nuklear is supposed to work on all systems providing floating point
   5951     math without any dependencies I also had to implement my own math functions
   5952     for sqrt, sin and cos. Since the actual highly accurate implementations for
   5953     the standard library functions are quite complex and I do not need high
   5954     precision for my use cases I use approximations.
   5955 
   5956     Sqrt
   5957     ----
   5958     For square root nuklear uses the famous fast inverse square root:
   5959     https://en.wikipedia.org/wiki/Fast_inverse_square_root with
   5960     slightly tweaked magic constant. While on today's hardware it is
   5961     probably not faster it is still fast and accurate enough for
   5962     nuklear's use cases. IMPORTANT: this requires float format IEEE 754
   5963 
   5964     Sine/Cosine
   5965     -----------
   5966     All constants inside both function are generated Remez's minimax
   5967     approximations for value range 0...2*PI. The reason why I decided to
   5968     approximate exactly that range is that nuklear only needs sine and
   5969     cosine to generate circles which only requires that exact range.
   5970     In addition I used Remez instead of Taylor for additional precision:
   5971     www.lolengine.net/blog/2011/12/21/better-function-approximations.
   5972 
   5973     The tool I used to generate constants for both sine and cosine
   5974     (it can actually approximate a lot more functions) can be
   5975     found here: www.lolengine.net/wiki/oss/lolremez
   5976 */
   5977 NK_LIB float
   5978 nk_inv_sqrt(float n)
   5979 {
   5980     float x2;
   5981     const float threehalfs = 1.5f;
   5982     union {nk_uint i; float f;} conv = {0};
   5983     conv.f = n;
   5984     x2 = n * 0.5f;
   5985     conv.i = 0x5f375A84 - (conv.i >> 1);
   5986     conv.f = conv.f * (threehalfs - (x2 * conv.f * conv.f));
   5987     return conv.f;
   5988 }
   5989 NK_LIB float
   5990 nk_sqrt(float x)
   5991 {
   5992     return x * nk_inv_sqrt(x);
   5993 }
   5994 NK_LIB float
   5995 nk_sin(float x)
   5996 {
   5997     NK_STORAGE const float a0 = +1.91059300966915117e-31f;
   5998     NK_STORAGE const float a1 = +1.00086760103908896f;
   5999     NK_STORAGE const float a2 = -1.21276126894734565e-2f;
   6000     NK_STORAGE const float a3 = -1.38078780785773762e-1f;
   6001     NK_STORAGE const float a4 = -2.67353392911981221e-2f;
   6002     NK_STORAGE const float a5 = +2.08026600266304389e-2f;
   6003     NK_STORAGE const float a6 = -3.03996055049204407e-3f;
   6004     NK_STORAGE const float a7 = +1.38235642404333740e-4f;
   6005     return a0 + x*(a1 + x*(a2 + x*(a3 + x*(a4 + x*(a5 + x*(a6 + x*a7))))));
   6006 }
   6007 NK_LIB float
   6008 nk_cos(float x)
   6009 {
   6010     NK_STORAGE const float a0 = +1.00238601909309722f;
   6011     NK_STORAGE const float a1 = -3.81919947353040024e-2f;
   6012     NK_STORAGE const float a2 = -3.94382342128062756e-1f;
   6013     NK_STORAGE const float a3 = -1.18134036025221444e-1f;
   6014     NK_STORAGE const float a4 = +1.07123798512170878e-1f;
   6015     NK_STORAGE const float a5 = -1.86637164165180873e-2f;
   6016     NK_STORAGE const float a6 = +9.90140908664079833e-4f;
   6017     NK_STORAGE const float a7 = -5.23022132118824778e-14f;
   6018     return a0 + x*(a1 + x*(a2 + x*(a3 + x*(a4 + x*(a5 + x*(a6 + x*a7))))));
   6019 }
   6020 NK_LIB nk_uint
   6021 nk_round_up_pow2(nk_uint v)
   6022 {
   6023     v--;
   6024     v |= v >> 1;
   6025     v |= v >> 2;
   6026     v |= v >> 4;
   6027     v |= v >> 8;
   6028     v |= v >> 16;
   6029     v++;
   6030     return v;
   6031 }
   6032 NK_LIB double
   6033 nk_pow(double x, int n)
   6034 {
   6035     /*  check the sign of n */
   6036     double r = 1;
   6037     int plus = n >= 0;
   6038     n = (plus) ? n : -n;
   6039     while (n > 0) {
   6040         if ((n & 1) == 1)
   6041             r *= x;
   6042         n /= 2;
   6043         x *= x;
   6044     }
   6045     return plus ? r : 1.0 / r;
   6046 }
   6047 NK_LIB int
   6048 nk_ifloord(double x)
   6049 {
   6050     x = (double)((int)x - ((x < 0.0) ? 1 : 0));
   6051     return (int)x;
   6052 }
   6053 NK_LIB int
   6054 nk_ifloorf(float x)
   6055 {
   6056     x = (float)((int)x - ((x < 0.0f) ? 1 : 0));
   6057     return (int)x;
   6058 }
   6059 NK_LIB int
   6060 nk_iceilf(float x)
   6061 {
   6062     if (x >= 0) {
   6063         int i = (int)x;
   6064         return (x > i) ? i+1: i;
   6065     } else {
   6066         int t = (int)x;
   6067         float r = x - (float)t;
   6068         return (r > 0.0f) ? t+1: t;
   6069     }
   6070 }
   6071 NK_LIB int
   6072 nk_log10(double n)
   6073 {
   6074     int neg;
   6075     int ret;
   6076     int exp = 0;
   6077 
   6078     neg = (n < 0) ? 1 : 0;
   6079     ret = (neg) ? (int)-n : (int)n;
   6080     while ((ret / 10) > 0) {
   6081         ret /= 10;
   6082         exp++;
   6083     }
   6084     if (neg) exp = -exp;
   6085     return exp;
   6086 }
   6087 NK_API struct nk_rect
   6088 nk_get_null_rect(void)
   6089 {
   6090     return nk_null_rect;
   6091 }
   6092 NK_API struct nk_rect
   6093 nk_rect(float x, float y, float w, float h)
   6094 {
   6095     struct nk_rect r;
   6096     r.x = x; r.y = y;
   6097     r.w = w; r.h = h;
   6098     return r;
   6099 }
   6100 NK_API struct nk_rect
   6101 nk_recti(int x, int y, int w, int h)
   6102 {
   6103     struct nk_rect r;
   6104     r.x = (float)x;
   6105     r.y = (float)y;
   6106     r.w = (float)w;
   6107     r.h = (float)h;
   6108     return r;
   6109 }
   6110 NK_API struct nk_rect
   6111 nk_recta(struct nk_vec2 pos, struct nk_vec2 size)
   6112 {
   6113     return nk_rect(pos.x, pos.y, size.x, size.y);
   6114 }
   6115 NK_API struct nk_rect
   6116 nk_rectv(const float *r)
   6117 {
   6118     return nk_rect(r[0], r[1], r[2], r[3]);
   6119 }
   6120 NK_API struct nk_rect
   6121 nk_rectiv(const int *r)
   6122 {
   6123     return nk_recti(r[0], r[1], r[2], r[3]);
   6124 }
   6125 NK_API struct nk_vec2
   6126 nk_rect_pos(struct nk_rect r)
   6127 {
   6128     struct nk_vec2 ret;
   6129     ret.x = r.x; ret.y = r.y;
   6130     return ret;
   6131 }
   6132 NK_API struct nk_vec2
   6133 nk_rect_size(struct nk_rect r)
   6134 {
   6135     struct nk_vec2 ret;
   6136     ret.x = r.w; ret.y = r.h;
   6137     return ret;
   6138 }
   6139 NK_LIB struct nk_rect
   6140 nk_shrink_rect(struct nk_rect r, float amount)
   6141 {
   6142     struct nk_rect res;
   6143     r.w = NK_MAX(r.w, 2 * amount);
   6144     r.h = NK_MAX(r.h, 2 * amount);
   6145     res.x = r.x + amount;
   6146     res.y = r.y + amount;
   6147     res.w = r.w - 2 * amount;
   6148     res.h = r.h - 2 * amount;
   6149     return res;
   6150 }
   6151 NK_LIB struct nk_rect
   6152 nk_pad_rect(struct nk_rect r, struct nk_vec2 pad)
   6153 {
   6154     r.w = NK_MAX(r.w, 2 * pad.x);
   6155     r.h = NK_MAX(r.h, 2 * pad.y);
   6156     r.x += pad.x; r.y += pad.y;
   6157     r.w -= 2 * pad.x;
   6158     r.h -= 2 * pad.y;
   6159     return r;
   6160 }
   6161 NK_API struct nk_vec2
   6162 nk_vec2(float x, float y)
   6163 {
   6164     struct nk_vec2 ret;
   6165     ret.x = x; ret.y = y;
   6166     return ret;
   6167 }
   6168 NK_API struct nk_vec2
   6169 nk_vec2i(int x, int y)
   6170 {
   6171     struct nk_vec2 ret;
   6172     ret.x = (float)x;
   6173     ret.y = (float)y;
   6174     return ret;
   6175 }
   6176 NK_API struct nk_vec2
   6177 nk_vec2v(const float *v)
   6178 {
   6179     return nk_vec2(v[0], v[1]);
   6180 }
   6181 NK_API struct nk_vec2
   6182 nk_vec2iv(const int *v)
   6183 {
   6184     return nk_vec2i(v[0], v[1]);
   6185 }
   6186 NK_LIB void
   6187 nk_unify(struct nk_rect *clip, const struct nk_rect *a, float x0, float y0,
   6188     float x1, float y1)
   6189 {
   6190     NK_ASSERT(a);
   6191     NK_ASSERT(clip);
   6192     clip->x = NK_MAX(a->x, x0);
   6193     clip->y = NK_MAX(a->y, y0);
   6194     clip->w = NK_MIN(a->x + a->w, x1) - clip->x;
   6195     clip->h = NK_MIN(a->y + a->h, y1) - clip->y;
   6196     clip->w = NK_MAX(0, clip->w);
   6197     clip->h = NK_MAX(0, clip->h);
   6198 }
   6199 
   6200 NK_API void
   6201 nk_triangle_from_direction(struct nk_vec2 *result, struct nk_rect r,
   6202     float pad_x, float pad_y, enum nk_heading direction)
   6203 {
   6204     float w_half, h_half;
   6205     NK_ASSERT(result);
   6206 
   6207     r.w = NK_MAX(2 * pad_x, r.w);
   6208     r.h = NK_MAX(2 * pad_y, r.h);
   6209     r.w = r.w - 2 * pad_x;
   6210     r.h = r.h - 2 * pad_y;
   6211 
   6212     r.x = r.x + pad_x;
   6213     r.y = r.y + pad_y;
   6214 
   6215     w_half = r.w / 2.0f;
   6216     h_half = r.h / 2.0f;
   6217 
   6218     if (direction == NK_UP) {
   6219         result[0] = nk_vec2(r.x + w_half, r.y);
   6220         result[1] = nk_vec2(r.x + r.w, r.y + r.h);
   6221         result[2] = nk_vec2(r.x, r.y + r.h);
   6222     } else if (direction == NK_RIGHT) {
   6223         result[0] = nk_vec2(r.x, r.y);
   6224         result[1] = nk_vec2(r.x + r.w, r.y + h_half);
   6225         result[2] = nk_vec2(r.x, r.y + r.h);
   6226     } else if (direction == NK_DOWN) {
   6227         result[0] = nk_vec2(r.x, r.y);
   6228         result[1] = nk_vec2(r.x + r.w, r.y);
   6229         result[2] = nk_vec2(r.x + w_half, r.y + r.h);
   6230     } else {
   6231         result[0] = nk_vec2(r.x, r.y + h_half);
   6232         result[1] = nk_vec2(r.x + r.w, r.y);
   6233         result[2] = nk_vec2(r.x + r.w, r.y + r.h);
   6234     }
   6235 }
   6236 
   6237 
   6238 
   6239 
   6240 
   6241 /* ===============================================================
   6242  *
   6243  *                              UTIL
   6244  *
   6245  * ===============================================================*/
   6246 NK_INTERN int nk_str_match_here(const char *regexp, const char *text);
   6247 NK_INTERN int nk_str_match_star(int c, const char *regexp, const char *text);
   6248 NK_LIB int nk_is_lower(int c) {return (c >= 'a' && c <= 'z') || (c >= 0xE0 && c <= 0xFF);}
   6249 NK_LIB int nk_is_upper(int c){return (c >= 'A' && c <= 'Z') || (c >= 0xC0 && c <= 0xDF);}
   6250 NK_LIB int nk_to_upper(int c) {return (c >= 'a' && c <= 'z') ? (c - ('a' - 'A')) : c;}
   6251 NK_LIB int nk_to_lower(int c) {return (c >= 'A' && c <= 'Z') ? (c - ('a' + 'A')) : c;}
   6252 
   6253 NK_LIB void*
   6254 nk_memcopy(void *dst0, const void *src0, nk_size length)
   6255 {
   6256     nk_ptr t;
   6257     char *dst = (char*)dst0;
   6258     const char *src = (const char*)src0;
   6259     if (length == 0 || dst == src)
   6260         goto done;
   6261 
   6262     #define nk_word int
   6263     #define nk_wsize sizeof(nk_word)
   6264     #define nk_wmask (nk_wsize-1)
   6265     #define NK_TLOOP(s) if (t) NK_TLOOP1(s)
   6266     #define NK_TLOOP1(s) do { s; } while (--t)
   6267 
   6268     if (dst < src) {
   6269         t = (nk_ptr)src; /* only need low bits */
   6270         if ((t | (nk_ptr)dst) & nk_wmask) {
   6271             if ((t ^ (nk_ptr)dst) & nk_wmask || length < nk_wsize)
   6272                 t = length;
   6273             else
   6274                 t = nk_wsize - (t & nk_wmask);
   6275             length -= t;
   6276             NK_TLOOP1(*dst++ = *src++);
   6277         }
   6278         t = length / nk_wsize;
   6279         NK_TLOOP(*(nk_word*)(void*)dst = *(const nk_word*)(const void*)src;
   6280             src += nk_wsize; dst += nk_wsize);
   6281         t = length & nk_wmask;
   6282         NK_TLOOP(*dst++ = *src++);
   6283     } else {
   6284         src += length;
   6285         dst += length;
   6286         t = (nk_ptr)src;
   6287         if ((t | (nk_ptr)dst) & nk_wmask) {
   6288             if ((t ^ (nk_ptr)dst) & nk_wmask || length <= nk_wsize)
   6289                 t = length;
   6290             else
   6291                 t &= nk_wmask;
   6292             length -= t;
   6293             NK_TLOOP1(*--dst = *--src);
   6294         }
   6295         t = length / nk_wsize;
   6296         NK_TLOOP(src -= nk_wsize; dst -= nk_wsize;
   6297             *(nk_word*)(void*)dst = *(const nk_word*)(const void*)src);
   6298         t = length & nk_wmask;
   6299         NK_TLOOP(*--dst = *--src);
   6300     }
   6301     #undef nk_word
   6302     #undef nk_wsize
   6303     #undef nk_wmask
   6304     #undef NK_TLOOP
   6305     #undef NK_TLOOP1
   6306 done:
   6307     return (dst0);
   6308 }
   6309 NK_LIB void
   6310 nk_memset(void *ptr, int c0, nk_size size)
   6311 {
   6312     #define nk_word unsigned
   6313     #define nk_wsize sizeof(nk_word)
   6314     #define nk_wmask (nk_wsize - 1)
   6315     nk_byte *dst = (nk_byte*)ptr;
   6316     unsigned c = 0;
   6317     nk_size t = 0;
   6318 
   6319     if ((c = (nk_byte)c0) != 0) {
   6320         c = (c << 8) | c; /* at least 16-bits  */
   6321         if (sizeof(unsigned int) > 2)
   6322             c = (c << 16) | c; /* at least 32-bits*/
   6323     }
   6324 
   6325     /* too small of a word count */
   6326     dst = (nk_byte*)ptr;
   6327     if (size < 3 * nk_wsize) {
   6328         while (size--) *dst++ = (nk_byte)c0;
   6329         return;
   6330     }
   6331 
   6332     /* align destination */
   6333     if ((t = NK_PTR_TO_UINT(dst) & nk_wmask) != 0) {
   6334         t = nk_wsize -t;
   6335         size -= t;
   6336         do {
   6337             *dst++ = (nk_byte)c0;
   6338         } while (--t != 0);
   6339     }
   6340 
   6341     /* fill word */
   6342     t = size / nk_wsize;
   6343     do {
   6344         *(nk_word*)((void*)dst) = c;
   6345         dst += nk_wsize;
   6346     } while (--t != 0);
   6347 
   6348     /* fill trailing bytes */
   6349     t = (size & nk_wmask);
   6350     if (t != 0) {
   6351         do {
   6352             *dst++ = (nk_byte)c0;
   6353         } while (--t != 0);
   6354     }
   6355 
   6356     #undef nk_word
   6357     #undef nk_wsize
   6358     #undef nk_wmask
   6359 }
   6360 NK_LIB void
   6361 nk_zero(void *ptr, nk_size size)
   6362 {
   6363     NK_ASSERT(ptr);
   6364     NK_MEMSET(ptr, 0, size);
   6365 }
   6366 NK_API int
   6367 nk_strlen(const char *str)
   6368 {
   6369     int siz = 0;
   6370     NK_ASSERT(str);
   6371     while (str && *str++ != '\0') siz++;
   6372     return siz;
   6373 }
   6374 NK_API int
   6375 nk_strtoi(const char *str, const char **endptr)
   6376 {
   6377     int neg = 1;
   6378     const char *p = str;
   6379     int value = 0;
   6380 
   6381     NK_ASSERT(str);
   6382     if (!str) return 0;
   6383 
   6384     /* skip whitespace */
   6385     while (*p == ' ') p++;
   6386     if (*p == '-') {
   6387         neg = -1;
   6388         p++;
   6389     }
   6390     while (*p && *p >= '0' && *p <= '9') {
   6391         value = value * 10 + (int) (*p - '0');
   6392         p++;
   6393     }
   6394     if (endptr)
   6395         *endptr = p;
   6396     return neg*value;
   6397 }
   6398 NK_API double
   6399 nk_strtod(const char *str, const char **endptr)
   6400 {
   6401     double m;
   6402     double neg = 1.0;
   6403     const char *p = str;
   6404     double value = 0;
   6405     double number = 0;
   6406 
   6407     NK_ASSERT(str);
   6408     if (!str) return 0;
   6409 
   6410     /* skip whitespace */
   6411     while (*p == ' ') p++;
   6412     if (*p == '-') {
   6413         neg = -1.0;
   6414         p++;
   6415     }
   6416 
   6417     while (*p && *p != '.' && *p != 'e') {
   6418         value = value * 10.0 + (double) (*p - '0');
   6419         p++;
   6420     }
   6421 
   6422     if (*p == '.') {
   6423         p++;
   6424         for(m = 0.1; *p && *p != 'e'; p++ ) {
   6425             value = value + (double) (*p - '0') * m;
   6426             m *= 0.1;
   6427         }
   6428     }
   6429     if (*p == 'e') {
   6430         int i, pow, div;
   6431         p++;
   6432         if (*p == '-') {
   6433             div = nk_true;
   6434             p++;
   6435         } else if (*p == '+') {
   6436             div = nk_false;
   6437             p++;
   6438         } else div = nk_false;
   6439 
   6440         for (pow = 0; *p; p++)
   6441             pow = pow * 10 + (int) (*p - '0');
   6442 
   6443         for (m = 1.0, i = 0; i < pow; i++)
   6444             m *= 10.0;
   6445 
   6446         if (div)
   6447             value /= m;
   6448         else value *= m;
   6449     }
   6450     number = value * neg;
   6451     if (endptr)
   6452         *endptr = p;
   6453     return number;
   6454 }
   6455 NK_API float
   6456 nk_strtof(const char *str, const char **endptr)
   6457 {
   6458     float float_value;
   6459     double double_value;
   6460     double_value = NK_STRTOD(str, endptr);
   6461     float_value = (float)double_value;
   6462     return float_value;
   6463 }
   6464 NK_API int
   6465 nk_stricmp(const char *s1, const char *s2)
   6466 {
   6467     nk_int c1,c2,d;
   6468     do {
   6469         c1 = *s1++;
   6470         c2 = *s2++;
   6471         d = c1 - c2;
   6472         while (d) {
   6473             if (c1 <= 'Z' && c1 >= 'A') {
   6474                 d += ('a' - 'A');
   6475                 if (!d) break;
   6476             }
   6477             if (c2 <= 'Z' && c2 >= 'A') {
   6478                 d -= ('a' - 'A');
   6479                 if (!d) break;
   6480             }
   6481             return ((d >= 0) << 1) - 1;
   6482         }
   6483     } while (c1);
   6484     return 0;
   6485 }
   6486 NK_API int
   6487 nk_stricmpn(const char *s1, const char *s2, int n)
   6488 {
   6489     int c1,c2,d;
   6490     NK_ASSERT(n >= 0);
   6491     do {
   6492         c1 = *s1++;
   6493         c2 = *s2++;
   6494         if (!n--) return 0;
   6495 
   6496         d = c1 - c2;
   6497         while (d) {
   6498             if (c1 <= 'Z' && c1 >= 'A') {
   6499                 d += ('a' - 'A');
   6500                 if (!d) break;
   6501             }
   6502             if (c2 <= 'Z' && c2 >= 'A') {
   6503                 d -= ('a' - 'A');
   6504                 if (!d) break;
   6505             }
   6506             return ((d >= 0) << 1) - 1;
   6507         }
   6508     } while (c1);
   6509     return 0;
   6510 }
   6511 NK_INTERN int
   6512 nk_str_match_here(const char *regexp, const char *text)
   6513 {
   6514     if (regexp[0] == '\0')
   6515         return 1;
   6516     if (regexp[1] == '*')
   6517         return nk_str_match_star(regexp[0], regexp+2, text);
   6518     if (regexp[0] == '$' && regexp[1] == '\0')
   6519         return *text == '\0';
   6520     if (*text!='\0' && (regexp[0]=='.' || regexp[0]==*text))
   6521         return nk_str_match_here(regexp+1, text+1);
   6522     return 0;
   6523 }
   6524 NK_INTERN int
   6525 nk_str_match_star(int c, const char *regexp, const char *text)
   6526 {
   6527     do {/* a '* matches zero or more instances */
   6528         if (nk_str_match_here(regexp, text))
   6529             return 1;
   6530     } while (*text != '\0' && (*text++ == c || c == '.'));
   6531     return 0;
   6532 }
   6533 NK_API int
   6534 nk_strfilter(const char *text, const char *regexp)
   6535 {
   6536     /*
   6537     c    matches any literal character c
   6538     .    matches any single character
   6539     ^    matches the beginning of the input string
   6540     $    matches the end of the input string
   6541     *    matches zero or more occurrences of the previous character*/
   6542     if (regexp[0] == '^')
   6543         return nk_str_match_here(regexp+1, text);
   6544     do {    /* must look even if string is empty */
   6545         if (nk_str_match_here(regexp, text))
   6546             return 1;
   6547     } while (*text++ != '\0');
   6548     return 0;
   6549 }
   6550 NK_API int
   6551 nk_strmatch_fuzzy_text(const char *str, int str_len,
   6552     const char *pattern, int *out_score)
   6553 {
   6554     /* Returns true if each character in pattern is found sequentially within str
   6555      * if found then out_score is also set. Score value has no intrinsic meaning.
   6556      * Range varies with pattern. Can only compare scores with same search pattern. */
   6557 
   6558     /* bonus for adjacent matches */
   6559     #define NK_ADJACENCY_BONUS 5
   6560     /* bonus if match occurs after a separator */
   6561     #define NK_SEPARATOR_BONUS 10
   6562     /* bonus if match is uppercase and prev is lower */
   6563     #define NK_CAMEL_BONUS 10
   6564     /* penalty applied for every letter in str before the first match */
   6565     #define NK_LEADING_LETTER_PENALTY (-3)
   6566     /* maximum penalty for leading letters */
   6567     #define NK_MAX_LEADING_LETTER_PENALTY (-9)
   6568     /* penalty for every letter that doesn't matter */
   6569     #define NK_UNMATCHED_LETTER_PENALTY (-1)
   6570 
   6571     /* loop variables */
   6572     int score = 0;
   6573     char const * pattern_iter = pattern;
   6574     int str_iter = 0;
   6575     int prev_matched = nk_false;
   6576     int prev_lower = nk_false;
   6577     /* true so if first letter match gets separator bonus*/
   6578     int prev_separator = nk_true;
   6579 
   6580     /* use "best" matched letter if multiple string letters match the pattern */
   6581     char const * best_letter = 0;
   6582     int best_letter_score = 0;
   6583 
   6584     /* loop over strings */
   6585     NK_ASSERT(str);
   6586     NK_ASSERT(pattern);
   6587     if (!str || !str_len || !pattern) return 0;
   6588     while (str_iter < str_len)
   6589     {
   6590         const char pattern_letter = *pattern_iter;
   6591         const char str_letter = str[str_iter];
   6592 
   6593         int next_match = *pattern_iter != '\0' &&
   6594             nk_to_lower(pattern_letter) == nk_to_lower(str_letter);
   6595         int rematch = best_letter && nk_to_upper(*best_letter) == nk_to_upper(str_letter);
   6596 
   6597         int advanced = next_match && best_letter;
   6598         int pattern_repeat = best_letter && *pattern_iter != '\0';
   6599         pattern_repeat = pattern_repeat &&
   6600             nk_to_lower(*best_letter) == nk_to_lower(pattern_letter);
   6601 
   6602         if (advanced || pattern_repeat) {
   6603             score += best_letter_score;
   6604             best_letter = 0;
   6605             best_letter_score = 0;
   6606         }
   6607 
   6608         if (next_match || rematch)
   6609         {
   6610             int new_score = 0;
   6611             /* Apply penalty for each letter before the first pattern match */
   6612             if (pattern_iter == pattern) {
   6613                 int count = (int)(&str[str_iter] - str);
   6614                 int penalty = NK_LEADING_LETTER_PENALTY * count;
   6615                 if (penalty < NK_MAX_LEADING_LETTER_PENALTY)
   6616                     penalty = NK_MAX_LEADING_LETTER_PENALTY;
   6617 
   6618                 score += penalty;
   6619             }
   6620 
   6621             /* apply bonus for consecutive bonuses */
   6622             if (prev_matched)
   6623                 new_score += NK_ADJACENCY_BONUS;
   6624 
   6625             /* apply bonus for matches after a separator */
   6626             if (prev_separator)
   6627                 new_score += NK_SEPARATOR_BONUS;
   6628 
   6629             /* apply bonus across camel case boundaries */
   6630             if (prev_lower && nk_is_upper(str_letter))
   6631                 new_score += NK_CAMEL_BONUS;
   6632 
   6633             /* update pattern iter IFF the next pattern letter was matched */
   6634             if (next_match)
   6635                 ++pattern_iter;
   6636 
   6637             /* update best letter in str which may be for a "next" letter or a rematch */
   6638             if (new_score >= best_letter_score) {
   6639                 /* apply penalty for now skipped letter */
   6640                 if (best_letter != 0)
   6641                     score += NK_UNMATCHED_LETTER_PENALTY;
   6642 
   6643                 best_letter = &str[str_iter];
   6644                 best_letter_score = new_score;
   6645             }
   6646             prev_matched = nk_true;
   6647         } else {
   6648             score += NK_UNMATCHED_LETTER_PENALTY;
   6649             prev_matched = nk_false;
   6650         }
   6651 
   6652         /* separators should be more easily defined */
   6653         prev_lower = nk_is_lower(str_letter) != 0;
   6654         prev_separator = str_letter == '_' || str_letter == ' ';
   6655 
   6656         ++str_iter;
   6657     }
   6658 
   6659     /* apply score for last match */
   6660     if (best_letter)
   6661         score += best_letter_score;
   6662 
   6663     /* did not match full pattern */
   6664     if (*pattern_iter != '\0')
   6665         return nk_false;
   6666 
   6667     if (out_score)
   6668         *out_score = score;
   6669     return nk_true;
   6670 }
   6671 NK_API int
   6672 nk_strmatch_fuzzy_string(char const *str, char const *pattern, int *out_score)
   6673 {
   6674     return nk_strmatch_fuzzy_text(str, nk_strlen(str), pattern, out_score);
   6675 }
   6676 NK_LIB int
   6677 nk_string_float_limit(char *string, int prec)
   6678 {
   6679     int dot = 0;
   6680     char *c = string;
   6681     while (*c) {
   6682         if (*c == '.') {
   6683             dot = 1;
   6684             c++;
   6685             continue;
   6686         }
   6687         if (dot == (prec+1)) {
   6688             *c = 0;
   6689             break;
   6690         }
   6691         if (dot > 0) dot++;
   6692         c++;
   6693     }
   6694     return (int)(c - string);
   6695 }
   6696 NK_INTERN void
   6697 nk_strrev_ascii(char *s)
   6698 {
   6699     int len = nk_strlen(s);
   6700     int end = len / 2;
   6701     int i = 0;
   6702     char t;
   6703     for (; i < end; ++i) {
   6704         t = s[i];
   6705         s[i] = s[len - 1 - i];
   6706         s[len -1 - i] = t;
   6707     }
   6708 }
   6709 NK_LIB char*
   6710 nk_itoa(char *s, long n)
   6711 {
   6712     long i = 0;
   6713     if (n == 0) {
   6714         s[i++] = '0';
   6715         s[i] = 0;
   6716         return s;
   6717     }
   6718     if (n < 0) {
   6719         s[i++] = '-';
   6720         n = -n;
   6721     }
   6722     while (n > 0) {
   6723         s[i++] = (char)('0' + (n % 10));
   6724         n /= 10;
   6725     }
   6726     s[i] = 0;
   6727     if (s[0] == '-')
   6728         ++s;
   6729 
   6730     nk_strrev_ascii(s);
   6731     return s;
   6732 }
   6733 NK_LIB char*
   6734 nk_dtoa(char *s, double n)
   6735 {
   6736     int useExp = 0;
   6737     int digit = 0, m = 0, m1 = 0;
   6738     char *c = s;
   6739     int neg = 0;
   6740 
   6741     NK_ASSERT(s);
   6742     if (!s) return 0;
   6743 
   6744     if (n == 0.0) {
   6745         s[0] = '0'; s[1] = '\0';
   6746         return s;
   6747     }
   6748 
   6749     neg = (n < 0);
   6750     if (neg) n = -n;
   6751 
   6752     /* calculate magnitude */
   6753     m = nk_log10(n);
   6754     useExp = (m >= 14 || (neg && m >= 9) || m <= -9);
   6755     if (neg) *(c++) = '-';
   6756 
   6757     /* set up for scientific notation */
   6758     if (useExp) {
   6759         if (m < 0)
   6760            m -= 1;
   6761         n = n / (double)nk_pow(10.0, m);
   6762         m1 = m;
   6763         m = 0;
   6764     }
   6765     if (m < 1.0) {
   6766         m = 0;
   6767     }
   6768 
   6769     /* convert the number */
   6770     while (n > NK_FLOAT_PRECISION || m >= 0) {
   6771         double weight = nk_pow(10.0, m);
   6772         if (weight > 0) {
   6773             double t = (double)n / weight;
   6774             digit = nk_ifloord(t);
   6775             n -= ((double)digit * weight);
   6776             *(c++) = (char)('0' + (char)digit);
   6777         }
   6778         if (m == 0 && n > 0)
   6779             *(c++) = '.';
   6780         m--;
   6781     }
   6782 
   6783     if (useExp) {
   6784         /* convert the exponent */
   6785         int i, j;
   6786         *(c++) = 'e';
   6787         if (m1 > 0) {
   6788             *(c++) = '+';
   6789         } else {
   6790             *(c++) = '-';
   6791             m1 = -m1;
   6792         }
   6793         m = 0;
   6794         while (m1 > 0) {
   6795             *(c++) = (char)('0' + (char)(m1 % 10));
   6796             m1 /= 10;
   6797             m++;
   6798         }
   6799         c -= m;
   6800         for (i = 0, j = m-1; i<j; i++, j--) {
   6801             /* swap without temporary */
   6802             c[i] ^= c[j];
   6803             c[j] ^= c[i];
   6804             c[i] ^= c[j];
   6805         }
   6806         c += m;
   6807     }
   6808     *(c) = '\0';
   6809     return s;
   6810 }
   6811 #ifdef NK_INCLUDE_STANDARD_VARARGS
   6812 #ifndef NK_INCLUDE_STANDARD_IO
   6813 NK_INTERN int
   6814 nk_vsnprintf(char *buf, int buf_size, const char *fmt, va_list args)
   6815 {
   6816     enum nk_arg_type {
   6817         NK_ARG_TYPE_CHAR,
   6818         NK_ARG_TYPE_SHORT,
   6819         NK_ARG_TYPE_DEFAULT,
   6820         NK_ARG_TYPE_LONG
   6821     };
   6822     enum nk_arg_flags {
   6823         NK_ARG_FLAG_LEFT = 0x01,
   6824         NK_ARG_FLAG_PLUS = 0x02,
   6825         NK_ARG_FLAG_SPACE = 0x04,
   6826         NK_ARG_FLAG_NUM = 0x10,
   6827         NK_ARG_FLAG_ZERO = 0x20
   6828     };
   6829 
   6830     char number_buffer[NK_MAX_NUMBER_BUFFER];
   6831     enum nk_arg_type arg_type = NK_ARG_TYPE_DEFAULT;
   6832     int precision = NK_DEFAULT;
   6833     int width = NK_DEFAULT;
   6834     nk_flags flag = 0;
   6835 
   6836     int len = 0;
   6837     int result = -1;
   6838     const char *iter = fmt;
   6839 
   6840     NK_ASSERT(buf);
   6841     NK_ASSERT(buf_size);
   6842     if (!buf || !buf_size || !fmt) return 0;
   6843     for (iter = fmt; *iter && len < buf_size; iter++) {
   6844         /* copy all non-format characters */
   6845         while (*iter && (*iter != '%') && (len < buf_size))
   6846             buf[len++] = *iter++;
   6847         if (!(*iter) || len >= buf_size) break;
   6848         iter++;
   6849 
   6850         /* flag arguments */
   6851         while (*iter) {
   6852             if (*iter == '-') flag |= NK_ARG_FLAG_LEFT;
   6853             else if (*iter == '+') flag |= NK_ARG_FLAG_PLUS;
   6854             else if (*iter == ' ') flag |= NK_ARG_FLAG_SPACE;
   6855             else if (*iter == '#') flag |= NK_ARG_FLAG_NUM;
   6856             else if (*iter == '0') flag |= NK_ARG_FLAG_ZERO;
   6857             else break;
   6858             iter++;
   6859         }
   6860 
   6861         /* width argument */
   6862         width = NK_DEFAULT;
   6863         if (*iter >= '1' && *iter <= '9') {
   6864             const char *end;
   6865             width = nk_strtoi(iter, &end);
   6866             if (end == iter)
   6867                 width = -1;
   6868             else iter = end;
   6869         } else if (*iter == '*') {
   6870             width = va_arg(args, int);
   6871             iter++;
   6872         }
   6873 
   6874         /* precision argument */
   6875         precision = NK_DEFAULT;
   6876         if (*iter == '.') {
   6877             iter++;
   6878             if (*iter == '*') {
   6879                 precision = va_arg(args, int);
   6880                 iter++;
   6881             } else {
   6882                 const char *end;
   6883                 precision = nk_strtoi(iter, &end);
   6884                 if (end == iter)
   6885                     precision = -1;
   6886                 else iter = end;
   6887             }
   6888         }
   6889 
   6890         /* length modifier */
   6891         if (*iter == 'h') {
   6892             if (*(iter+1) == 'h') {
   6893                 arg_type = NK_ARG_TYPE_CHAR;
   6894                 iter++;
   6895             } else arg_type = NK_ARG_TYPE_SHORT;
   6896             iter++;
   6897         } else if (*iter == 'l') {
   6898             arg_type = NK_ARG_TYPE_LONG;
   6899             iter++;
   6900         } else arg_type = NK_ARG_TYPE_DEFAULT;
   6901 
   6902         /* specifier */
   6903         if (*iter == '%') {
   6904             NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
   6905             NK_ASSERT(precision == NK_DEFAULT);
   6906             NK_ASSERT(width == NK_DEFAULT);
   6907             if (len < buf_size)
   6908                 buf[len++] = '%';
   6909         } else if (*iter == 's') {
   6910             /* string  */
   6911             const char *str = va_arg(args, const char*);
   6912             NK_ASSERT(str != buf && "buffer and argument are not allowed to overlap!");
   6913             NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
   6914             NK_ASSERT(precision == NK_DEFAULT);
   6915             NK_ASSERT(width == NK_DEFAULT);
   6916             if (str == buf) return -1;
   6917             while (str && *str && len < buf_size)
   6918                 buf[len++] = *str++;
   6919         } else if (*iter == 'n') {
   6920             /* current length callback */
   6921             signed int *n = va_arg(args, int*);
   6922             NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
   6923             NK_ASSERT(precision == NK_DEFAULT);
   6924             NK_ASSERT(width == NK_DEFAULT);
   6925             if (n) *n = len;
   6926         } else if (*iter == 'c' || *iter == 'i' || *iter == 'd') {
   6927             /* signed integer */
   6928             long value = 0;
   6929             const char *num_iter;
   6930             int num_len, num_print, padding;
   6931             int cur_precision = NK_MAX(precision, 1);
   6932             int cur_width = NK_MAX(width, 0);
   6933 
   6934             /* retrieve correct value type */
   6935             if (arg_type == NK_ARG_TYPE_CHAR)
   6936                 value = (signed char)va_arg(args, int);
   6937             else if (arg_type == NK_ARG_TYPE_SHORT)
   6938                 value = (signed short)va_arg(args, int);
   6939             else if (arg_type == NK_ARG_TYPE_LONG)
   6940                 value = va_arg(args, signed long);
   6941             else if (*iter == 'c')
   6942                 value = (unsigned char)va_arg(args, int);
   6943             else value = va_arg(args, signed int);
   6944 
   6945             /* convert number to string */
   6946             nk_itoa(number_buffer, value);
   6947             num_len = nk_strlen(number_buffer);
   6948             padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0);
   6949             if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE))
   6950                 padding = NK_MAX(padding-1, 0);
   6951 
   6952             /* fill left padding up to a total of `width` characters */
   6953             if (!(flag & NK_ARG_FLAG_LEFT)) {
   6954                 while (padding-- > 0 && (len < buf_size)) {
   6955                     if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT))
   6956                         buf[len++] = '0';
   6957                     else buf[len++] = ' ';
   6958                 }
   6959             }
   6960 
   6961             /* copy string value representation into buffer */
   6962             if ((flag & NK_ARG_FLAG_PLUS) && value >= 0 && len < buf_size)
   6963                 buf[len++] = '+';
   6964             else if ((flag & NK_ARG_FLAG_SPACE) && value >= 0 && len < buf_size)
   6965                 buf[len++] = ' ';
   6966 
   6967             /* fill up to precision number of digits with '0' */
   6968             num_print = NK_MAX(cur_precision, num_len);
   6969             while (precision && (num_print > num_len) && (len < buf_size)) {
   6970                 buf[len++] = '0';
   6971                 num_print--;
   6972             }
   6973 
   6974             /* copy string value representation into buffer */
   6975             num_iter = number_buffer;
   6976             while (precision && *num_iter && len < buf_size)
   6977                 buf[len++] = *num_iter++;
   6978 
   6979             /* fill right padding up to width characters */
   6980             if (flag & NK_ARG_FLAG_LEFT) {
   6981                 while ((padding-- > 0) && (len < buf_size))
   6982                     buf[len++] = ' ';
   6983             }
   6984         } else if (*iter == 'o' || *iter == 'x' || *iter == 'X' || *iter == 'u') {
   6985             /* unsigned integer */
   6986             unsigned long value = 0;
   6987             int num_len = 0, num_print, padding = 0;
   6988             int cur_precision = NK_MAX(precision, 1);
   6989             int cur_width = NK_MAX(width, 0);
   6990             unsigned int base = (*iter == 'o') ? 8: (*iter == 'u')? 10: 16;
   6991 
   6992             /* print oct/hex/dec value */
   6993             const char *upper_output_format = "0123456789ABCDEF";
   6994             const char *lower_output_format = "0123456789abcdef";
   6995             const char *output_format = (*iter == 'x') ?
   6996                 lower_output_format: upper_output_format;
   6997 
   6998             /* retrieve correct value type */
   6999             if (arg_type == NK_ARG_TYPE_CHAR)
   7000                 value = (unsigned char)va_arg(args, int);
   7001             else if (arg_type == NK_ARG_TYPE_SHORT)
   7002                 value = (unsigned short)va_arg(args, int);
   7003             else if (arg_type == NK_ARG_TYPE_LONG)
   7004                 value = va_arg(args, unsigned long);
   7005             else value = va_arg(args, unsigned int);
   7006 
   7007             do {
   7008                 /* convert decimal number into hex/oct number */
   7009                 int digit = output_format[value % base];
   7010                 if (num_len < NK_MAX_NUMBER_BUFFER)
   7011                     number_buffer[num_len++] = (char)digit;
   7012                 value /= base;
   7013             } while (value > 0);
   7014 
   7015             num_print = NK_MAX(cur_precision, num_len);
   7016             padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0);
   7017             if (flag & NK_ARG_FLAG_NUM)
   7018                 padding = NK_MAX(padding-1, 0);
   7019 
   7020             /* fill left padding up to a total of `width` characters */
   7021             if (!(flag & NK_ARG_FLAG_LEFT)) {
   7022                 while ((padding-- > 0) && (len < buf_size)) {
   7023                     if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT))
   7024                         buf[len++] = '0';
   7025                     else buf[len++] = ' ';
   7026                 }
   7027             }
   7028 
   7029             /* fill up to precision number of digits */
   7030             if (num_print && (flag & NK_ARG_FLAG_NUM)) {
   7031                 if ((*iter == 'o') && (len < buf_size)) {
   7032                     buf[len++] = '0';
   7033                 } else if ((*iter == 'x') && ((len+1) < buf_size)) {
   7034                     buf[len++] = '0';
   7035                     buf[len++] = 'x';
   7036                 } else if ((*iter == 'X') && ((len+1) < buf_size)) {
   7037                     buf[len++] = '0';
   7038                     buf[len++] = 'X';
   7039                 }
   7040             }
   7041             while (precision && (num_print > num_len) && (len < buf_size)) {
   7042                 buf[len++] = '0';
   7043                 num_print--;
   7044             }
   7045 
   7046             /* reverse number direction */
   7047             while (num_len > 0) {
   7048                 if (precision && (len < buf_size))
   7049                     buf[len++] = number_buffer[num_len-1];
   7050                 num_len--;
   7051             }
   7052 
   7053             /* fill right padding up to width characters */
   7054             if (flag & NK_ARG_FLAG_LEFT) {
   7055                 while ((padding-- > 0) && (len < buf_size))
   7056                     buf[len++] = ' ';
   7057             }
   7058         } else if (*iter == 'f') {
   7059             /* floating point */
   7060             const char *num_iter;
   7061             int cur_precision = (precision < 0) ? 6: precision;
   7062             int prefix, cur_width = NK_MAX(width, 0);
   7063             double value = va_arg(args, double);
   7064             int num_len = 0, frac_len = 0, dot = 0;
   7065             int padding = 0;
   7066 
   7067             NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
   7068             NK_DTOA(number_buffer, value);
   7069             num_len = nk_strlen(number_buffer);
   7070 
   7071             /* calculate padding */
   7072             num_iter = number_buffer;
   7073             while (*num_iter && *num_iter != '.')
   7074                 num_iter++;
   7075 
   7076             prefix = (*num_iter == '.')?(int)(num_iter - number_buffer)+1:0;
   7077             padding = NK_MAX(cur_width - (prefix + NK_MIN(cur_precision, num_len - prefix)) , 0);
   7078             if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE))
   7079                 padding = NK_MAX(padding-1, 0);
   7080 
   7081             /* fill left padding up to a total of `width` characters */
   7082             if (!(flag & NK_ARG_FLAG_LEFT)) {
   7083                 while (padding-- > 0 && (len < buf_size)) {
   7084                     if (flag & NK_ARG_FLAG_ZERO)
   7085                         buf[len++] = '0';
   7086                     else buf[len++] = ' ';
   7087                 }
   7088             }
   7089 
   7090             /* copy string value representation into buffer */
   7091             num_iter = number_buffer;
   7092             if ((flag & NK_ARG_FLAG_PLUS) && (value >= 0) && (len < buf_size))
   7093                 buf[len++] = '+';
   7094             else if ((flag & NK_ARG_FLAG_SPACE) && (value >= 0) && (len < buf_size))
   7095                 buf[len++] = ' ';
   7096             while (*num_iter) {
   7097                 if (dot) frac_len++;
   7098                 if (len < buf_size)
   7099                     buf[len++] = *num_iter;
   7100                 if (*num_iter == '.') dot = 1;
   7101                 if (frac_len >= cur_precision) break;
   7102                 num_iter++;
   7103             }
   7104 
   7105             /* fill number up to precision */
   7106             while (frac_len < cur_precision) {
   7107                 if (!dot && len < buf_size) {
   7108                     buf[len++] = '.';
   7109                     dot = 1;
   7110                 }
   7111                 if (len < buf_size)
   7112                     buf[len++] = '0';
   7113                 frac_len++;
   7114             }
   7115 
   7116             /* fill right padding up to width characters */
   7117             if (flag & NK_ARG_FLAG_LEFT) {
   7118                 while ((padding-- > 0) && (len < buf_size))
   7119                     buf[len++] = ' ';
   7120             }
   7121         } else {
   7122             /* Specifier not supported: g,G,e,E,p,z */
   7123             NK_ASSERT(0 && "specifier is not supported!");
   7124             return result;
   7125         }
   7126     }
   7127     buf[(len >= buf_size)?(buf_size-1):len] = 0;
   7128     result = (len >= buf_size)?-1:len;
   7129     return result;
   7130 }
   7131 #endif
   7132 NK_LIB int
   7133 nk_strfmt(char *buf, int buf_size, const char *fmt, va_list args)
   7134 {
   7135     int result = -1;
   7136     NK_ASSERT(buf);
   7137     NK_ASSERT(buf_size);
   7138     if (!buf || !buf_size || !fmt) return 0;
   7139 #ifdef NK_INCLUDE_STANDARD_IO
   7140     result = NK_VSNPRINTF(buf, (nk_size)buf_size, fmt, args);
   7141     result = (result >= buf_size) ? -1: result;
   7142     buf[buf_size-1] = 0;
   7143 #else
   7144     result = nk_vsnprintf(buf, buf_size, fmt, args);
   7145 #endif
   7146     return result;
   7147 }
   7148 #endif
   7149 NK_API nk_hash
   7150 nk_murmur_hash(const void * key, int len, nk_hash seed)
   7151 {
   7152     /* 32-Bit MurmurHash3: https://code.google.com/p/smhasher/wiki/MurmurHash3*/
   7153     #define NK_ROTL(x,r) ((x) << (r) | ((x) >> (32 - r)))
   7154     union {const nk_uint *i; const nk_byte *b;} conv = {0};
   7155     const nk_byte *data = (const nk_byte*)key;
   7156     const int nblocks = len/4;
   7157     nk_uint h1 = seed;
   7158     const nk_uint c1 = 0xcc9e2d51;
   7159     const nk_uint c2 = 0x1b873593;
   7160     const nk_byte *tail;
   7161     const nk_uint *blocks;
   7162     nk_uint k1;
   7163     int i;
   7164 
   7165     /* body */
   7166     if (!key) return 0;
   7167     conv.b = (data + nblocks*4);
   7168     blocks = (const nk_uint*)conv.i;
   7169     for (i = -nblocks; i; ++i) {
   7170         k1 = blocks[i];
   7171         k1 *= c1;
   7172         k1 = NK_ROTL(k1,15);
   7173         k1 *= c2;
   7174 
   7175         h1 ^= k1;
   7176         h1 = NK_ROTL(h1,13);
   7177         h1 = h1*5+0xe6546b64;
   7178     }
   7179 
   7180     /* tail */
   7181     tail = (const nk_byte*)(data + nblocks*4);
   7182     k1 = 0;
   7183     switch (len & 3) {
   7184     case 3: k1 ^= (nk_uint)(tail[2] << 16); /* fallthrough */
   7185     case 2: k1 ^= (nk_uint)(tail[1] << 8u); /* fallthrough */
   7186     case 1: k1 ^= tail[0];
   7187             k1 *= c1;
   7188             k1 = NK_ROTL(k1,15);
   7189             k1 *= c2;
   7190             h1 ^= k1;
   7191             break;
   7192     default: break;
   7193     }
   7194 
   7195     /* finalization */
   7196     h1 ^= (nk_uint)len;
   7197     /* fmix32 */
   7198     h1 ^= h1 >> 16;
   7199     h1 *= 0x85ebca6b;
   7200     h1 ^= h1 >> 13;
   7201     h1 *= 0xc2b2ae35;
   7202     h1 ^= h1 >> 16;
   7203 
   7204     #undef NK_ROTL
   7205     return h1;
   7206 }
   7207 #ifdef NK_INCLUDE_STANDARD_IO
   7208 NK_LIB char*
   7209 nk_file_load(const char* path, nk_size* siz, struct nk_allocator *alloc)
   7210 {
   7211     char *buf;
   7212     FILE *fd;
   7213     long ret;
   7214 
   7215     NK_ASSERT(path);
   7216     NK_ASSERT(siz);
   7217     NK_ASSERT(alloc);
   7218     if (!path || !siz || !alloc)
   7219         return 0;
   7220 
   7221     fd = fopen(path, "rb");
   7222     if (!fd) return 0;
   7223     fseek(fd, 0, SEEK_END);
   7224     ret = ftell(fd);
   7225     if (ret < 0) {
   7226         fclose(fd);
   7227         return 0;
   7228     }
   7229     *siz = (nk_size)ret;
   7230     fseek(fd, 0, SEEK_SET);
   7231     buf = (char*)alloc->alloc(alloc->userdata,0, *siz);
   7232     NK_ASSERT(buf);
   7233     if (!buf) {
   7234         fclose(fd);
   7235         return 0;
   7236     }
   7237     *siz = (nk_size)fread(buf, 1,*siz, fd);
   7238     fclose(fd);
   7239     return buf;
   7240 }
   7241 #endif
   7242 NK_LIB int
   7243 nk_text_clamp(const struct nk_user_font *font, const char *text,
   7244     int text_len, float space, int *glyphs, float *text_width,
   7245     nk_rune *sep_list, int sep_count)
   7246 {
   7247     int i = 0;
   7248     int glyph_len = 0;
   7249     float last_width = 0;
   7250     nk_rune unicode = 0;
   7251     float width = 0;
   7252     int len = 0;
   7253     int g = 0;
   7254     float s;
   7255 
   7256     int sep_len = 0;
   7257     int sep_g = 0;
   7258     float sep_width = 0;
   7259     sep_count = NK_MAX(sep_count,0);
   7260 
   7261     glyph_len = nk_utf_decode(text, &unicode, text_len);
   7262     while (glyph_len && (width < space) && (len < text_len)) {
   7263         len += glyph_len;
   7264         s = font->width(font->userdata, font->height, text, len);
   7265         for (i = 0; i < sep_count; ++i) {
   7266             if (unicode != sep_list[i]) continue;
   7267             sep_width = last_width = width;
   7268             sep_g = g+1;
   7269             sep_len = len;
   7270             break;
   7271         }
   7272         if (i == sep_count){
   7273             last_width = sep_width = width;
   7274             sep_g = g+1;
   7275         }
   7276         width = s;
   7277         glyph_len = nk_utf_decode(&text[len], &unicode, text_len - len);
   7278         g++;
   7279     }
   7280     if (len >= text_len) {
   7281         *glyphs = g;
   7282         *text_width = last_width;
   7283         return len;
   7284     } else {
   7285         *glyphs = sep_g;
   7286         *text_width = sep_width;
   7287         return (!sep_len) ? len: sep_len;
   7288     }
   7289 }
   7290 NK_LIB struct nk_vec2
   7291 nk_text_calculate_text_bounds(const struct nk_user_font *font,
   7292     const char *begin, int byte_len, float row_height, const char **remaining,
   7293     struct nk_vec2 *out_offset, int *glyphs, int op)
   7294 {
   7295     float line_height = row_height;
   7296     struct nk_vec2 text_size = nk_vec2(0,0);
   7297     float line_width = 0.0f;
   7298 
   7299     float glyph_width;
   7300     int glyph_len = 0;
   7301     nk_rune unicode = 0;
   7302     int text_len = 0;
   7303     if (!begin || byte_len <= 0 || !font)
   7304         return nk_vec2(0,row_height);
   7305 
   7306     glyph_len = nk_utf_decode(begin, &unicode, byte_len);
   7307     if (!glyph_len) return text_size;
   7308     glyph_width = font->width(font->userdata, font->height, begin, glyph_len);
   7309 
   7310     *glyphs = 0;
   7311     while ((text_len < byte_len) && glyph_len) {
   7312         if (unicode == '\n') {
   7313             text_size.x = NK_MAX(text_size.x, line_width);
   7314             text_size.y += line_height;
   7315             line_width = 0;
   7316             *glyphs+=1;
   7317             if (op == NK_STOP_ON_NEW_LINE)
   7318                 break;
   7319 
   7320             text_len++;
   7321             glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
   7322             continue;
   7323         }
   7324 
   7325         if (unicode == '\r') {
   7326             text_len++;
   7327             *glyphs+=1;
   7328             glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
   7329             continue;
   7330         }
   7331 
   7332         *glyphs = *glyphs + 1;
   7333         text_len += glyph_len;
   7334         line_width += (float)glyph_width;
   7335         glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
   7336         glyph_width = font->width(font->userdata, font->height, begin+text_len, glyph_len);
   7337         continue;
   7338     }
   7339 
   7340     if (text_size.x < line_width)
   7341         text_size.x = line_width;
   7342     if (out_offset)
   7343         *out_offset = nk_vec2(line_width, text_size.y + line_height);
   7344     if (line_width > 0 || text_size.y == 0.0f)
   7345         text_size.y += line_height;
   7346     if (remaining)
   7347         *remaining = begin+text_len;
   7348     return text_size;
   7349 }
   7350 
   7351 
   7352 
   7353 
   7354 
   7355 /* ==============================================================
   7356  *
   7357  *                          COLOR
   7358  *
   7359  * ===============================================================*/
   7360 NK_INTERN int
   7361 nk_parse_hex(const char *p, int length)
   7362 {
   7363     int i = 0;
   7364     int len = 0;
   7365     while (len < length) {
   7366         i <<= 4;
   7367         if (p[len] >= 'a' && p[len] <= 'f')
   7368             i += ((p[len] - 'a') + 10);
   7369         else if (p[len] >= 'A' && p[len] <= 'F')
   7370             i += ((p[len] - 'A') + 10);
   7371         else i += (p[len] - '0');
   7372         len++;
   7373     }
   7374     return i;
   7375 }
   7376 NK_API struct nk_color
   7377 nk_rgba(int r, int g, int b, int a)
   7378 {
   7379     struct nk_color ret;
   7380     ret.r = (nk_byte)NK_CLAMP(0, r, 255);
   7381     ret.g = (nk_byte)NK_CLAMP(0, g, 255);
   7382     ret.b = (nk_byte)NK_CLAMP(0, b, 255);
   7383     ret.a = (nk_byte)NK_CLAMP(0, a, 255);
   7384     return ret;
   7385 }
   7386 NK_API struct nk_color
   7387 nk_rgb_hex(const char *rgb)
   7388 {
   7389     struct nk_color col;
   7390     const char *c = rgb;
   7391     if (*c == '#') c++;
   7392     col.r = (nk_byte)nk_parse_hex(c, 2);
   7393     col.g = (nk_byte)nk_parse_hex(c+2, 2);
   7394     col.b = (nk_byte)nk_parse_hex(c+4, 2);
   7395     col.a = 255;
   7396     return col;
   7397 }
   7398 NK_API struct nk_color
   7399 nk_rgba_hex(const char *rgb)
   7400 {
   7401     struct nk_color col;
   7402     const char *c = rgb;
   7403     if (*c == '#') c++;
   7404     col.r = (nk_byte)nk_parse_hex(c, 2);
   7405     col.g = (nk_byte)nk_parse_hex(c+2, 2);
   7406     col.b = (nk_byte)nk_parse_hex(c+4, 2);
   7407     col.a = (nk_byte)nk_parse_hex(c+6, 2);
   7408     return col;
   7409 }
   7410 NK_API void
   7411 nk_color_hex_rgba(char *output, struct nk_color col)
   7412 {
   7413     #define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i): 'A' - 10 + (i))
   7414     output[0] = (char)NK_TO_HEX((col.r & 0xF0) >> 4);
   7415     output[1] = (char)NK_TO_HEX((col.r & 0x0F));
   7416     output[2] = (char)NK_TO_HEX((col.g & 0xF0) >> 4);
   7417     output[3] = (char)NK_TO_HEX((col.g & 0x0F));
   7418     output[4] = (char)NK_TO_HEX((col.b & 0xF0) >> 4);
   7419     output[5] = (char)NK_TO_HEX((col.b & 0x0F));
   7420     output[6] = (char)NK_TO_HEX((col.a & 0xF0) >> 4);
   7421     output[7] = (char)NK_TO_HEX((col.a & 0x0F));
   7422     output[8] = '\0';
   7423     #undef NK_TO_HEX
   7424 }
   7425 NK_API void
   7426 nk_color_hex_rgb(char *output, struct nk_color col)
   7427 {
   7428     #define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i): 'A' - 10 + (i))
   7429     output[0] = (char)NK_TO_HEX((col.r & 0xF0) >> 4);
   7430     output[1] = (char)NK_TO_HEX((col.r & 0x0F));
   7431     output[2] = (char)NK_TO_HEX((col.g & 0xF0) >> 4);
   7432     output[3] = (char)NK_TO_HEX((col.g & 0x0F));
   7433     output[4] = (char)NK_TO_HEX((col.b & 0xF0) >> 4);
   7434     output[5] = (char)NK_TO_HEX((col.b & 0x0F));
   7435     output[6] = '\0';
   7436     #undef NK_TO_HEX
   7437 }
   7438 NK_API struct nk_color
   7439 nk_rgba_iv(const int *c)
   7440 {
   7441     return nk_rgba(c[0], c[1], c[2], c[3]);
   7442 }
   7443 NK_API struct nk_color
   7444 nk_rgba_bv(const nk_byte *c)
   7445 {
   7446     return nk_rgba(c[0], c[1], c[2], c[3]);
   7447 }
   7448 NK_API struct nk_color
   7449 nk_rgb(int r, int g, int b)
   7450 {
   7451     struct nk_color ret;
   7452     ret.r = (nk_byte)NK_CLAMP(0, r, 255);
   7453     ret.g = (nk_byte)NK_CLAMP(0, g, 255);
   7454     ret.b = (nk_byte)NK_CLAMP(0, b, 255);
   7455     ret.a = (nk_byte)255;
   7456     return ret;
   7457 }
   7458 NK_API struct nk_color
   7459 nk_rgb_iv(const int *c)
   7460 {
   7461     return nk_rgb(c[0], c[1], c[2]);
   7462 }
   7463 NK_API struct nk_color
   7464 nk_rgb_bv(const nk_byte* c)
   7465 {
   7466     return nk_rgb(c[0], c[1], c[2]);
   7467 }
   7468 NK_API struct nk_color
   7469 nk_rgba_u32(nk_uint in)
   7470 {
   7471     struct nk_color ret;
   7472     ret.r = (in & 0xFF);
   7473     ret.g = ((in >> 8) & 0xFF);
   7474     ret.b = ((in >> 16) & 0xFF);
   7475     ret.a = (nk_byte)((in >> 24) & 0xFF);
   7476     return ret;
   7477 }
   7478 NK_API struct nk_color
   7479 nk_rgba_f(float r, float g, float b, float a)
   7480 {
   7481     struct nk_color ret;
   7482     ret.r = (nk_byte)(NK_SATURATE(r) * 255.0f);
   7483     ret.g = (nk_byte)(NK_SATURATE(g) * 255.0f);
   7484     ret.b = (nk_byte)(NK_SATURATE(b) * 255.0f);
   7485     ret.a = (nk_byte)(NK_SATURATE(a) * 255.0f);
   7486     return ret;
   7487 }
   7488 NK_API struct nk_color
   7489 nk_rgba_fv(const float *c)
   7490 {
   7491     return nk_rgba_f(c[0], c[1], c[2], c[3]);
   7492 }
   7493 NK_API struct nk_color
   7494 nk_rgba_cf(struct nk_colorf c)
   7495 {
   7496     return nk_rgba_f(c.r, c.g, c.b, c.a);
   7497 }
   7498 NK_API struct nk_color
   7499 nk_rgb_f(float r, float g, float b)
   7500 {
   7501     struct nk_color ret;
   7502     ret.r = (nk_byte)(NK_SATURATE(r) * 255.0f);
   7503     ret.g = (nk_byte)(NK_SATURATE(g) * 255.0f);
   7504     ret.b = (nk_byte)(NK_SATURATE(b) * 255.0f);
   7505     ret.a = 255;
   7506     return ret;
   7507 }
   7508 NK_API struct nk_color
   7509 nk_rgb_fv(const float *c)
   7510 {
   7511     return nk_rgb_f(c[0], c[1], c[2]);
   7512 }
   7513 NK_API struct nk_color
   7514 nk_rgb_cf(struct nk_colorf c)
   7515 {
   7516     return nk_rgb_f(c.r, c.g, c.b);
   7517 }
   7518 NK_API struct nk_color
   7519 nk_hsv(int h, int s, int v)
   7520 {
   7521     return nk_hsva(h, s, v, 255);
   7522 }
   7523 NK_API struct nk_color
   7524 nk_hsv_iv(const int *c)
   7525 {
   7526     return nk_hsv(c[0], c[1], c[2]);
   7527 }
   7528 NK_API struct nk_color
   7529 nk_hsv_bv(const nk_byte *c)
   7530 {
   7531     return nk_hsv(c[0], c[1], c[2]);
   7532 }
   7533 NK_API struct nk_color
   7534 nk_hsv_f(float h, float s, float v)
   7535 {
   7536     return nk_hsva_f(h, s, v, 1.0f);
   7537 }
   7538 NK_API struct nk_color
   7539 nk_hsv_fv(const float *c)
   7540 {
   7541     return nk_hsv_f(c[0], c[1], c[2]);
   7542 }
   7543 NK_API struct nk_color
   7544 nk_hsva(int h, int s, int v, int a)
   7545 {
   7546     float hf = ((float)NK_CLAMP(0, h, 255)) / 255.0f;
   7547     float sf = ((float)NK_CLAMP(0, s, 255)) / 255.0f;
   7548     float vf = ((float)NK_CLAMP(0, v, 255)) / 255.0f;
   7549     float af = ((float)NK_CLAMP(0, a, 255)) / 255.0f;
   7550     return nk_hsva_f(hf, sf, vf, af);
   7551 }
   7552 NK_API struct nk_color
   7553 nk_hsva_iv(const int *c)
   7554 {
   7555     return nk_hsva(c[0], c[1], c[2], c[3]);
   7556 }
   7557 NK_API struct nk_color
   7558 nk_hsva_bv(const nk_byte *c)
   7559 {
   7560     return nk_hsva(c[0], c[1], c[2], c[3]);
   7561 }
   7562 NK_API struct nk_colorf
   7563 nk_hsva_colorf(float h, float s, float v, float a)
   7564 {
   7565     int i;
   7566     float p, q, t, f;
   7567     struct nk_colorf out = {0,0,0,0};
   7568     if (s <= 0.0f) {
   7569         out.r = v; out.g = v; out.b = v; out.a = a;
   7570         return out;
   7571     }
   7572     h = h / (60.0f/360.0f);
   7573     i = (int)h;
   7574     f = h - (float)i;
   7575     p = v * (1.0f - s);
   7576     q = v * (1.0f - (s * f));
   7577     t = v * (1.0f - s * (1.0f - f));
   7578 
   7579     switch (i) {
   7580     case 0: default: out.r = v; out.g = t; out.b = p; break;
   7581     case 1: out.r = q; out.g = v; out.b = p; break;
   7582     case 2: out.r = p; out.g = v; out.b = t; break;
   7583     case 3: out.r = p; out.g = q; out.b = v; break;
   7584     case 4: out.r = t; out.g = p; out.b = v; break;
   7585     case 5: out.r = v; out.g = p; out.b = q; break;}
   7586     out.a = a;
   7587     return out;
   7588 }
   7589 NK_API struct nk_colorf
   7590 nk_hsva_colorfv(float *c)
   7591 {
   7592     return nk_hsva_colorf(c[0], c[1], c[2], c[3]);
   7593 }
   7594 NK_API struct nk_color
   7595 nk_hsva_f(float h, float s, float v, float a)
   7596 {
   7597     struct nk_colorf c = nk_hsva_colorf(h, s, v, a);
   7598     return nk_rgba_f(c.r, c.g, c.b, c.a);
   7599 }
   7600 NK_API struct nk_color
   7601 nk_hsva_fv(const float *c)
   7602 {
   7603     return nk_hsva_f(c[0], c[1], c[2], c[3]);
   7604 }
   7605 NK_API nk_uint
   7606 nk_color_u32(struct nk_color in)
   7607 {
   7608     nk_uint out = (nk_uint)in.r;
   7609     out |= ((nk_uint)in.g << 8);
   7610     out |= ((nk_uint)in.b << 16);
   7611     out |= ((nk_uint)in.a << 24);
   7612     return out;
   7613 }
   7614 NK_API void
   7615 nk_color_f(float *r, float *g, float *b, float *a, struct nk_color in)
   7616 {
   7617     NK_STORAGE const float s = 1.0f/255.0f;
   7618     *r = (float)in.r * s;
   7619     *g = (float)in.g * s;
   7620     *b = (float)in.b * s;
   7621     *a = (float)in.a * s;
   7622 }
   7623 NK_API void
   7624 nk_color_fv(float *c, struct nk_color in)
   7625 {
   7626     nk_color_f(&c[0], &c[1], &c[2], &c[3], in);
   7627 }
   7628 NK_API struct nk_colorf
   7629 nk_color_cf(struct nk_color in)
   7630 {
   7631     struct nk_colorf o;
   7632     nk_color_f(&o.r, &o.g, &o.b, &o.a, in);
   7633     return o;
   7634 }
   7635 NK_API void
   7636 nk_color_d(double *r, double *g, double *b, double *a, struct nk_color in)
   7637 {
   7638     NK_STORAGE const double s = 1.0/255.0;
   7639     *r = (double)in.r * s;
   7640     *g = (double)in.g * s;
   7641     *b = (double)in.b * s;
   7642     *a = (double)in.a * s;
   7643 }
   7644 NK_API void
   7645 nk_color_dv(double *c, struct nk_color in)
   7646 {
   7647     nk_color_d(&c[0], &c[1], &c[2], &c[3], in);
   7648 }
   7649 NK_API void
   7650 nk_color_hsv_f(float *out_h, float *out_s, float *out_v, struct nk_color in)
   7651 {
   7652     float a;
   7653     nk_color_hsva_f(out_h, out_s, out_v, &a, in);
   7654 }
   7655 NK_API void
   7656 nk_color_hsv_fv(float *out, struct nk_color in)
   7657 {
   7658     float a;
   7659     nk_color_hsva_f(&out[0], &out[1], &out[2], &a, in);
   7660 }
   7661 NK_API void
   7662 nk_colorf_hsva_f(float *out_h, float *out_s,
   7663     float *out_v, float *out_a, struct nk_colorf in)
   7664 {
   7665     float chroma;
   7666     float K = 0.0f;
   7667     if (in.g < in.b) {
   7668         const float t = in.g; in.g = in.b; in.b = t;
   7669         K = -1.f;
   7670     }
   7671     if (in.r < in.g) {
   7672         const float t = in.r; in.r = in.g; in.g = t;
   7673         K = -2.f/6.0f - K;
   7674     }
   7675     chroma = in.r - ((in.g < in.b) ? in.g: in.b);
   7676     *out_h = NK_ABS(K + (in.g - in.b)/(6.0f * chroma + 1e-20f));
   7677     *out_s = chroma / (in.r + 1e-20f);
   7678     *out_v = in.r;
   7679     *out_a = in.a;
   7680 
   7681 }
   7682 NK_API void
   7683 nk_colorf_hsva_fv(float *hsva, struct nk_colorf in)
   7684 {
   7685     nk_colorf_hsva_f(&hsva[0], &hsva[1], &hsva[2], &hsva[3], in);
   7686 }
   7687 NK_API void
   7688 nk_color_hsva_f(float *out_h, float *out_s,
   7689     float *out_v, float *out_a, struct nk_color in)
   7690 {
   7691     struct nk_colorf col;
   7692     nk_color_f(&col.r,&col.g,&col.b,&col.a, in);
   7693     nk_colorf_hsva_f(out_h, out_s, out_v, out_a, col);
   7694 }
   7695 NK_API void
   7696 nk_color_hsva_fv(float *out, struct nk_color in)
   7697 {
   7698     nk_color_hsva_f(&out[0], &out[1], &out[2], &out[3], in);
   7699 }
   7700 NK_API void
   7701 nk_color_hsva_i(int *out_h, int *out_s, int *out_v,
   7702                 int *out_a, struct nk_color in)
   7703 {
   7704     float h,s,v,a;
   7705     nk_color_hsva_f(&h, &s, &v, &a, in);
   7706     *out_h = (nk_byte)(h * 255.0f);
   7707     *out_s = (nk_byte)(s * 255.0f);
   7708     *out_v = (nk_byte)(v * 255.0f);
   7709     *out_a = (nk_byte)(a * 255.0f);
   7710 }
   7711 NK_API void
   7712 nk_color_hsva_iv(int *out, struct nk_color in)
   7713 {
   7714     nk_color_hsva_i(&out[0], &out[1], &out[2], &out[3], in);
   7715 }
   7716 NK_API void
   7717 nk_color_hsva_bv(nk_byte *out, struct nk_color in)
   7718 {
   7719     int tmp[4];
   7720     nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
   7721     out[0] = (nk_byte)tmp[0];
   7722     out[1] = (nk_byte)tmp[1];
   7723     out[2] = (nk_byte)tmp[2];
   7724     out[3] = (nk_byte)tmp[3];
   7725 }
   7726 NK_API void
   7727 nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a, struct nk_color in)
   7728 {
   7729     int tmp[4];
   7730     nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
   7731     *h = (nk_byte)tmp[0];
   7732     *s = (nk_byte)tmp[1];
   7733     *v = (nk_byte)tmp[2];
   7734     *a = (nk_byte)tmp[3];
   7735 }
   7736 NK_API void
   7737 nk_color_hsv_i(int *out_h, int *out_s, int *out_v, struct nk_color in)
   7738 {
   7739     int a;
   7740     nk_color_hsva_i(out_h, out_s, out_v, &a, in);
   7741 }
   7742 NK_API void
   7743 nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v, struct nk_color in)
   7744 {
   7745     int tmp[4];
   7746     nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
   7747     *out_h = (nk_byte)tmp[0];
   7748     *out_s = (nk_byte)tmp[1];
   7749     *out_v = (nk_byte)tmp[2];
   7750 }
   7751 NK_API void
   7752 nk_color_hsv_iv(int *out, struct nk_color in)
   7753 {
   7754     nk_color_hsv_i(&out[0], &out[1], &out[2], in);
   7755 }
   7756 NK_API void
   7757 nk_color_hsv_bv(nk_byte *out, struct nk_color in)
   7758 {
   7759     int tmp[4];
   7760     nk_color_hsv_i(&tmp[0], &tmp[1], &tmp[2], in);
   7761     out[0] = (nk_byte)tmp[0];
   7762     out[1] = (nk_byte)tmp[1];
   7763     out[2] = (nk_byte)tmp[2];
   7764 }
   7765 
   7766 
   7767 
   7768 
   7769 
   7770 /* ===============================================================
   7771  *
   7772  *                              UTF-8
   7773  *
   7774  * ===============================================================*/
   7775 NK_GLOBAL const nk_byte nk_utfbyte[NK_UTF_SIZE+1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
   7776 NK_GLOBAL const nk_byte nk_utfmask[NK_UTF_SIZE+1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
   7777 NK_GLOBAL const nk_uint nk_utfmin[NK_UTF_SIZE+1] = {0, 0, 0x80, 0x800, 0x10000};
   7778 NK_GLOBAL const nk_uint nk_utfmax[NK_UTF_SIZE+1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
   7779 
   7780 NK_INTERN int
   7781 nk_utf_validate(nk_rune *u, int i)
   7782 {
   7783     NK_ASSERT(u);
   7784     if (!u) return 0;
   7785     if (!NK_BETWEEN(*u, nk_utfmin[i], nk_utfmax[i]) ||
   7786          NK_BETWEEN(*u, 0xD800, 0xDFFF))
   7787             *u = NK_UTF_INVALID;
   7788     for (i = 1; *u > nk_utfmax[i]; ++i);
   7789     return i;
   7790 }
   7791 NK_INTERN nk_rune
   7792 nk_utf_decode_byte(char c, int *i)
   7793 {
   7794     NK_ASSERT(i);
   7795     if (!i) return 0;
   7796     for(*i = 0; *i < (int)NK_LEN(nk_utfmask); ++(*i)) {
   7797         if (((nk_byte)c & nk_utfmask[*i]) == nk_utfbyte[*i])
   7798             return (nk_byte)(c & ~nk_utfmask[*i]);
   7799     }
   7800     return 0;
   7801 }
   7802 NK_API int
   7803 nk_utf_decode(const char *c, nk_rune *u, int clen)
   7804 {
   7805     int i, j, len, type=0;
   7806     nk_rune udecoded;
   7807 
   7808     NK_ASSERT(c);
   7809     NK_ASSERT(u);
   7810 
   7811     if (!c || !u) return 0;
   7812     if (!clen) return 0;
   7813     *u = NK_UTF_INVALID;
   7814 
   7815     udecoded = nk_utf_decode_byte(c[0], &len);
   7816     if (!NK_BETWEEN(len, 1, NK_UTF_SIZE))
   7817         return 1;
   7818 
   7819     for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
   7820         udecoded = (udecoded << 6) | nk_utf_decode_byte(c[i], &type);
   7821         if (type != 0)
   7822             return j;
   7823     }
   7824     if (j < len)
   7825         return 0;
   7826     *u = udecoded;
   7827     nk_utf_validate(u, len);
   7828     return len;
   7829 }
   7830 NK_INTERN char
   7831 nk_utf_encode_byte(nk_rune u, int i)
   7832 {
   7833     return (char)((nk_utfbyte[i]) | ((nk_byte)u & ~nk_utfmask[i]));
   7834 }
   7835 NK_API int
   7836 nk_utf_encode(nk_rune u, char *c, int clen)
   7837 {
   7838     int len, i;
   7839     len = nk_utf_validate(&u, 0);
   7840     if (clen < len || !len || len > NK_UTF_SIZE)
   7841         return 0;
   7842 
   7843     for (i = len - 1; i != 0; --i) {
   7844         c[i] = nk_utf_encode_byte(u, 0);
   7845         u >>= 6;
   7846     }
   7847     c[0] = nk_utf_encode_byte(u, len);
   7848     return len;
   7849 }
   7850 NK_API int
   7851 nk_utf_len(const char *str, int len)
   7852 {
   7853     const char *text;
   7854     int glyphs = 0;
   7855     int text_len;
   7856     int glyph_len;
   7857     int src_len = 0;
   7858     nk_rune unicode;
   7859 
   7860     NK_ASSERT(str);
   7861     if (!str || !len) return 0;
   7862 
   7863     text = str;
   7864     text_len = len;
   7865     glyph_len = nk_utf_decode(text, &unicode, text_len);
   7866     while (glyph_len && src_len < len) {
   7867         glyphs++;
   7868         src_len = src_len + glyph_len;
   7869         glyph_len = nk_utf_decode(text + src_len, &unicode, text_len - src_len);
   7870     }
   7871     return glyphs;
   7872 }
   7873 NK_API const char*
   7874 nk_utf_at(const char *buffer, int length, int index,
   7875     nk_rune *unicode, int *len)
   7876 {
   7877     int i = 0;
   7878     int src_len = 0;
   7879     int glyph_len = 0;
   7880     const char *text;
   7881     int text_len;
   7882 
   7883     NK_ASSERT(buffer);
   7884     NK_ASSERT(unicode);
   7885     NK_ASSERT(len);
   7886 
   7887     if (!buffer || !unicode || !len) return 0;
   7888     if (index < 0) {
   7889         *unicode = NK_UTF_INVALID;
   7890         *len = 0;
   7891         return 0;
   7892     }
   7893 
   7894     text = buffer;
   7895     text_len = length;
   7896     glyph_len = nk_utf_decode(text, unicode, text_len);
   7897     while (glyph_len) {
   7898         if (i == index) {
   7899             *len = glyph_len;
   7900             break;
   7901         }
   7902 
   7903         i++;
   7904         src_len = src_len + glyph_len;
   7905         glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
   7906     }
   7907     if (i != index) return 0;
   7908     return buffer + src_len;
   7909 }
   7910 
   7911 
   7912 
   7913 
   7914 
   7915 /* ==============================================================
   7916  *
   7917  *                          BUFFER
   7918  *
   7919  * ===============================================================*/
   7920 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
   7921 NK_LIB void*
   7922 nk_malloc(nk_handle unused, void *old,nk_size size)
   7923 {
   7924     NK_UNUSED(unused);
   7925     NK_UNUSED(old);
   7926     return malloc(size);
   7927 }
   7928 NK_LIB void
   7929 nk_mfree(nk_handle unused, void *ptr)
   7930 {
   7931     NK_UNUSED(unused);
   7932     free(ptr);
   7933 }
   7934 NK_API void
   7935 nk_buffer_init_default(struct nk_buffer *buffer)
   7936 {
   7937     struct nk_allocator alloc;
   7938     alloc.userdata.ptr = 0;
   7939     alloc.alloc = nk_malloc;
   7940     alloc.free = nk_mfree;
   7941     nk_buffer_init(buffer, &alloc, NK_BUFFER_DEFAULT_INITIAL_SIZE);
   7942 }
   7943 #endif
   7944 
   7945 NK_API void
   7946 nk_buffer_init(struct nk_buffer *b, const struct nk_allocator *a,
   7947     nk_size initial_size)
   7948 {
   7949     NK_ASSERT(b);
   7950     NK_ASSERT(a);
   7951     NK_ASSERT(initial_size);
   7952     if (!b || !a || !initial_size) return;
   7953 
   7954     nk_zero(b, sizeof(*b));
   7955     b->type = NK_BUFFER_DYNAMIC;
   7956     b->memory.ptr = a->alloc(a->userdata,0, initial_size);
   7957     b->memory.size = initial_size;
   7958     b->size = initial_size;
   7959     b->grow_factor = 2.0f;
   7960     b->pool = *a;
   7961 }
   7962 NK_API void
   7963 nk_buffer_init_fixed(struct nk_buffer *b, void *m, nk_size size)
   7964 {
   7965     NK_ASSERT(b);
   7966     NK_ASSERT(m);
   7967     NK_ASSERT(size);
   7968     if (!b || !m || !size) return;
   7969 
   7970     nk_zero(b, sizeof(*b));
   7971     b->type = NK_BUFFER_FIXED;
   7972     b->memory.ptr = m;
   7973     b->memory.size = size;
   7974     b->size = size;
   7975 }
   7976 NK_LIB void*
   7977 nk_buffer_align(void *unaligned,
   7978     nk_size align, nk_size *alignment,
   7979     enum nk_buffer_allocation_type type)
   7980 {
   7981     void *memory = 0;
   7982     switch (type) {
   7983     default:
   7984     case NK_BUFFER_MAX:
   7985     case NK_BUFFER_FRONT:
   7986         if (align) {
   7987             memory = NK_ALIGN_PTR(unaligned, align);
   7988             *alignment = (nk_size)((nk_byte*)memory - (nk_byte*)unaligned);
   7989         } else {
   7990             memory = unaligned;
   7991             *alignment = 0;
   7992         }
   7993         break;
   7994     case NK_BUFFER_BACK:
   7995         if (align) {
   7996             memory = NK_ALIGN_PTR_BACK(unaligned, align);
   7997             *alignment = (nk_size)((nk_byte*)unaligned - (nk_byte*)memory);
   7998         } else {
   7999             memory = unaligned;
   8000             *alignment = 0;
   8001         }
   8002         break;
   8003     }
   8004     return memory;
   8005 }
   8006 NK_LIB void*
   8007 nk_buffer_realloc(struct nk_buffer *b, nk_size capacity, nk_size *size)
   8008 {
   8009     void *temp;
   8010     nk_size buffer_size;
   8011 
   8012     NK_ASSERT(b);
   8013     NK_ASSERT(size);
   8014     if (!b || !size || !b->pool.alloc || !b->pool.free)
   8015         return 0;
   8016 
   8017     buffer_size = b->memory.size;
   8018     temp = b->pool.alloc(b->pool.userdata, b->memory.ptr, capacity);
   8019     NK_ASSERT(temp);
   8020     if (!temp) return 0;
   8021 
   8022     *size = capacity;
   8023     if (temp != b->memory.ptr) {
   8024         NK_MEMCPY(temp, b->memory.ptr, buffer_size);
   8025         b->pool.free(b->pool.userdata, b->memory.ptr);
   8026     }
   8027 
   8028     if (b->size == buffer_size) {
   8029         /* no back buffer so just set correct size */
   8030         b->size = capacity;
   8031         return temp;
   8032     } else {
   8033         /* copy back buffer to the end of the new buffer */
   8034         void *dst, *src;
   8035         nk_size back_size;
   8036         back_size = buffer_size - b->size;
   8037         dst = nk_ptr_add(void, temp, capacity - back_size);
   8038         src = nk_ptr_add(void, temp, b->size);
   8039         NK_MEMCPY(dst, src, back_size);
   8040         b->size = capacity - back_size;
   8041     }
   8042     return temp;
   8043 }
   8044 NK_LIB void*
   8045 nk_buffer_alloc(struct nk_buffer *b, enum nk_buffer_allocation_type type,
   8046     nk_size size, nk_size align)
   8047 {
   8048     int full;
   8049     nk_size alignment;
   8050     void *unaligned;
   8051     void *memory;
   8052 
   8053     NK_ASSERT(b);
   8054     NK_ASSERT(size);
   8055     if (!b || !size) return 0;
   8056     b->needed += size;
   8057 
   8058     /* calculate total size with needed alignment + size */
   8059     if (type == NK_BUFFER_FRONT)
   8060         unaligned = nk_ptr_add(void, b->memory.ptr, b->allocated);
   8061     else unaligned = nk_ptr_add(void, b->memory.ptr, b->size - size);
   8062     memory = nk_buffer_align(unaligned, align, &alignment, type);
   8063 
   8064     /* check if buffer has enough memory*/
   8065     if (type == NK_BUFFER_FRONT)
   8066         full = ((b->allocated + size + alignment) > b->size);
   8067     else full = ((b->size - NK_MIN(b->size,(size + alignment))) <= b->allocated);
   8068 
   8069     if (full) {
   8070         nk_size capacity;
   8071         if (b->type != NK_BUFFER_DYNAMIC)
   8072             return 0;
   8073         NK_ASSERT(b->pool.alloc && b->pool.free);
   8074         if (b->type != NK_BUFFER_DYNAMIC || !b->pool.alloc || !b->pool.free)
   8075             return 0;
   8076 
   8077         /* buffer is full so allocate bigger buffer if dynamic */
   8078         capacity = (nk_size)((float)b->memory.size * b->grow_factor);
   8079         capacity = NK_MAX(capacity, nk_round_up_pow2((nk_uint)(b->allocated + size)));
   8080         b->memory.ptr = nk_buffer_realloc(b, capacity, &b->memory.size);
   8081         if (!b->memory.ptr) return 0;
   8082 
   8083         /* align newly allocated pointer */
   8084         if (type == NK_BUFFER_FRONT)
   8085             unaligned = nk_ptr_add(void, b->memory.ptr, b->allocated);
   8086         else unaligned = nk_ptr_add(void, b->memory.ptr, b->size - size);
   8087         memory = nk_buffer_align(unaligned, align, &alignment, type);
   8088     }
   8089     if (type == NK_BUFFER_FRONT)
   8090         b->allocated += size + alignment;
   8091     else b->size -= (size + alignment);
   8092     b->needed += alignment;
   8093     b->calls++;
   8094     return memory;
   8095 }
   8096 NK_API void
   8097 nk_buffer_push(struct nk_buffer *b, enum nk_buffer_allocation_type type,
   8098     const void *memory, nk_size size, nk_size align)
   8099 {
   8100     void *mem = nk_buffer_alloc(b, type, size, align);
   8101     if (!mem) return;
   8102     NK_MEMCPY(mem, memory, size);
   8103 }
   8104 NK_API void
   8105 nk_buffer_mark(struct nk_buffer *buffer, enum nk_buffer_allocation_type type)
   8106 {
   8107     NK_ASSERT(buffer);
   8108     if (!buffer) return;
   8109     buffer->marker[type].active = nk_true;
   8110     if (type == NK_BUFFER_BACK)
   8111         buffer->marker[type].offset = buffer->size;
   8112     else buffer->marker[type].offset = buffer->allocated;
   8113 }
   8114 NK_API void
   8115 nk_buffer_reset(struct nk_buffer *buffer, enum nk_buffer_allocation_type type)
   8116 {
   8117     NK_ASSERT(buffer);
   8118     if (!buffer) return;
   8119     if (type == NK_BUFFER_BACK) {
   8120         /* reset back buffer either back to marker or empty */
   8121         buffer->needed -= (buffer->memory.size - buffer->marker[type].offset);
   8122         if (buffer->marker[type].active)
   8123             buffer->size = buffer->marker[type].offset;
   8124         else buffer->size = buffer->memory.size;
   8125         buffer->marker[type].active = nk_false;
   8126     } else {
   8127         /* reset front buffer either back to back marker or empty */
   8128         buffer->needed -= (buffer->allocated - buffer->marker[type].offset);
   8129         if (buffer->marker[type].active)
   8130             buffer->allocated = buffer->marker[type].offset;
   8131         else buffer->allocated = 0;
   8132         buffer->marker[type].active = nk_false;
   8133     }
   8134 }
   8135 NK_API void
   8136 nk_buffer_clear(struct nk_buffer *b)
   8137 {
   8138     NK_ASSERT(b);
   8139     if (!b) return;
   8140     b->allocated = 0;
   8141     b->size = b->memory.size;
   8142     b->calls = 0;
   8143     b->needed = 0;
   8144 }
   8145 NK_API void
   8146 nk_buffer_free(struct nk_buffer *b)
   8147 {
   8148     NK_ASSERT(b);
   8149     if (!b || !b->memory.ptr) return;
   8150     if (b->type == NK_BUFFER_FIXED) return;
   8151     if (!b->pool.free) return;
   8152     NK_ASSERT(b->pool.free);
   8153     b->pool.free(b->pool.userdata, b->memory.ptr);
   8154 }
   8155 NK_API void
   8156 nk_buffer_info(struct nk_memory_status *s, struct nk_buffer *b)
   8157 {
   8158     NK_ASSERT(b);
   8159     NK_ASSERT(s);
   8160     if (!s || !b) return;
   8161     s->allocated = b->allocated;
   8162     s->size =  b->memory.size;
   8163     s->needed = b->needed;
   8164     s->memory = b->memory.ptr;
   8165     s->calls = b->calls;
   8166 }
   8167 NK_API void*
   8168 nk_buffer_memory(struct nk_buffer *buffer)
   8169 {
   8170     NK_ASSERT(buffer);
   8171     if (!buffer) return 0;
   8172     return buffer->memory.ptr;
   8173 }
   8174 NK_API const void*
   8175 nk_buffer_memory_const(const struct nk_buffer *buffer)
   8176 {
   8177     NK_ASSERT(buffer);
   8178     if (!buffer) return 0;
   8179     return buffer->memory.ptr;
   8180 }
   8181 NK_API nk_size
   8182 nk_buffer_total(struct nk_buffer *buffer)
   8183 {
   8184     NK_ASSERT(buffer);
   8185     if (!buffer) return 0;
   8186     return buffer->memory.size;
   8187 }
   8188 
   8189 
   8190 
   8191 
   8192 
   8193 /* ===============================================================
   8194  *
   8195  *                              STRING
   8196  *
   8197  * ===============================================================*/
   8198 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
   8199 NK_API void
   8200 nk_str_init_default(struct nk_str *str)
   8201 {
   8202     struct nk_allocator alloc;
   8203     alloc.userdata.ptr = 0;
   8204     alloc.alloc = nk_malloc;
   8205     alloc.free = nk_mfree;
   8206     nk_buffer_init(&str->buffer, &alloc, 32);
   8207     str->len = 0;
   8208 }
   8209 #endif
   8210 
   8211 NK_API void
   8212 nk_str_init(struct nk_str *str, const struct nk_allocator *alloc, nk_size size)
   8213 {
   8214     nk_buffer_init(&str->buffer, alloc, size);
   8215     str->len = 0;
   8216 }
   8217 NK_API void
   8218 nk_str_init_fixed(struct nk_str *str, void *memory, nk_size size)
   8219 {
   8220     nk_buffer_init_fixed(&str->buffer, memory, size);
   8221     str->len = 0;
   8222 }
   8223 NK_API int
   8224 nk_str_append_text_char(struct nk_str *s, const char *str, int len)
   8225 {
   8226     char *mem;
   8227     NK_ASSERT(s);
   8228     NK_ASSERT(str);
   8229     if (!s || !str || !len) return 0;
   8230     mem = (char*)nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len * sizeof(char), 0);
   8231     if (!mem) return 0;
   8232     NK_MEMCPY(mem, str, (nk_size)len * sizeof(char));
   8233     s->len += nk_utf_len(str, len);
   8234     return len;
   8235 }
   8236 NK_API int
   8237 nk_str_append_str_char(struct nk_str *s, const char *str)
   8238 {
   8239     return nk_str_append_text_char(s, str, nk_strlen(str));
   8240 }
   8241 NK_API int
   8242 nk_str_append_text_utf8(struct nk_str *str, const char *text, int len)
   8243 {
   8244     int i = 0;
   8245     int byte_len = 0;
   8246     nk_rune unicode;
   8247     if (!str || !text || !len) return 0;
   8248     for (i = 0; i < len; ++i)
   8249         byte_len += nk_utf_decode(text+byte_len, &unicode, 4);
   8250     nk_str_append_text_char(str, text, byte_len);
   8251     return len;
   8252 }
   8253 NK_API int
   8254 nk_str_append_str_utf8(struct nk_str *str, const char *text)
   8255 {
   8256     int runes = 0;
   8257     int byte_len = 0;
   8258     int num_runes = 0;
   8259     int glyph_len = 0;
   8260     nk_rune unicode;
   8261     if (!str || !text) return 0;
   8262 
   8263     glyph_len = byte_len = nk_utf_decode(text+byte_len, &unicode, 4);
   8264     while (unicode != '\0' && glyph_len) {
   8265         glyph_len = nk_utf_decode(text+byte_len, &unicode, 4);
   8266         byte_len += glyph_len;
   8267         num_runes++;
   8268     }
   8269     nk_str_append_text_char(str, text, byte_len);
   8270     return runes;
   8271 }
   8272 NK_API int
   8273 nk_str_append_text_runes(struct nk_str *str, const nk_rune *text, int len)
   8274 {
   8275     int i = 0;
   8276     int byte_len = 0;
   8277     nk_glyph glyph;
   8278 
   8279     NK_ASSERT(str);
   8280     if (!str || !text || !len) return 0;
   8281     for (i = 0; i < len; ++i) {
   8282         byte_len = nk_utf_encode(text[i], glyph, NK_UTF_SIZE);
   8283         if (!byte_len) break;
   8284         nk_str_append_text_char(str, glyph, byte_len);
   8285     }
   8286     return len;
   8287 }
   8288 NK_API int
   8289 nk_str_append_str_runes(struct nk_str *str, const nk_rune *runes)
   8290 {
   8291     int i = 0;
   8292     nk_glyph glyph;
   8293     int byte_len;
   8294     NK_ASSERT(str);
   8295     if (!str || !runes) return 0;
   8296     while (runes[i] != '\0') {
   8297         byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE);
   8298         nk_str_append_text_char(str, glyph, byte_len);
   8299         i++;
   8300     }
   8301     return i;
   8302 }
   8303 NK_API int
   8304 nk_str_insert_at_char(struct nk_str *s, int pos, const char *str, int len)
   8305 {
   8306     int i;
   8307     void *mem;
   8308     char *src;
   8309     char *dst;
   8310 
   8311     int copylen;
   8312     NK_ASSERT(s);
   8313     NK_ASSERT(str);
   8314     NK_ASSERT(len >= 0);
   8315     if (!s || !str || !len || (nk_size)pos > s->buffer.allocated) return 0;
   8316     if ((s->buffer.allocated + (nk_size)len >= s->buffer.memory.size) &&
   8317         (s->buffer.type == NK_BUFFER_FIXED)) return 0;
   8318 
   8319     copylen = (int)s->buffer.allocated - pos;
   8320     if (!copylen) {
   8321         nk_str_append_text_char(s, str, len);
   8322         return 1;
   8323     }
   8324     mem = nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len * sizeof(char), 0);
   8325     if (!mem) return 0;
   8326 
   8327     /* memmove */
   8328     NK_ASSERT(((int)pos + (int)len + ((int)copylen - 1)) >= 0);
   8329     NK_ASSERT(((int)pos + ((int)copylen - 1)) >= 0);
   8330     dst = nk_ptr_add(char, s->buffer.memory.ptr, pos + len + (copylen - 1));
   8331     src = nk_ptr_add(char, s->buffer.memory.ptr, pos + (copylen-1));
   8332     for (i = 0; i < copylen; ++i) *dst-- = *src--;
   8333     mem = nk_ptr_add(void, s->buffer.memory.ptr, pos);
   8334     NK_MEMCPY(mem, str, (nk_size)len * sizeof(char));
   8335     s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated);
   8336     return 1;
   8337 }
   8338 NK_API int
   8339 nk_str_insert_at_rune(struct nk_str *str, int pos, const char *cstr, int len)
   8340 {
   8341     int glyph_len;
   8342     nk_rune unicode;
   8343     const char *begin;
   8344     const char *buffer;
   8345 
   8346     NK_ASSERT(str);
   8347     NK_ASSERT(cstr);
   8348     NK_ASSERT(len);
   8349     if (!str || !cstr || !len) return 0;
   8350     begin = nk_str_at_rune(str, pos, &unicode, &glyph_len);
   8351     if (!str->len)
   8352         return nk_str_append_text_char(str, cstr, len);
   8353     buffer = nk_str_get_const(str);
   8354     if (!begin) return 0;
   8355     return nk_str_insert_at_char(str, (int)(begin - buffer), cstr, len);
   8356 }
   8357 NK_API int
   8358 nk_str_insert_text_char(struct nk_str *str, int pos, const char *text, int len)
   8359 {
   8360     return nk_str_insert_text_utf8(str, pos, text, len);
   8361 }
   8362 NK_API int
   8363 nk_str_insert_str_char(struct nk_str *str, int pos, const char *text)
   8364 {
   8365     return nk_str_insert_text_utf8(str, pos, text, nk_strlen(text));
   8366 }
   8367 NK_API int
   8368 nk_str_insert_text_utf8(struct nk_str *str, int pos, const char *text, int len)
   8369 {
   8370     int i = 0;
   8371     int byte_len = 0;
   8372     nk_rune unicode;
   8373 
   8374     NK_ASSERT(str);
   8375     NK_ASSERT(text);
   8376     if (!str || !text || !len) return 0;
   8377     for (i = 0; i < len; ++i)
   8378         byte_len += nk_utf_decode(text+byte_len, &unicode, 4);
   8379     nk_str_insert_at_rune(str, pos, text, byte_len);
   8380     return len;
   8381 }
   8382 NK_API int
   8383 nk_str_insert_str_utf8(struct nk_str *str, int pos, const char *text)
   8384 {
   8385     int runes = 0;
   8386     int byte_len = 0;
   8387     int num_runes = 0;
   8388     int glyph_len = 0;
   8389     nk_rune unicode;
   8390     if (!str || !text) return 0;
   8391 
   8392     glyph_len = byte_len = nk_utf_decode(text+byte_len, &unicode, 4);
   8393     while (unicode != '\0' && glyph_len) {
   8394         glyph_len = nk_utf_decode(text+byte_len, &unicode, 4);
   8395         byte_len += glyph_len;
   8396         num_runes++;
   8397     }
   8398     nk_str_insert_at_rune(str, pos, text, byte_len);
   8399     return runes;
   8400 }
   8401 NK_API int
   8402 nk_str_insert_text_runes(struct nk_str *str, int pos, const nk_rune *runes, int len)
   8403 {
   8404     int i = 0;
   8405     int byte_len = 0;
   8406     nk_glyph glyph;
   8407 
   8408     NK_ASSERT(str);
   8409     if (!str || !runes || !len) return 0;
   8410     for (i = 0; i < len; ++i) {
   8411         byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE);
   8412         if (!byte_len) break;
   8413         nk_str_insert_at_rune(str, pos+i, glyph, byte_len);
   8414     }
   8415     return len;
   8416 }
   8417 NK_API int
   8418 nk_str_insert_str_runes(struct nk_str *str, int pos, const nk_rune *runes)
   8419 {
   8420     int i = 0;
   8421     nk_glyph glyph;
   8422     int byte_len;
   8423     NK_ASSERT(str);
   8424     if (!str || !runes) return 0;
   8425     while (runes[i] != '\0') {
   8426         byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE);
   8427         nk_str_insert_at_rune(str, pos+i, glyph, byte_len);
   8428         i++;
   8429     }
   8430     return i;
   8431 }
   8432 NK_API void
   8433 nk_str_remove_chars(struct nk_str *s, int len)
   8434 {
   8435     NK_ASSERT(s);
   8436     NK_ASSERT(len >= 0);
   8437     if (!s || len < 0 || (nk_size)len > s->buffer.allocated) return;
   8438     NK_ASSERT(((int)s->buffer.allocated - (int)len) >= 0);
   8439     s->buffer.allocated -= (nk_size)len;
   8440     s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated);
   8441 }
   8442 NK_API void
   8443 nk_str_remove_runes(struct nk_str *str, int len)
   8444 {
   8445     int index;
   8446     const char *begin;
   8447     const char *end;
   8448     nk_rune unicode;
   8449 
   8450     NK_ASSERT(str);
   8451     NK_ASSERT(len >= 0);
   8452     if (!str || len < 0) return;
   8453     if (len >= str->len) {
   8454         str->len = 0;
   8455         return;
   8456     }
   8457 
   8458     index = str->len - len;
   8459     begin = nk_str_at_rune(str, index, &unicode, &len);
   8460     end = (const char*)str->buffer.memory.ptr + str->buffer.allocated;
   8461     nk_str_remove_chars(str, (int)(end-begin)+1);
   8462 }
   8463 NK_API void
   8464 nk_str_delete_chars(struct nk_str *s, int pos, int len)
   8465 {
   8466     NK_ASSERT(s);
   8467     if (!s || !len || (nk_size)pos > s->buffer.allocated ||
   8468         (nk_size)(pos + len) > s->buffer.allocated) return;
   8469 
   8470     if ((nk_size)(pos + len) < s->buffer.allocated) {
   8471         /* memmove */
   8472         char *dst = nk_ptr_add(char, s->buffer.memory.ptr, pos);
   8473         char *src = nk_ptr_add(char, s->buffer.memory.ptr, pos + len);
   8474         NK_MEMCPY(dst, src, s->buffer.allocated - (nk_size)(pos + len));
   8475         NK_ASSERT(((int)s->buffer.allocated - (int)len) >= 0);
   8476         s->buffer.allocated -= (nk_size)len;
   8477     } else nk_str_remove_chars(s, len);
   8478     s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated);
   8479 }
   8480 NK_API void
   8481 nk_str_delete_runes(struct nk_str *s, int pos, int len)
   8482 {
   8483     char *temp;
   8484     nk_rune unicode;
   8485     char *begin;
   8486     char *end;
   8487     int unused;
   8488 
   8489     NK_ASSERT(s);
   8490     NK_ASSERT(s->len >= pos + len);
   8491     if (s->len < pos + len)
   8492         len = NK_CLAMP(0, (s->len - pos), s->len);
   8493     if (!len) return;
   8494 
   8495     temp = (char *)s->buffer.memory.ptr;
   8496     begin = nk_str_at_rune(s, pos, &unicode, &unused);
   8497     if (!begin) return;
   8498     s->buffer.memory.ptr = begin;
   8499     end = nk_str_at_rune(s, len, &unicode, &unused);
   8500     s->buffer.memory.ptr = temp;
   8501     if (!end) return;
   8502     nk_str_delete_chars(s, (int)(begin - temp), (int)(end - begin));
   8503 }
   8504 NK_API char*
   8505 nk_str_at_char(struct nk_str *s, int pos)
   8506 {
   8507     NK_ASSERT(s);
   8508     if (!s || pos > (int)s->buffer.allocated) return 0;
   8509     return nk_ptr_add(char, s->buffer.memory.ptr, pos);
   8510 }
   8511 NK_API char*
   8512 nk_str_at_rune(struct nk_str *str, int pos, nk_rune *unicode, int *len)
   8513 {
   8514     int i = 0;
   8515     int src_len = 0;
   8516     int glyph_len = 0;
   8517     char *text;
   8518     int text_len;
   8519 
   8520     NK_ASSERT(str);
   8521     NK_ASSERT(unicode);
   8522     NK_ASSERT(len);
   8523 
   8524     if (!str || !unicode || !len) return 0;
   8525     if (pos < 0) {
   8526         *unicode = 0;
   8527         *len = 0;
   8528         return 0;
   8529     }
   8530 
   8531     text = (char*)str->buffer.memory.ptr;
   8532     text_len = (int)str->buffer.allocated;
   8533     glyph_len = nk_utf_decode(text, unicode, text_len);
   8534     while (glyph_len) {
   8535         if (i == pos) {
   8536             *len = glyph_len;
   8537             break;
   8538         }
   8539 
   8540         i++;
   8541         src_len = src_len + glyph_len;
   8542         glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
   8543     }
   8544     if (i != pos) return 0;
   8545     return text + src_len;
   8546 }
   8547 NK_API const char*
   8548 nk_str_at_char_const(const struct nk_str *s, int pos)
   8549 {
   8550     NK_ASSERT(s);
   8551     if (!s || pos > (int)s->buffer.allocated) return 0;
   8552     return nk_ptr_add(char, s->buffer.memory.ptr, pos);
   8553 }
   8554 NK_API const char*
   8555 nk_str_at_const(const struct nk_str *str, int pos, nk_rune *unicode, int *len)
   8556 {
   8557     int i = 0;
   8558     int src_len = 0;
   8559     int glyph_len = 0;
   8560     char *text;
   8561     int text_len;
   8562 
   8563     NK_ASSERT(str);
   8564     NK_ASSERT(unicode);
   8565     NK_ASSERT(len);
   8566 
   8567     if (!str || !unicode || !len) return 0;
   8568     if (pos < 0) {
   8569         *unicode = 0;
   8570         *len = 0;
   8571         return 0;
   8572     }
   8573 
   8574     text = (char*)str->buffer.memory.ptr;
   8575     text_len = (int)str->buffer.allocated;
   8576     glyph_len = nk_utf_decode(text, unicode, text_len);
   8577     while (glyph_len) {
   8578         if (i == pos) {
   8579             *len = glyph_len;
   8580             break;
   8581         }
   8582 
   8583         i++;
   8584         src_len = src_len + glyph_len;
   8585         glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
   8586     }
   8587     if (i != pos) return 0;
   8588     return text + src_len;
   8589 }
   8590 NK_API nk_rune
   8591 nk_str_rune_at(const struct nk_str *str, int pos)
   8592 {
   8593     int len;
   8594     nk_rune unicode = 0;
   8595     nk_str_at_const(str, pos, &unicode, &len);
   8596     return unicode;
   8597 }
   8598 NK_API char*
   8599 nk_str_get(struct nk_str *s)
   8600 {
   8601     NK_ASSERT(s);
   8602     if (!s || !s->len || !s->buffer.allocated) return 0;
   8603     return (char*)s->buffer.memory.ptr;
   8604 }
   8605 NK_API const char*
   8606 nk_str_get_const(const struct nk_str *s)
   8607 {
   8608     NK_ASSERT(s);
   8609     if (!s || !s->len || !s->buffer.allocated) return 0;
   8610     return (const char*)s->buffer.memory.ptr;
   8611 }
   8612 NK_API int
   8613 nk_str_len(struct nk_str *s)
   8614 {
   8615     NK_ASSERT(s);
   8616     if (!s || !s->len || !s->buffer.allocated) return 0;
   8617     return s->len;
   8618 }
   8619 NK_API int
   8620 nk_str_len_char(struct nk_str *s)
   8621 {
   8622     NK_ASSERT(s);
   8623     if (!s || !s->len || !s->buffer.allocated) return 0;
   8624     return (int)s->buffer.allocated;
   8625 }
   8626 NK_API void
   8627 nk_str_clear(struct nk_str *str)
   8628 {
   8629     NK_ASSERT(str);
   8630     nk_buffer_clear(&str->buffer);
   8631     str->len = 0;
   8632 }
   8633 NK_API void
   8634 nk_str_free(struct nk_str *str)
   8635 {
   8636     NK_ASSERT(str);
   8637     nk_buffer_free(&str->buffer);
   8638     str->len = 0;
   8639 }
   8640 
   8641 
   8642 
   8643 
   8644 
   8645 /* ==============================================================
   8646  *
   8647  *                          DRAW
   8648  *
   8649  * ===============================================================*/
   8650 NK_LIB void
   8651 nk_command_buffer_init(struct nk_command_buffer *cb,
   8652     struct nk_buffer *b, enum nk_command_clipping clip)
   8653 {
   8654     NK_ASSERT(cb);
   8655     NK_ASSERT(b);
   8656     if (!cb || !b) return;
   8657     cb->base = b;
   8658     cb->use_clipping = (int)clip;
   8659     cb->begin = b->allocated;
   8660     cb->end = b->allocated;
   8661     cb->last = b->allocated;
   8662 }
   8663 NK_LIB void
   8664 nk_command_buffer_reset(struct nk_command_buffer *b)
   8665 {
   8666     NK_ASSERT(b);
   8667     if (!b) return;
   8668     b->begin = 0;
   8669     b->end = 0;
   8670     b->last = 0;
   8671     b->clip = nk_null_rect;
   8672 #ifdef NK_INCLUDE_COMMAND_USERDATA
   8673     b->userdata.ptr = 0;
   8674 #endif
   8675 }
   8676 NK_LIB void*
   8677 nk_command_buffer_push(struct nk_command_buffer* b,
   8678     enum nk_command_type t, nk_size size)
   8679 {
   8680     NK_STORAGE const nk_size align = NK_ALIGNOF(struct nk_command);
   8681     struct nk_command *cmd;
   8682     nk_size alignment;
   8683     void *unaligned;
   8684     void *memory;
   8685 
   8686     NK_ASSERT(b);
   8687     NK_ASSERT(b->base);
   8688     if (!b) return 0;
   8689     cmd = (struct nk_command*)nk_buffer_alloc(b->base,NK_BUFFER_FRONT,size,align);
   8690     if (!cmd) return 0;
   8691 
   8692     /* make sure the offset to the next command is aligned */
   8693     b->last = (nk_size)((nk_byte*)cmd - (nk_byte*)b->base->memory.ptr);
   8694     unaligned = (nk_byte*)cmd + size;
   8695     memory = NK_ALIGN_PTR(unaligned, align);
   8696     alignment = (nk_size)((nk_byte*)memory - (nk_byte*)unaligned);
   8697 #ifdef NK_ZERO_COMMAND_MEMORY
   8698     NK_MEMSET(cmd, 0, size + alignment);
   8699 #endif
   8700 
   8701     cmd->type = t;
   8702     cmd->next = b->base->allocated + alignment;
   8703 #ifdef NK_INCLUDE_COMMAND_USERDATA
   8704     cmd->userdata = b->userdata;
   8705 #endif
   8706     b->end = cmd->next;
   8707     return cmd;
   8708 }
   8709 NK_API void
   8710 nk_push_scissor(struct nk_command_buffer *b, struct nk_rect r)
   8711 {
   8712     struct nk_command_scissor *cmd;
   8713     NK_ASSERT(b);
   8714     if (!b) return;
   8715 
   8716     b->clip.x = r.x;
   8717     b->clip.y = r.y;
   8718     b->clip.w = r.w;
   8719     b->clip.h = r.h;
   8720     cmd = (struct nk_command_scissor*)
   8721         nk_command_buffer_push(b, NK_COMMAND_SCISSOR, sizeof(*cmd));
   8722 
   8723     if (!cmd) return;
   8724     cmd->x = (short)r.x;
   8725     cmd->y = (short)r.y;
   8726     cmd->w = (unsigned short)NK_MAX(0, r.w);
   8727     cmd->h = (unsigned short)NK_MAX(0, r.h);
   8728 }
   8729 NK_API void
   8730 nk_stroke_line(struct nk_command_buffer *b, float x0, float y0,
   8731     float x1, float y1, float line_thickness, struct nk_color c)
   8732 {
   8733     struct nk_command_line *cmd;
   8734     NK_ASSERT(b);
   8735     if (!b || line_thickness <= 0) return;
   8736     cmd = (struct nk_command_line*)
   8737         nk_command_buffer_push(b, NK_COMMAND_LINE, sizeof(*cmd));
   8738     if (!cmd) return;
   8739     cmd->line_thickness = (unsigned short)line_thickness;
   8740     cmd->begin.x = (short)x0;
   8741     cmd->begin.y = (short)y0;
   8742     cmd->end.x = (short)x1;
   8743     cmd->end.y = (short)y1;
   8744     cmd->color = c;
   8745 }
   8746 NK_API void
   8747 nk_stroke_curve(struct nk_command_buffer *b, float ax, float ay,
   8748     float ctrl0x, float ctrl0y, float ctrl1x, float ctrl1y,
   8749     float bx, float by, float line_thickness, struct nk_color col)
   8750 {
   8751     struct nk_command_curve *cmd;
   8752     NK_ASSERT(b);
   8753     if (!b || col.a == 0 || line_thickness <= 0) return;
   8754 
   8755     cmd = (struct nk_command_curve*)
   8756         nk_command_buffer_push(b, NK_COMMAND_CURVE, sizeof(*cmd));
   8757     if (!cmd) return;
   8758     cmd->line_thickness = (unsigned short)line_thickness;
   8759     cmd->begin.x = (short)ax;
   8760     cmd->begin.y = (short)ay;
   8761     cmd->ctrl[0].x = (short)ctrl0x;
   8762     cmd->ctrl[0].y = (short)ctrl0y;
   8763     cmd->ctrl[1].x = (short)ctrl1x;
   8764     cmd->ctrl[1].y = (short)ctrl1y;
   8765     cmd->end.x = (short)bx;
   8766     cmd->end.y = (short)by;
   8767     cmd->color = col;
   8768 }
   8769 NK_API void
   8770 nk_stroke_rect(struct nk_command_buffer *b, struct nk_rect rect,
   8771     float rounding, float line_thickness, struct nk_color c)
   8772 {
   8773     struct nk_command_rect *cmd;
   8774     NK_ASSERT(b);
   8775     if (!b || c.a == 0 || rect.w == 0 || rect.h == 0 || line_thickness <= 0) return;
   8776     if (b->use_clipping) {
   8777         const struct nk_rect *clip = &b->clip;
   8778         if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
   8779             clip->x, clip->y, clip->w, clip->h)) return;
   8780     }
   8781     cmd = (struct nk_command_rect*)
   8782         nk_command_buffer_push(b, NK_COMMAND_RECT, sizeof(*cmd));
   8783     if (!cmd) return;
   8784     cmd->rounding = (unsigned short)rounding;
   8785     cmd->line_thickness = (unsigned short)line_thickness;
   8786     cmd->x = (short)rect.x;
   8787     cmd->y = (short)rect.y;
   8788     cmd->w = (unsigned short)NK_MAX(0, rect.w);
   8789     cmd->h = (unsigned short)NK_MAX(0, rect.h);
   8790     cmd->color = c;
   8791 }
   8792 NK_API void
   8793 nk_fill_rect(struct nk_command_buffer *b, struct nk_rect rect,
   8794     float rounding, struct nk_color c)
   8795 {
   8796     struct nk_command_rect_filled *cmd;
   8797     NK_ASSERT(b);
   8798     if (!b || c.a == 0 || rect.w == 0 || rect.h == 0) return;
   8799     if (b->use_clipping) {
   8800         const struct nk_rect *clip = &b->clip;
   8801         if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
   8802             clip->x, clip->y, clip->w, clip->h)) return;
   8803     }
   8804 
   8805     cmd = (struct nk_command_rect_filled*)
   8806         nk_command_buffer_push(b, NK_COMMAND_RECT_FILLED, sizeof(*cmd));
   8807     if (!cmd) return;
   8808     cmd->rounding = (unsigned short)rounding;
   8809     cmd->x = (short)rect.x;
   8810     cmd->y = (short)rect.y;
   8811     cmd->w = (unsigned short)NK_MAX(0, rect.w);
   8812     cmd->h = (unsigned short)NK_MAX(0, rect.h);
   8813     cmd->color = c;
   8814 }
   8815 NK_API void
   8816 nk_fill_rect_multi_color(struct nk_command_buffer *b, struct nk_rect rect,
   8817     struct nk_color left, struct nk_color top, struct nk_color right,
   8818     struct nk_color bottom)
   8819 {
   8820     struct nk_command_rect_multi_color *cmd;
   8821     NK_ASSERT(b);
   8822     if (!b || rect.w == 0 || rect.h == 0) return;
   8823     if (b->use_clipping) {
   8824         const struct nk_rect *clip = &b->clip;
   8825         if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
   8826             clip->x, clip->y, clip->w, clip->h)) return;
   8827     }
   8828 
   8829     cmd = (struct nk_command_rect_multi_color*)
   8830         nk_command_buffer_push(b, NK_COMMAND_RECT_MULTI_COLOR, sizeof(*cmd));
   8831     if (!cmd) return;
   8832     cmd->x = (short)rect.x;
   8833     cmd->y = (short)rect.y;
   8834     cmd->w = (unsigned short)NK_MAX(0, rect.w);
   8835     cmd->h = (unsigned short)NK_MAX(0, rect.h);
   8836     cmd->left = left;
   8837     cmd->top = top;
   8838     cmd->right = right;
   8839     cmd->bottom = bottom;
   8840 }
   8841 NK_API void
   8842 nk_stroke_circle(struct nk_command_buffer *b, struct nk_rect r,
   8843     float line_thickness, struct nk_color c)
   8844 {
   8845     struct nk_command_circle *cmd;
   8846     if (!b || r.w == 0 || r.h == 0 || line_thickness <= 0) return;
   8847     if (b->use_clipping) {
   8848         const struct nk_rect *clip = &b->clip;
   8849         if (!NK_INTERSECT(r.x, r.y, r.w, r.h, clip->x, clip->y, clip->w, clip->h))
   8850             return;
   8851     }
   8852 
   8853     cmd = (struct nk_command_circle*)
   8854         nk_command_buffer_push(b, NK_COMMAND_CIRCLE, sizeof(*cmd));
   8855     if (!cmd) return;
   8856     cmd->line_thickness = (unsigned short)line_thickness;
   8857     cmd->x = (short)r.x;
   8858     cmd->y = (short)r.y;
   8859     cmd->w = (unsigned short)NK_MAX(r.w, 0);
   8860     cmd->h = (unsigned short)NK_MAX(r.h, 0);
   8861     cmd->color = c;
   8862 }
   8863 NK_API void
   8864 nk_fill_circle(struct nk_command_buffer *b, struct nk_rect r, struct nk_color c)
   8865 {
   8866     struct nk_command_circle_filled *cmd;
   8867     NK_ASSERT(b);
   8868     if (!b || c.a == 0 || r.w == 0 || r.h == 0) return;
   8869     if (b->use_clipping) {
   8870         const struct nk_rect *clip = &b->clip;
   8871         if (!NK_INTERSECT(r.x, r.y, r.w, r.h, clip->x, clip->y, clip->w, clip->h))
   8872             return;
   8873     }
   8874 
   8875     cmd = (struct nk_command_circle_filled*)
   8876         nk_command_buffer_push(b, NK_COMMAND_CIRCLE_FILLED, sizeof(*cmd));
   8877     if (!cmd) return;
   8878     cmd->x = (short)r.x;
   8879     cmd->y = (short)r.y;
   8880     cmd->w = (unsigned short)NK_MAX(r.w, 0);
   8881     cmd->h = (unsigned short)NK_MAX(r.h, 0);
   8882     cmd->color = c;
   8883 }
   8884 NK_API void
   8885 nk_stroke_arc(struct nk_command_buffer *b, float cx, float cy, float radius,
   8886     float a_min, float a_max, float line_thickness, struct nk_color c)
   8887 {
   8888     struct nk_command_arc *cmd;
   8889     if (!b || c.a == 0 || line_thickness <= 0) return;
   8890     cmd = (struct nk_command_arc*)
   8891         nk_command_buffer_push(b, NK_COMMAND_ARC, sizeof(*cmd));
   8892     if (!cmd) return;
   8893     cmd->line_thickness = (unsigned short)line_thickness;
   8894     cmd->cx = (short)cx;
   8895     cmd->cy = (short)cy;
   8896     cmd->r = (unsigned short)radius;
   8897     cmd->a[0] = a_min;
   8898     cmd->a[1] = a_max;
   8899     cmd->color = c;
   8900 }
   8901 NK_API void
   8902 nk_fill_arc(struct nk_command_buffer *b, float cx, float cy, float radius,
   8903     float a_min, float a_max, struct nk_color c)
   8904 {
   8905     struct nk_command_arc_filled *cmd;
   8906     NK_ASSERT(b);
   8907     if (!b || c.a == 0) return;
   8908     cmd = (struct nk_command_arc_filled*)
   8909         nk_command_buffer_push(b, NK_COMMAND_ARC_FILLED, sizeof(*cmd));
   8910     if (!cmd) return;
   8911     cmd->cx = (short)cx;
   8912     cmd->cy = (short)cy;
   8913     cmd->r = (unsigned short)radius;
   8914     cmd->a[0] = a_min;
   8915     cmd->a[1] = a_max;
   8916     cmd->color = c;
   8917 }
   8918 NK_API void
   8919 nk_stroke_triangle(struct nk_command_buffer *b, float x0, float y0, float x1,
   8920     float y1, float x2, float y2, float line_thickness, struct nk_color c)
   8921 {
   8922     struct nk_command_triangle *cmd;
   8923     NK_ASSERT(b);
   8924     if (!b || c.a == 0 || line_thickness <= 0) return;
   8925     if (b->use_clipping) {
   8926         const struct nk_rect *clip = &b->clip;
   8927         if (!NK_INBOX(x0, y0, clip->x, clip->y, clip->w, clip->h) &&
   8928             !NK_INBOX(x1, y1, clip->x, clip->y, clip->w, clip->h) &&
   8929             !NK_INBOX(x2, y2, clip->x, clip->y, clip->w, clip->h))
   8930             return;
   8931     }
   8932 
   8933     cmd = (struct nk_command_triangle*)
   8934         nk_command_buffer_push(b, NK_COMMAND_TRIANGLE, sizeof(*cmd));
   8935     if (!cmd) return;
   8936     cmd->line_thickness = (unsigned short)line_thickness;
   8937     cmd->a.x = (short)x0;
   8938     cmd->a.y = (short)y0;
   8939     cmd->b.x = (short)x1;
   8940     cmd->b.y = (short)y1;
   8941     cmd->c.x = (short)x2;
   8942     cmd->c.y = (short)y2;
   8943     cmd->color = c;
   8944 }
   8945 NK_API void
   8946 nk_fill_triangle(struct nk_command_buffer *b, float x0, float y0, float x1,
   8947     float y1, float x2, float y2, struct nk_color c)
   8948 {
   8949     struct nk_command_triangle_filled *cmd;
   8950     NK_ASSERT(b);
   8951     if (!b || c.a == 0) return;
   8952     if (!b) return;
   8953     if (b->use_clipping) {
   8954         const struct nk_rect *clip = &b->clip;
   8955         if (!NK_INBOX(x0, y0, clip->x, clip->y, clip->w, clip->h) &&
   8956             !NK_INBOX(x1, y1, clip->x, clip->y, clip->w, clip->h) &&
   8957             !NK_INBOX(x2, y2, clip->x, clip->y, clip->w, clip->h))
   8958             return;
   8959     }
   8960 
   8961     cmd = (struct nk_command_triangle_filled*)
   8962         nk_command_buffer_push(b, NK_COMMAND_TRIANGLE_FILLED, sizeof(*cmd));
   8963     if (!cmd) return;
   8964     cmd->a.x = (short)x0;
   8965     cmd->a.y = (short)y0;
   8966     cmd->b.x = (short)x1;
   8967     cmd->b.y = (short)y1;
   8968     cmd->c.x = (short)x2;
   8969     cmd->c.y = (short)y2;
   8970     cmd->color = c;
   8971 }
   8972 NK_API void
   8973 nk_stroke_polygon(struct nk_command_buffer *b,  float *points, int point_count,
   8974     float line_thickness, struct nk_color col)
   8975 {
   8976     int i;
   8977     nk_size size = 0;
   8978     struct nk_command_polygon *cmd;
   8979 
   8980     NK_ASSERT(b);
   8981     if (!b || col.a == 0 || line_thickness <= 0) return;
   8982     size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count;
   8983     cmd = (struct nk_command_polygon*) nk_command_buffer_push(b, NK_COMMAND_POLYGON, size);
   8984     if (!cmd) return;
   8985     cmd->color = col;
   8986     cmd->line_thickness = (unsigned short)line_thickness;
   8987     cmd->point_count = (unsigned short)point_count;
   8988     for (i = 0; i < point_count; ++i) {
   8989         cmd->points[i].x = (short)points[i*2];
   8990         cmd->points[i].y = (short)points[i*2+1];
   8991     }
   8992 }
   8993 NK_API void
   8994 nk_fill_polygon(struct nk_command_buffer *b, float *points, int point_count,
   8995     struct nk_color col)
   8996 {
   8997     int i;
   8998     nk_size size = 0;
   8999     struct nk_command_polygon_filled *cmd;
   9000 
   9001     NK_ASSERT(b);
   9002     if (!b || col.a == 0) return;
   9003     size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count;
   9004     cmd = (struct nk_command_polygon_filled*)
   9005         nk_command_buffer_push(b, NK_COMMAND_POLYGON_FILLED, size);
   9006     if (!cmd) return;
   9007     cmd->color = col;
   9008     cmd->point_count = (unsigned short)point_count;
   9009     for (i = 0; i < point_count; ++i) {
   9010         cmd->points[i].x = (short)points[i*2+0];
   9011         cmd->points[i].y = (short)points[i*2+1];
   9012     }
   9013 }
   9014 NK_API void
   9015 nk_stroke_polyline(struct nk_command_buffer *b, float *points, int point_count,
   9016     float line_thickness, struct nk_color col)
   9017 {
   9018     int i;
   9019     nk_size size = 0;
   9020     struct nk_command_polyline *cmd;
   9021 
   9022     NK_ASSERT(b);
   9023     if (!b || col.a == 0 || line_thickness <= 0) return;
   9024     size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count;
   9025     cmd = (struct nk_command_polyline*) nk_command_buffer_push(b, NK_COMMAND_POLYLINE, size);
   9026     if (!cmd) return;
   9027     cmd->color = col;
   9028     cmd->point_count = (unsigned short)point_count;
   9029     cmd->line_thickness = (unsigned short)line_thickness;
   9030     for (i = 0; i < point_count; ++i) {
   9031         cmd->points[i].x = (short)points[i*2];
   9032         cmd->points[i].y = (short)points[i*2+1];
   9033     }
   9034 }
   9035 NK_API void
   9036 nk_draw_image(struct nk_command_buffer *b, struct nk_rect r,
   9037     const struct nk_image *img, struct nk_color col)
   9038 {
   9039     struct nk_command_image *cmd;
   9040     NK_ASSERT(b);
   9041     if (!b) return;
   9042     if (b->use_clipping) {
   9043         const struct nk_rect *c = &b->clip;
   9044         if (c->w == 0 || c->h == 0 || !NK_INTERSECT(r.x, r.y, r.w, r.h, c->x, c->y, c->w, c->h))
   9045             return;
   9046     }
   9047 
   9048     cmd = (struct nk_command_image*)
   9049         nk_command_buffer_push(b, NK_COMMAND_IMAGE, sizeof(*cmd));
   9050     if (!cmd) return;
   9051     cmd->x = (short)r.x;
   9052     cmd->y = (short)r.y;
   9053     cmd->w = (unsigned short)NK_MAX(0, r.w);
   9054     cmd->h = (unsigned short)NK_MAX(0, r.h);
   9055     cmd->img = *img;
   9056     cmd->col = col;
   9057 }
   9058 NK_API void
   9059 nk_push_custom(struct nk_command_buffer *b, struct nk_rect r,
   9060     nk_command_custom_callback cb, nk_handle usr)
   9061 {
   9062     struct nk_command_custom *cmd;
   9063     NK_ASSERT(b);
   9064     if (!b) return;
   9065     if (b->use_clipping) {
   9066         const struct nk_rect *c = &b->clip;
   9067         if (c->w == 0 || c->h == 0 || !NK_INTERSECT(r.x, r.y, r.w, r.h, c->x, c->y, c->w, c->h))
   9068             return;
   9069     }
   9070 
   9071     cmd = (struct nk_command_custom*)
   9072         nk_command_buffer_push(b, NK_COMMAND_CUSTOM, sizeof(*cmd));
   9073     if (!cmd) return;
   9074     cmd->x = (short)r.x;
   9075     cmd->y = (short)r.y;
   9076     cmd->w = (unsigned short)NK_MAX(0, r.w);
   9077     cmd->h = (unsigned short)NK_MAX(0, r.h);
   9078     cmd->callback_data = usr;
   9079     cmd->callback = cb;
   9080 }
   9081 NK_API void
   9082 nk_draw_text(struct nk_command_buffer *b, struct nk_rect r,
   9083     const char *string, int length, const struct nk_user_font *font,
   9084     struct nk_color bg, struct nk_color fg)
   9085 {
   9086     float text_width = 0;
   9087     struct nk_command_text *cmd;
   9088 
   9089     NK_ASSERT(b);
   9090     NK_ASSERT(font);
   9091     if (!b || !string || !length || (bg.a == 0 && fg.a == 0)) return;
   9092     if (b->use_clipping) {
   9093         const struct nk_rect *c = &b->clip;
   9094         if (c->w == 0 || c->h == 0 || !NK_INTERSECT(r.x, r.y, r.w, r.h, c->x, c->y, c->w, c->h))
   9095             return;
   9096     }
   9097 
   9098     /* make sure text fits inside bounds */
   9099     text_width = font->width(font->userdata, font->height, string, length);
   9100     if (text_width > r.w){
   9101         int glyphs = 0;
   9102         float txt_width = (float)text_width;
   9103         length = nk_text_clamp(font, string, length, r.w, &glyphs, &txt_width, 0,0);
   9104     }
   9105 
   9106     if (!length) return;
   9107     cmd = (struct nk_command_text*)
   9108         nk_command_buffer_push(b, NK_COMMAND_TEXT, sizeof(*cmd) + (nk_size)(length + 1));
   9109     if (!cmd) return;
   9110     cmd->x = (short)r.x;
   9111     cmd->y = (short)r.y;
   9112     cmd->w = (unsigned short)r.w;
   9113     cmd->h = (unsigned short)r.h;
   9114     cmd->background = bg;
   9115     cmd->foreground = fg;
   9116     cmd->font = font;
   9117     cmd->length = length;
   9118     cmd->height = font->height;
   9119     NK_MEMCPY(cmd->string, string, (nk_size)length);
   9120     cmd->string[length] = '\0';
   9121 }
   9122 
   9123 
   9124 
   9125 
   9126 
   9127 /* ===============================================================
   9128  *
   9129  *                              VERTEX
   9130  *
   9131  * ===============================================================*/
   9132 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
   9133 NK_API void
   9134 nk_draw_list_init(struct nk_draw_list *list)
   9135 {
   9136     nk_size i = 0;
   9137     NK_ASSERT(list);
   9138     if (!list) return;
   9139     nk_zero(list, sizeof(*list));
   9140     for (i = 0; i < NK_LEN(list->circle_vtx); ++i) {
   9141         const float a = ((float)i / (float)NK_LEN(list->circle_vtx)) * 2 * NK_PI;
   9142         list->circle_vtx[i].x = (float)NK_COS(a);
   9143         list->circle_vtx[i].y = (float)NK_SIN(a);
   9144     }
   9145 }
   9146 NK_API void
   9147 nk_draw_list_setup(struct nk_draw_list *canvas, const struct nk_convert_config *config,
   9148     struct nk_buffer *cmds, struct nk_buffer *vertices, struct nk_buffer *elements,
   9149     enum nk_anti_aliasing line_aa, enum nk_anti_aliasing shape_aa)
   9150 {
   9151     NK_ASSERT(canvas);
   9152     NK_ASSERT(config);
   9153     NK_ASSERT(cmds);
   9154     NK_ASSERT(vertices);
   9155     NK_ASSERT(elements);
   9156     if (!canvas || !config || !cmds || !vertices || !elements)
   9157         return;
   9158 
   9159     canvas->buffer = cmds;
   9160     canvas->config = *config;
   9161     canvas->elements = elements;
   9162     canvas->vertices = vertices;
   9163     canvas->line_AA = line_aa;
   9164     canvas->shape_AA = shape_aa;
   9165     canvas->clip_rect = nk_null_rect;
   9166 
   9167     canvas->cmd_offset = 0;
   9168     canvas->element_count = 0;
   9169     canvas->vertex_count = 0;
   9170     canvas->cmd_offset = 0;
   9171     canvas->cmd_count = 0;
   9172     canvas->path_count = 0;
   9173 }
   9174 NK_API const struct nk_draw_command*
   9175 nk__draw_list_begin(const struct nk_draw_list *canvas, const struct nk_buffer *buffer)
   9176 {
   9177     nk_byte *memory;
   9178     nk_size offset;
   9179     const struct nk_draw_command *cmd;
   9180 
   9181     NK_ASSERT(buffer);
   9182     if (!buffer || !buffer->size || !canvas->cmd_count)
   9183         return 0;
   9184 
   9185     memory = (nk_byte*)buffer->memory.ptr;
   9186     offset = buffer->memory.size - canvas->cmd_offset;
   9187     cmd = nk_ptr_add(const struct nk_draw_command, memory, offset);
   9188     return cmd;
   9189 }
   9190 NK_API const struct nk_draw_command*
   9191 nk__draw_list_end(const struct nk_draw_list *canvas, const struct nk_buffer *buffer)
   9192 {
   9193     nk_size size;
   9194     nk_size offset;
   9195     nk_byte *memory;
   9196     const struct nk_draw_command *end;
   9197 
   9198     NK_ASSERT(buffer);
   9199     NK_ASSERT(canvas);
   9200     if (!buffer || !canvas)
   9201         return 0;
   9202 
   9203     memory = (nk_byte*)buffer->memory.ptr;
   9204     size = buffer->memory.size;
   9205     offset = size - canvas->cmd_offset;
   9206     end = nk_ptr_add(const struct nk_draw_command, memory, offset);
   9207     end -= (canvas->cmd_count-1);
   9208     return end;
   9209 }
   9210 NK_API const struct nk_draw_command*
   9211 nk__draw_list_next(const struct nk_draw_command *cmd,
   9212     const struct nk_buffer *buffer, const struct nk_draw_list *canvas)
   9213 {
   9214     const struct nk_draw_command *end;
   9215     NK_ASSERT(buffer);
   9216     NK_ASSERT(canvas);
   9217     if (!cmd || !buffer || !canvas)
   9218         return 0;
   9219 
   9220     end = nk__draw_list_end(canvas, buffer);
   9221     if (cmd <= end) return 0;
   9222     return (cmd-1);
   9223 }
   9224 NK_INTERN struct nk_vec2*
   9225 nk_draw_list_alloc_path(struct nk_draw_list *list, int count)
   9226 {
   9227     struct nk_vec2 *points;
   9228     NK_STORAGE const nk_size point_align = NK_ALIGNOF(struct nk_vec2);
   9229     NK_STORAGE const nk_size point_size = sizeof(struct nk_vec2);
   9230     points = (struct nk_vec2*)
   9231         nk_buffer_alloc(list->buffer, NK_BUFFER_FRONT,
   9232                         point_size * (nk_size)count, point_align);
   9233 
   9234     if (!points) return 0;
   9235     if (!list->path_offset) {
   9236         void *memory = nk_buffer_memory(list->buffer);
   9237         list->path_offset = (unsigned int)((nk_byte*)points - (nk_byte*)memory);
   9238     }
   9239     list->path_count += (unsigned int)count;
   9240     return points;
   9241 }
   9242 NK_INTERN struct nk_vec2
   9243 nk_draw_list_path_last(struct nk_draw_list *list)
   9244 {
   9245     void *memory;
   9246     struct nk_vec2 *point;
   9247     NK_ASSERT(list->path_count);
   9248     memory = nk_buffer_memory(list->buffer);
   9249     point = nk_ptr_add(struct nk_vec2, memory, list->path_offset);
   9250     point += (list->path_count-1);
   9251     return *point;
   9252 }
   9253 NK_INTERN struct nk_draw_command*
   9254 nk_draw_list_push_command(struct nk_draw_list *list, struct nk_rect clip,
   9255     nk_handle texture)
   9256 {
   9257     NK_STORAGE const nk_size cmd_align = NK_ALIGNOF(struct nk_draw_command);
   9258     NK_STORAGE const nk_size cmd_size = sizeof(struct nk_draw_command);
   9259     struct nk_draw_command *cmd;
   9260 
   9261     NK_ASSERT(list);
   9262     cmd = (struct nk_draw_command*)
   9263         nk_buffer_alloc(list->buffer, NK_BUFFER_BACK, cmd_size, cmd_align);
   9264 
   9265     if (!cmd) return 0;
   9266     if (!list->cmd_count) {
   9267         nk_byte *memory = (nk_byte*)nk_buffer_memory(list->buffer);
   9268         nk_size total = nk_buffer_total(list->buffer);
   9269         memory = nk_ptr_add(nk_byte, memory, total);
   9270         list->cmd_offset = (nk_size)(memory - (nk_byte*)cmd);
   9271     }
   9272 
   9273     cmd->elem_count = 0;
   9274     cmd->clip_rect = clip;
   9275     cmd->texture = texture;
   9276 #ifdef NK_INCLUDE_COMMAND_USERDATA
   9277     cmd->userdata = list->userdata;
   9278 #endif
   9279 
   9280     list->cmd_count++;
   9281     list->clip_rect = clip;
   9282     return cmd;
   9283 }
   9284 NK_INTERN struct nk_draw_command*
   9285 nk_draw_list_command_last(struct nk_draw_list *list)
   9286 {
   9287     void *memory;
   9288     nk_size size;
   9289     struct nk_draw_command *cmd;
   9290     NK_ASSERT(list->cmd_count);
   9291 
   9292     memory = nk_buffer_memory(list->buffer);
   9293     size = nk_buffer_total(list->buffer);
   9294     cmd = nk_ptr_add(struct nk_draw_command, memory, size - list->cmd_offset);
   9295     return (cmd - (list->cmd_count-1));
   9296 }
   9297 NK_INTERN void
   9298 nk_draw_list_add_clip(struct nk_draw_list *list, struct nk_rect rect)
   9299 {
   9300     NK_ASSERT(list);
   9301     if (!list) return;
   9302     if (!list->cmd_count) {
   9303         nk_draw_list_push_command(list, rect, list->config.null.texture);
   9304     } else {
   9305         struct nk_draw_command *prev = nk_draw_list_command_last(list);
   9306         if (prev->elem_count == 0)
   9307             prev->clip_rect = rect;
   9308         nk_draw_list_push_command(list, rect, prev->texture);
   9309     }
   9310 }
   9311 NK_INTERN void
   9312 nk_draw_list_push_image(struct nk_draw_list *list, nk_handle texture)
   9313 {
   9314     NK_ASSERT(list);
   9315     if (!list) return;
   9316     if (!list->cmd_count) {
   9317         nk_draw_list_push_command(list, nk_null_rect, texture);
   9318     } else {
   9319         struct nk_draw_command *prev = nk_draw_list_command_last(list);
   9320         if (prev->elem_count == 0) {
   9321             prev->texture = texture;
   9322         #ifdef NK_INCLUDE_COMMAND_USERDATA
   9323             prev->userdata = list->userdata;
   9324         #endif
   9325     } else if (prev->texture.id != texture.id
   9326         #ifdef NK_INCLUDE_COMMAND_USERDATA
   9327             || prev->userdata.id != list->userdata.id
   9328         #endif
   9329         ) nk_draw_list_push_command(list, prev->clip_rect, texture);
   9330     }
   9331 }
   9332 #ifdef NK_INCLUDE_COMMAND_USERDATA
   9333 NK_API void
   9334 nk_draw_list_push_userdata(struct nk_draw_list *list, nk_handle userdata)
   9335 {
   9336     list->userdata = userdata;
   9337 }
   9338 #endif
   9339 NK_INTERN void*
   9340 nk_draw_list_alloc_vertices(struct nk_draw_list *list, nk_size count)
   9341 {
   9342     void *vtx;
   9343     NK_ASSERT(list);
   9344     if (!list) return 0;
   9345     vtx = nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT,
   9346         list->config.vertex_size*count, list->config.vertex_alignment);
   9347     if (!vtx) return 0;
   9348     list->vertex_count += (unsigned int)count;
   9349 
   9350     /* This assert triggers because your are drawing a lot of stuff and nuklear
   9351      * defined `nk_draw_index` as `nk_ushort` to safe space be default.
   9352      *
   9353      * So you reached the maximum number of indicies or rather vertexes.
   9354      * To solve this issue please change typdef `nk_draw_index` to `nk_uint`
   9355      * and don't forget to specify the new element size in your drawing
   9356      * backend (OpenGL, DirectX, ...). For example in OpenGL for `glDrawElements`
   9357      * instead of specifing `GL_UNSIGNED_SHORT` you have to define `GL_UNSIGNED_INT`.
   9358      * Sorry for the inconvenience. */
   9359     NK_ASSERT((sizeof(nk_draw_index) == 2 && list->vertex_count < NK_USHORT_MAX &&
   9360         "To many verticies for 16-bit vertex indicies. Please read comment above on how to solve this problem"));
   9361     return vtx;
   9362 }
   9363 NK_INTERN nk_draw_index*
   9364 nk_draw_list_alloc_elements(struct nk_draw_list *list, nk_size count)
   9365 {
   9366     nk_draw_index *ids;
   9367     struct nk_draw_command *cmd;
   9368     NK_STORAGE const nk_size elem_align = NK_ALIGNOF(nk_draw_index);
   9369     NK_STORAGE const nk_size elem_size = sizeof(nk_draw_index);
   9370     NK_ASSERT(list);
   9371     if (!list) return 0;
   9372 
   9373     ids = (nk_draw_index*)
   9374         nk_buffer_alloc(list->elements, NK_BUFFER_FRONT, elem_size*count, elem_align);
   9375     if (!ids) return 0;
   9376     cmd = nk_draw_list_command_last(list);
   9377     list->element_count += (unsigned int)count;
   9378     cmd->elem_count += (unsigned int)count;
   9379     return ids;
   9380 }
   9381 NK_INTERN int
   9382 nk_draw_vertex_layout_element_is_end_of_layout(
   9383     const struct nk_draw_vertex_layout_element *element)
   9384 {
   9385     return (element->attribute == NK_VERTEX_ATTRIBUTE_COUNT ||
   9386             element->format == NK_FORMAT_COUNT);
   9387 }
   9388 NK_INTERN void
   9389 nk_draw_vertex_color(void *attr, const float *vals,
   9390     enum nk_draw_vertex_layout_format format)
   9391 {
   9392     /* if this triggers you tried to provide a value format for a color */
   9393     float val[4];
   9394     NK_ASSERT(format >= NK_FORMAT_COLOR_BEGIN);
   9395     NK_ASSERT(format <= NK_FORMAT_COLOR_END);
   9396     if (format < NK_FORMAT_COLOR_BEGIN || format > NK_FORMAT_COLOR_END) return;
   9397 
   9398     val[0] = NK_SATURATE(vals[0]);
   9399     val[1] = NK_SATURATE(vals[1]);
   9400     val[2] = NK_SATURATE(vals[2]);
   9401     val[3] = NK_SATURATE(vals[3]);
   9402 
   9403     switch (format) {
   9404     default: NK_ASSERT(0 && "Invalid vertex layout color format"); break;
   9405     case NK_FORMAT_R8G8B8A8:
   9406     case NK_FORMAT_R8G8B8: {
   9407         struct nk_color col = nk_rgba_fv(val);
   9408         NK_MEMCPY(attr, &col.r, sizeof(col));
   9409     } break;
   9410     case NK_FORMAT_B8G8R8A8: {
   9411         struct nk_color col = nk_rgba_fv(val);
   9412         struct nk_color bgra = nk_rgba(col.b, col.g, col.r, col.a);
   9413         NK_MEMCPY(attr, &bgra, sizeof(bgra));
   9414     } break;
   9415     case NK_FORMAT_R16G15B16: {
   9416         nk_ushort col[3];
   9417         col[0] = (nk_ushort)(val[0]*(float)NK_USHORT_MAX);
   9418         col[1] = (nk_ushort)(val[1]*(float)NK_USHORT_MAX);
   9419         col[2] = (nk_ushort)(val[2]*(float)NK_USHORT_MAX);
   9420         NK_MEMCPY(attr, col, sizeof(col));
   9421     } break;
   9422     case NK_FORMAT_R16G15B16A16: {
   9423         nk_ushort col[4];
   9424         col[0] = (nk_ushort)(val[0]*(float)NK_USHORT_MAX);
   9425         col[1] = (nk_ushort)(val[1]*(float)NK_USHORT_MAX);
   9426         col[2] = (nk_ushort)(val[2]*(float)NK_USHORT_MAX);
   9427         col[3] = (nk_ushort)(val[3]*(float)NK_USHORT_MAX);
   9428         NK_MEMCPY(attr, col, sizeof(col));
   9429     } break;
   9430     case NK_FORMAT_R32G32B32: {
   9431         nk_uint col[3];
   9432         col[0] = (nk_uint)(val[0]*(float)NK_UINT_MAX);
   9433         col[1] = (nk_uint)(val[1]*(float)NK_UINT_MAX);
   9434         col[2] = (nk_uint)(val[2]*(float)NK_UINT_MAX);
   9435         NK_MEMCPY(attr, col, sizeof(col));
   9436     } break;
   9437     case NK_FORMAT_R32G32B32A32: {
   9438         nk_uint col[4];
   9439         col[0] = (nk_uint)(val[0]*(float)NK_UINT_MAX);
   9440         col[1] = (nk_uint)(val[1]*(float)NK_UINT_MAX);
   9441         col[2] = (nk_uint)(val[2]*(float)NK_UINT_MAX);
   9442         col[3] = (nk_uint)(val[3]*(float)NK_UINT_MAX);
   9443         NK_MEMCPY(attr, col, sizeof(col));
   9444     } break;
   9445     case NK_FORMAT_R32G32B32A32_FLOAT:
   9446         NK_MEMCPY(attr, val, sizeof(float)*4);
   9447         break;
   9448     case NK_FORMAT_R32G32B32A32_DOUBLE: {
   9449         double col[4];
   9450         col[0] = (double)val[0];
   9451         col[1] = (double)val[1];
   9452         col[2] = (double)val[2];
   9453         col[3] = (double)val[3];
   9454         NK_MEMCPY(attr, col, sizeof(col));
   9455     } break;
   9456     case NK_FORMAT_RGB32:
   9457     case NK_FORMAT_RGBA32: {
   9458         struct nk_color col = nk_rgba_fv(val);
   9459         nk_uint color = nk_color_u32(col);
   9460         NK_MEMCPY(attr, &color, sizeof(color));
   9461     } break; }
   9462 }
   9463 NK_INTERN void
   9464 nk_draw_vertex_element(void *dst, const float *values, int value_count,
   9465     enum nk_draw_vertex_layout_format format)
   9466 {
   9467     int value_index;
   9468     void *attribute = dst;
   9469     /* if this triggers you tried to provide a color format for a value */
   9470     NK_ASSERT(format < NK_FORMAT_COLOR_BEGIN);
   9471     if (format >= NK_FORMAT_COLOR_BEGIN && format <= NK_FORMAT_COLOR_END) return;
   9472     for (value_index = 0; value_index < value_count; ++value_index) {
   9473         switch (format) {
   9474         default: NK_ASSERT(0 && "invalid vertex layout format"); break;
   9475         case NK_FORMAT_SCHAR: {
   9476             char value = (char)NK_CLAMP((float)NK_SCHAR_MIN, values[value_index], (float)NK_SCHAR_MAX);
   9477             NK_MEMCPY(attribute, &value, sizeof(value));
   9478             attribute = (void*)((char*)attribute + sizeof(char));
   9479         } break;
   9480         case NK_FORMAT_SSHORT: {
   9481             nk_short value = (nk_short)NK_CLAMP((float)NK_SSHORT_MIN, values[value_index], (float)NK_SSHORT_MAX);
   9482             NK_MEMCPY(attribute, &value, sizeof(value));
   9483             attribute = (void*)((char*)attribute + sizeof(value));
   9484         } break;
   9485         case NK_FORMAT_SINT: {
   9486             nk_int value = (nk_int)NK_CLAMP((float)NK_SINT_MIN, values[value_index], (float)NK_SINT_MAX);
   9487             NK_MEMCPY(attribute, &value, sizeof(value));
   9488             attribute = (void*)((char*)attribute + sizeof(nk_int));
   9489         } break;
   9490         case NK_FORMAT_UCHAR: {
   9491             unsigned char value = (unsigned char)NK_CLAMP((float)NK_UCHAR_MIN, values[value_index], (float)NK_UCHAR_MAX);
   9492             NK_MEMCPY(attribute, &value, sizeof(value));
   9493             attribute = (void*)((char*)attribute + sizeof(unsigned char));
   9494         } break;
   9495         case NK_FORMAT_USHORT: {
   9496             nk_ushort value = (nk_ushort)NK_CLAMP((float)NK_USHORT_MIN, values[value_index], (float)NK_USHORT_MAX);
   9497             NK_MEMCPY(attribute, &value, sizeof(value));
   9498             attribute = (void*)((char*)attribute + sizeof(value));
   9499             } break;
   9500         case NK_FORMAT_UINT: {
   9501             nk_uint value = (nk_uint)NK_CLAMP((float)NK_UINT_MIN, values[value_index], (float)NK_UINT_MAX);
   9502             NK_MEMCPY(attribute, &value, sizeof(value));
   9503             attribute = (void*)((char*)attribute + sizeof(nk_uint));
   9504         } break;
   9505         case NK_FORMAT_FLOAT:
   9506             NK_MEMCPY(attribute, &values[value_index], sizeof(values[value_index]));
   9507             attribute = (void*)((char*)attribute + sizeof(float));
   9508             break;
   9509         case NK_FORMAT_DOUBLE: {
   9510             double value = (double)values[value_index];
   9511             NK_MEMCPY(attribute, &value, sizeof(value));
   9512             attribute = (void*)((char*)attribute + sizeof(double));
   9513             } break;
   9514         }
   9515     }
   9516 }
   9517 NK_INTERN void*
   9518 nk_draw_vertex(void *dst, const struct nk_convert_config *config,
   9519     struct nk_vec2 pos, struct nk_vec2 uv, struct nk_colorf color)
   9520 {
   9521     void *result = (void*)((char*)dst + config->vertex_size);
   9522     const struct nk_draw_vertex_layout_element *elem_iter = config->vertex_layout;
   9523     while (!nk_draw_vertex_layout_element_is_end_of_layout(elem_iter)) {
   9524         void *address = (void*)((char*)dst + elem_iter->offset);
   9525         switch (elem_iter->attribute) {
   9526         case NK_VERTEX_ATTRIBUTE_COUNT:
   9527         default: NK_ASSERT(0 && "wrong element attribute"); break;
   9528         case NK_VERTEX_POSITION: nk_draw_vertex_element(address, &pos.x, 2, elem_iter->format); break;
   9529         case NK_VERTEX_TEXCOORD: nk_draw_vertex_element(address, &uv.x, 2, elem_iter->format); break;
   9530         case NK_VERTEX_COLOR: nk_draw_vertex_color(address, &color.r, elem_iter->format); break;
   9531         }
   9532         elem_iter++;
   9533     }
   9534     return result;
   9535 }
   9536 NK_API void
   9537 nk_draw_list_stroke_poly_line(struct nk_draw_list *list, const struct nk_vec2 *points,
   9538     const unsigned int points_count, struct nk_color color, enum nk_draw_list_stroke closed,
   9539     float thickness, enum nk_anti_aliasing aliasing)
   9540 {
   9541     nk_size count;
   9542     int thick_line;
   9543     struct nk_colorf col;
   9544     struct nk_colorf col_trans;
   9545     NK_ASSERT(list);
   9546     if (!list || points_count < 2) return;
   9547 
   9548     color.a = (nk_byte)((float)color.a * list->config.global_alpha);
   9549     count = points_count;
   9550     if (!closed) count = points_count-1;
   9551     thick_line = thickness > 1.0f;
   9552 
   9553 #ifdef NK_INCLUDE_COMMAND_USERDATA
   9554     nk_draw_list_push_userdata(list, list->userdata);
   9555 #endif
   9556 
   9557     color.a = (nk_byte)((float)color.a * list->config.global_alpha);
   9558     nk_color_fv(&col.r, color);
   9559     col_trans = col;
   9560     col_trans.a = 0;
   9561 
   9562     if (aliasing == NK_ANTI_ALIASING_ON) {
   9563         /* ANTI-ALIASED STROKE */
   9564         const float AA_SIZE = 1.0f;
   9565         NK_STORAGE const nk_size pnt_align = NK_ALIGNOF(struct nk_vec2);
   9566         NK_STORAGE const nk_size pnt_size = sizeof(struct nk_vec2);
   9567 
   9568         /* allocate vertices and elements  */
   9569         nk_size i1 = 0;
   9570         nk_size vertex_offset;
   9571         nk_size index = list->vertex_count;
   9572 
   9573         const nk_size idx_count = (thick_line) ?  (count * 18) : (count * 12);
   9574         const nk_size vtx_count = (thick_line) ? (points_count * 4): (points_count *3);
   9575 
   9576         void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
   9577         nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
   9578 
   9579         nk_size size;
   9580         struct nk_vec2 *normals, *temp;
   9581         if (!vtx || !ids) return;
   9582 
   9583         /* temporary allocate normals + points */
   9584         vertex_offset = (nk_size)((nk_byte*)vtx - (nk_byte*)list->vertices->memory.ptr);
   9585         nk_buffer_mark(list->vertices, NK_BUFFER_FRONT);
   9586         size = pnt_size * ((thick_line) ? 5 : 3) * points_count;
   9587         normals = (struct nk_vec2*) nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, size, pnt_align);
   9588         if (!normals) return;
   9589         temp = normals + points_count;
   9590 
   9591         /* make sure vertex pointer is still correct */
   9592         vtx = (void*)((nk_byte*)list->vertices->memory.ptr + vertex_offset);
   9593 
   9594         /* calculate normals */
   9595         for (i1 = 0; i1 < count; ++i1) {
   9596             const nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1);
   9597             struct nk_vec2 diff = nk_vec2_sub(points[i2], points[i1]);
   9598             float len;
   9599 
   9600             /* vec2 inverted length  */
   9601             len = nk_vec2_len_sqr(diff);
   9602             if (len != 0.0f)
   9603                 len = nk_inv_sqrt(len);
   9604             else len = 1.0f;
   9605 
   9606             diff = nk_vec2_muls(diff, len);
   9607             normals[i1].x = diff.y;
   9608             normals[i1].y = -diff.x;
   9609         }
   9610 
   9611         if (!closed)
   9612             normals[points_count-1] = normals[points_count-2];
   9613 
   9614         if (!thick_line) {
   9615             nk_size idx1, i;
   9616             if (!closed) {
   9617                 struct nk_vec2 d;
   9618                 temp[0] = nk_vec2_add(points[0], nk_vec2_muls(normals[0], AA_SIZE));
   9619                 temp[1] = nk_vec2_sub(points[0], nk_vec2_muls(normals[0], AA_SIZE));
   9620                 d = nk_vec2_muls(normals[points_count-1], AA_SIZE);
   9621                 temp[(points_count-1) * 2 + 0] = nk_vec2_add(points[points_count-1], d);
   9622                 temp[(points_count-1) * 2 + 1] = nk_vec2_sub(points[points_count-1], d);
   9623             }
   9624 
   9625             /* fill elements */
   9626             idx1 = index;
   9627             for (i1 = 0; i1 < count; i1++) {
   9628                 struct nk_vec2 dm;
   9629                 float dmr2;
   9630                 nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1);
   9631                 nk_size idx2 = ((i1+1) == points_count) ? index: (idx1 + 3);
   9632 
   9633                 /* average normals */
   9634                 dm = nk_vec2_muls(nk_vec2_add(normals[i1], normals[i2]), 0.5f);
   9635                 dmr2 = dm.x * dm.x + dm.y* dm.y;
   9636                 if (dmr2 > 0.000001f) {
   9637                     float scale = 1.0f/dmr2;
   9638                     scale = NK_MIN(100.0f, scale);
   9639                     dm = nk_vec2_muls(dm, scale);
   9640                 }
   9641 
   9642                 dm = nk_vec2_muls(dm, AA_SIZE);
   9643                 temp[i2*2+0] = nk_vec2_add(points[i2], dm);
   9644                 temp[i2*2+1] = nk_vec2_sub(points[i2], dm);
   9645 
   9646                 ids[0] = (nk_draw_index)(idx2 + 0); ids[1] = (nk_draw_index)(idx1+0);
   9647                 ids[2] = (nk_draw_index)(idx1 + 2); ids[3] = (nk_draw_index)(idx1+2);
   9648                 ids[4] = (nk_draw_index)(idx2 + 2); ids[5] = (nk_draw_index)(idx2+0);
   9649                 ids[6] = (nk_draw_index)(idx2 + 1); ids[7] = (nk_draw_index)(idx1+1);
   9650                 ids[8] = (nk_draw_index)(idx1 + 0); ids[9] = (nk_draw_index)(idx1+0);
   9651                 ids[10]= (nk_draw_index)(idx2 + 0); ids[11]= (nk_draw_index)(idx2+1);
   9652                 ids += 12;
   9653                 idx1 = idx2;
   9654             }
   9655 
   9656             /* fill vertices */
   9657             for (i = 0; i < points_count; ++i) {
   9658                 const struct nk_vec2 uv = list->config.null.uv;
   9659                 vtx = nk_draw_vertex(vtx, &list->config, points[i], uv, col);
   9660                 vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+0], uv, col_trans);
   9661                 vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+1], uv, col_trans);
   9662             }
   9663         } else {
   9664             nk_size idx1, i;
   9665             const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f;
   9666             if (!closed) {
   9667                 struct nk_vec2 d1 = nk_vec2_muls(normals[0], half_inner_thickness + AA_SIZE);
   9668                 struct nk_vec2 d2 = nk_vec2_muls(normals[0], half_inner_thickness);
   9669 
   9670                 temp[0] = nk_vec2_add(points[0], d1);
   9671                 temp[1] = nk_vec2_add(points[0], d2);
   9672                 temp[2] = nk_vec2_sub(points[0], d2);
   9673                 temp[3] = nk_vec2_sub(points[0], d1);
   9674 
   9675                 d1 = nk_vec2_muls(normals[points_count-1], half_inner_thickness + AA_SIZE);
   9676                 d2 = nk_vec2_muls(normals[points_count-1], half_inner_thickness);
   9677 
   9678                 temp[(points_count-1)*4+0] = nk_vec2_add(points[points_count-1], d1);
   9679                 temp[(points_count-1)*4+1] = nk_vec2_add(points[points_count-1], d2);
   9680                 temp[(points_count-1)*4+2] = nk_vec2_sub(points[points_count-1], d2);
   9681                 temp[(points_count-1)*4+3] = nk_vec2_sub(points[points_count-1], d1);
   9682             }
   9683 
   9684             /* add all elements */
   9685             idx1 = index;
   9686             for (i1 = 0; i1 < count; ++i1) {
   9687                 struct nk_vec2 dm_out, dm_in;
   9688                 const nk_size i2 = ((i1+1) == points_count) ? 0: (i1 + 1);
   9689                 nk_size idx2 = ((i1+1) == points_count) ? index: (idx1 + 4);
   9690 
   9691                 /* average normals */
   9692                 struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(normals[i1], normals[i2]), 0.5f);
   9693                 float dmr2 = dm.x * dm.x + dm.y* dm.y;
   9694                 if (dmr2 > 0.000001f) {
   9695                     float scale = 1.0f/dmr2;
   9696                     scale = NK_MIN(100.0f, scale);
   9697                     dm = nk_vec2_muls(dm, scale);
   9698                 }
   9699 
   9700                 dm_out = nk_vec2_muls(dm, ((half_inner_thickness) + AA_SIZE));
   9701                 dm_in = nk_vec2_muls(dm, half_inner_thickness);
   9702                 temp[i2*4+0] = nk_vec2_add(points[i2], dm_out);
   9703                 temp[i2*4+1] = nk_vec2_add(points[i2], dm_in);
   9704                 temp[i2*4+2] = nk_vec2_sub(points[i2], dm_in);
   9705                 temp[i2*4+3] = nk_vec2_sub(points[i2], dm_out);
   9706 
   9707                 /* add indexes */
   9708                 ids[0] = (nk_draw_index)(idx2 + 1); ids[1] = (nk_draw_index)(idx1+1);
   9709                 ids[2] = (nk_draw_index)(idx1 + 2); ids[3] = (nk_draw_index)(idx1+2);
   9710                 ids[4] = (nk_draw_index)(idx2 + 2); ids[5] = (nk_draw_index)(idx2+1);
   9711                 ids[6] = (nk_draw_index)(idx2 + 1); ids[7] = (nk_draw_index)(idx1+1);
   9712                 ids[8] = (nk_draw_index)(idx1 + 0); ids[9] = (nk_draw_index)(idx1+0);
   9713                 ids[10]= (nk_draw_index)(idx2 + 0); ids[11] = (nk_draw_index)(idx2+1);
   9714                 ids[12]= (nk_draw_index)(idx2 + 2); ids[13] = (nk_draw_index)(idx1+2);
   9715                 ids[14]= (nk_draw_index)(idx1 + 3); ids[15] = (nk_draw_index)(idx1+3);
   9716                 ids[16]= (nk_draw_index)(idx2 + 3); ids[17] = (nk_draw_index)(idx2+2);
   9717                 ids += 18;
   9718                 idx1 = idx2;
   9719             }
   9720 
   9721             /* add vertices */
   9722             for (i = 0; i < points_count; ++i) {
   9723                 const struct nk_vec2 uv = list->config.null.uv;
   9724                 vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+0], uv, col_trans);
   9725                 vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+1], uv, col);
   9726                 vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+2], uv, col);
   9727                 vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+3], uv, col_trans);
   9728             }
   9729         }
   9730         /* free temporary normals + points */
   9731         nk_buffer_reset(list->vertices, NK_BUFFER_FRONT);
   9732     } else {
   9733         /* NON ANTI-ALIASED STROKE */
   9734         nk_size i1 = 0;
   9735         nk_size idx = list->vertex_count;
   9736         const nk_size idx_count = count * 6;
   9737         const nk_size vtx_count = count * 4;
   9738         void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
   9739         nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
   9740         if (!vtx || !ids) return;
   9741 
   9742         for (i1 = 0; i1 < count; ++i1) {
   9743             float dx, dy;
   9744             const struct nk_vec2 uv = list->config.null.uv;
   9745             const nk_size i2 = ((i1+1) == points_count) ? 0 : i1 + 1;
   9746             const struct nk_vec2 p1 = points[i1];
   9747             const struct nk_vec2 p2 = points[i2];
   9748             struct nk_vec2 diff = nk_vec2_sub(p2, p1);
   9749             float len;
   9750 
   9751             /* vec2 inverted length  */
   9752             len = nk_vec2_len_sqr(diff);
   9753             if (len != 0.0f)
   9754                 len = nk_inv_sqrt(len);
   9755             else len = 1.0f;
   9756             diff = nk_vec2_muls(diff, len);
   9757 
   9758             /* add vertices */
   9759             dx = diff.x * (thickness * 0.5f);
   9760             dy = diff.y * (thickness * 0.5f);
   9761 
   9762             vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p1.x + dy, p1.y - dx), uv, col);
   9763             vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p2.x + dy, p2.y - dx), uv, col);
   9764             vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p2.x - dy, p2.y + dx), uv, col);
   9765             vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p1.x - dy, p1.y + dx), uv, col);
   9766 
   9767             ids[0] = (nk_draw_index)(idx+0); ids[1] = (nk_draw_index)(idx+1);
   9768             ids[2] = (nk_draw_index)(idx+2); ids[3] = (nk_draw_index)(idx+0);
   9769             ids[4] = (nk_draw_index)(idx+2); ids[5] = (nk_draw_index)(idx+3);
   9770 
   9771             ids += 6;
   9772             idx += 4;
   9773         }
   9774     }
   9775 }
   9776 NK_API void
   9777 nk_draw_list_fill_poly_convex(struct nk_draw_list *list,
   9778     const struct nk_vec2 *points, const unsigned int points_count,
   9779     struct nk_color color, enum nk_anti_aliasing aliasing)
   9780 {
   9781     struct nk_colorf col;
   9782     struct nk_colorf col_trans;
   9783 
   9784     NK_STORAGE const nk_size pnt_align = NK_ALIGNOF(struct nk_vec2);
   9785     NK_STORAGE const nk_size pnt_size = sizeof(struct nk_vec2);
   9786     NK_ASSERT(list);
   9787     if (!list || points_count < 3) return;
   9788 
   9789 #ifdef NK_INCLUDE_COMMAND_USERDATA
   9790     nk_draw_list_push_userdata(list, list->userdata);
   9791 #endif
   9792 
   9793     color.a = (nk_byte)((float)color.a * list->config.global_alpha);
   9794     nk_color_fv(&col.r, color);
   9795     col_trans = col;
   9796     col_trans.a = 0;
   9797 
   9798     if (aliasing == NK_ANTI_ALIASING_ON) {
   9799         nk_size i = 0;
   9800         nk_size i0 = 0;
   9801         nk_size i1 = 0;
   9802 
   9803         const float AA_SIZE = 1.0f;
   9804         nk_size vertex_offset = 0;
   9805         nk_size index = list->vertex_count;
   9806 
   9807         const nk_size idx_count = (points_count-2)*3 + points_count*6;
   9808         const nk_size vtx_count = (points_count*2);
   9809 
   9810         void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
   9811         nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
   9812 
   9813         nk_size size = 0;
   9814         struct nk_vec2 *normals = 0;
   9815         unsigned int vtx_inner_idx = (unsigned int)(index + 0);
   9816         unsigned int vtx_outer_idx = (unsigned int)(index + 1);
   9817         if (!vtx || !ids) return;
   9818 
   9819         /* temporary allocate normals */
   9820         vertex_offset = (nk_size)((nk_byte*)vtx - (nk_byte*)list->vertices->memory.ptr);
   9821         nk_buffer_mark(list->vertices, NK_BUFFER_FRONT);
   9822         size = pnt_size * points_count;
   9823         normals = (struct nk_vec2*) nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, size, pnt_align);
   9824         if (!normals) return;
   9825         vtx = (void*)((nk_byte*)list->vertices->memory.ptr + vertex_offset);
   9826 
   9827         /* add elements */
   9828         for (i = 2; i < points_count; i++) {
   9829             ids[0] = (nk_draw_index)(vtx_inner_idx);
   9830             ids[1] = (nk_draw_index)(vtx_inner_idx + ((i-1) << 1));
   9831             ids[2] = (nk_draw_index)(vtx_inner_idx + (i << 1));
   9832             ids += 3;
   9833         }
   9834 
   9835         /* compute normals */
   9836         for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) {
   9837             struct nk_vec2 p0 = points[i0];
   9838             struct nk_vec2 p1 = points[i1];
   9839             struct nk_vec2 diff = nk_vec2_sub(p1, p0);
   9840 
   9841             /* vec2 inverted length  */
   9842             float len = nk_vec2_len_sqr(diff);
   9843             if (len != 0.0f)
   9844                 len = nk_inv_sqrt(len);
   9845             else len = 1.0f;
   9846             diff = nk_vec2_muls(diff, len);
   9847 
   9848             normals[i0].x = diff.y;
   9849             normals[i0].y = -diff.x;
   9850         }
   9851 
   9852         /* add vertices + indexes */
   9853         for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) {
   9854             const struct nk_vec2 uv = list->config.null.uv;
   9855             struct nk_vec2 n0 = normals[i0];
   9856             struct nk_vec2 n1 = normals[i1];
   9857             struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(n0, n1), 0.5f);
   9858             float dmr2 = dm.x*dm.x + dm.y*dm.y;
   9859             if (dmr2 > 0.000001f) {
   9860                 float scale = 1.0f / dmr2;
   9861                 scale = NK_MIN(scale, 100.0f);
   9862                 dm = nk_vec2_muls(dm, scale);
   9863             }
   9864             dm = nk_vec2_muls(dm, AA_SIZE * 0.5f);
   9865 
   9866             /* add vertices */
   9867             vtx = nk_draw_vertex(vtx, &list->config, nk_vec2_sub(points[i1], dm), uv, col);
   9868             vtx = nk_draw_vertex(vtx, &list->config, nk_vec2_add(points[i1], dm), uv, col_trans);
   9869 
   9870             /* add indexes */
   9871             ids[0] = (nk_draw_index)(vtx_inner_idx+(i1<<1));
   9872             ids[1] = (nk_draw_index)(vtx_inner_idx+(i0<<1));
   9873             ids[2] = (nk_draw_index)(vtx_outer_idx+(i0<<1));
   9874             ids[3] = (nk_draw_index)(vtx_outer_idx+(i0<<1));
   9875             ids[4] = (nk_draw_index)(vtx_outer_idx+(i1<<1));
   9876             ids[5] = (nk_draw_index)(vtx_inner_idx+(i1<<1));
   9877             ids += 6;
   9878         }
   9879         /* free temporary normals + points */
   9880         nk_buffer_reset(list->vertices, NK_BUFFER_FRONT);
   9881     } else {
   9882         nk_size i = 0;
   9883         nk_size index = list->vertex_count;
   9884         const nk_size idx_count = (points_count-2)*3;
   9885         const nk_size vtx_count = points_count;
   9886         void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
   9887         nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
   9888 
   9889         if (!vtx || !ids) return;
   9890         for (i = 0; i < vtx_count; ++i)
   9891             vtx = nk_draw_vertex(vtx, &list->config, points[i], list->config.null.uv, col);
   9892         for (i = 2; i < points_count; ++i) {
   9893             ids[0] = (nk_draw_index)index;
   9894             ids[1] = (nk_draw_index)(index+ i - 1);
   9895             ids[2] = (nk_draw_index)(index+i);
   9896             ids += 3;
   9897         }
   9898     }
   9899 }
   9900 NK_API void
   9901 nk_draw_list_path_clear(struct nk_draw_list *list)
   9902 {
   9903     NK_ASSERT(list);
   9904     if (!list) return;
   9905     nk_buffer_reset(list->buffer, NK_BUFFER_FRONT);
   9906     list->path_count = 0;
   9907     list->path_offset = 0;
   9908 }
   9909 NK_API void
   9910 nk_draw_list_path_line_to(struct nk_draw_list *list, struct nk_vec2 pos)
   9911 {
   9912     struct nk_vec2 *points = 0;
   9913     struct nk_draw_command *cmd = 0;
   9914     NK_ASSERT(list);
   9915     if (!list) return;
   9916     if (!list->cmd_count)
   9917         nk_draw_list_add_clip(list, nk_null_rect);
   9918 
   9919     cmd = nk_draw_list_command_last(list);
   9920     if (cmd && cmd->texture.ptr != list->config.null.texture.ptr)
   9921         nk_draw_list_push_image(list, list->config.null.texture);
   9922 
   9923     points = nk_draw_list_alloc_path(list, 1);
   9924     if (!points) return;
   9925     points[0] = pos;
   9926 }
   9927 NK_API void
   9928 nk_draw_list_path_arc_to_fast(struct nk_draw_list *list, struct nk_vec2 center,
   9929     float radius, int a_min, int a_max)
   9930 {
   9931     int a = 0;
   9932     NK_ASSERT(list);
   9933     if (!list) return;
   9934     if (a_min <= a_max) {
   9935         for (a = a_min; a <= a_max; a++) {
   9936             const struct nk_vec2 c = list->circle_vtx[(nk_size)a % NK_LEN(list->circle_vtx)];
   9937             const float x = center.x + c.x * radius;
   9938             const float y = center.y + c.y * radius;
   9939             nk_draw_list_path_line_to(list, nk_vec2(x, y));
   9940         }
   9941     }
   9942 }
   9943 NK_API void
   9944 nk_draw_list_path_arc_to(struct nk_draw_list *list, struct nk_vec2 center,
   9945     float radius, float a_min, float a_max, unsigned int segments)
   9946 {
   9947     unsigned int i = 0;
   9948     NK_ASSERT(list);
   9949     if (!list) return;
   9950     if (radius == 0.0f) return;
   9951 
   9952     /*  This algorithm for arc drawing relies on these two trigonometric identities[1]:
   9953             sin(a + b) = sin(a) * cos(b) + cos(a) * sin(b)
   9954             cos(a + b) = cos(a) * cos(b) - sin(a) * sin(b)
   9955 
   9956         Two coordinates (x, y) of a point on a circle centered on
   9957         the origin can be written in polar form as:
   9958             x = r * cos(a)
   9959             y = r * sin(a)
   9960         where r is the radius of the circle,
   9961             a is the angle between (x, y) and the origin.
   9962 
   9963         This allows us to rotate the coordinates around the
   9964         origin by an angle b using the following transformation:
   9965             x' = r * cos(a + b) = x * cos(b) - y * sin(b)
   9966             y' = r * sin(a + b) = y * cos(b) + x * sin(b)
   9967 
   9968         [1] https://en.wikipedia.org/wiki/List_of_trigonometric_identities#Angle_sum_and_difference_identities
   9969     */
   9970     {const float d_angle = (a_max - a_min) / (float)segments;
   9971     const float sin_d = (float)NK_SIN(d_angle);
   9972     const float cos_d = (float)NK_COS(d_angle);
   9973 
   9974     float cx = (float)NK_COS(a_min) * radius;
   9975     float cy = (float)NK_SIN(a_min) * radius;
   9976     for(i = 0; i <= segments; ++i) {
   9977         float new_cx, new_cy;
   9978         const float x = center.x + cx;
   9979         const float y = center.y + cy;
   9980         nk_draw_list_path_line_to(list, nk_vec2(x, y));
   9981 
   9982         new_cx = cx * cos_d - cy * sin_d;
   9983         new_cy = cy * cos_d + cx * sin_d;
   9984         cx = new_cx;
   9985         cy = new_cy;
   9986     }}
   9987 }
   9988 NK_API void
   9989 nk_draw_list_path_rect_to(struct nk_draw_list *list, struct nk_vec2 a,
   9990     struct nk_vec2 b, float rounding)
   9991 {
   9992     float r;
   9993     NK_ASSERT(list);
   9994     if (!list) return;
   9995     r = rounding;
   9996     r = NK_MIN(r, ((b.x-a.x) < 0) ? -(b.x-a.x): (b.x-a.x));
   9997     r = NK_MIN(r, ((b.y-a.y) < 0) ? -(b.y-a.y): (b.y-a.y));
   9998 
   9999     if (r == 0.0f) {
  10000         nk_draw_list_path_line_to(list, a);
  10001         nk_draw_list_path_line_to(list, nk_vec2(b.x,a.y));
  10002         nk_draw_list_path_line_to(list, b);
  10003         nk_draw_list_path_line_to(list, nk_vec2(a.x,b.y));
  10004     } else {
  10005         nk_draw_list_path_arc_to_fast(list, nk_vec2(a.x + r, a.y + r), r, 6, 9);
  10006         nk_draw_list_path_arc_to_fast(list, nk_vec2(b.x - r, a.y + r), r, 9, 12);
  10007         nk_draw_list_path_arc_to_fast(list, nk_vec2(b.x - r, b.y - r), r, 0, 3);
  10008         nk_draw_list_path_arc_to_fast(list, nk_vec2(a.x + r, b.y - r), r, 3, 6);
  10009     }
  10010 }
  10011 NK_API void
  10012 nk_draw_list_path_curve_to(struct nk_draw_list *list, struct nk_vec2 p2,
  10013     struct nk_vec2 p3, struct nk_vec2 p4, unsigned int num_segments)
  10014 {
  10015     float t_step;
  10016     unsigned int i_step;
  10017     struct nk_vec2 p1;
  10018 
  10019     NK_ASSERT(list);
  10020     NK_ASSERT(list->path_count);
  10021     if (!list || !list->path_count) return;
  10022     num_segments = NK_MAX(num_segments, 1);
  10023 
  10024     p1 = nk_draw_list_path_last(list);
  10025     t_step = 1.0f/(float)num_segments;
  10026     for (i_step = 1; i_step <= num_segments; ++i_step) {
  10027         float t = t_step * (float)i_step;
  10028         float u = 1.0f - t;
  10029         float w1 = u*u*u;
  10030         float w2 = 3*u*u*t;
  10031         float w3 = 3*u*t*t;
  10032         float w4 = t * t *t;
  10033         float x = w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x;
  10034         float y = w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y;
  10035         nk_draw_list_path_line_to(list, nk_vec2(x,y));
  10036     }
  10037 }
  10038 NK_API void
  10039 nk_draw_list_path_fill(struct nk_draw_list *list, struct nk_color color)
  10040 {
  10041     struct nk_vec2 *points;
  10042     NK_ASSERT(list);
  10043     if (!list) return;
  10044     points = (struct nk_vec2*)nk_buffer_memory(list->buffer);
  10045     nk_draw_list_fill_poly_convex(list, points, list->path_count, color, list->config.shape_AA);
  10046     nk_draw_list_path_clear(list);
  10047 }
  10048 NK_API void
  10049 nk_draw_list_path_stroke(struct nk_draw_list *list, struct nk_color color,
  10050     enum nk_draw_list_stroke closed, float thickness)
  10051 {
  10052     struct nk_vec2 *points;
  10053     NK_ASSERT(list);
  10054     if (!list) return;
  10055     points = (struct nk_vec2*)nk_buffer_memory(list->buffer);
  10056     nk_draw_list_stroke_poly_line(list, points, list->path_count, color,
  10057         closed, thickness, list->config.line_AA);
  10058     nk_draw_list_path_clear(list);
  10059 }
  10060 NK_API void
  10061 nk_draw_list_stroke_line(struct nk_draw_list *list, struct nk_vec2 a,
  10062     struct nk_vec2 b, struct nk_color col, float thickness)
  10063 {
  10064     NK_ASSERT(list);
  10065     if (!list || !col.a) return;
  10066     if (list->line_AA == NK_ANTI_ALIASING_ON) {
  10067         nk_draw_list_path_line_to(list, a);
  10068         nk_draw_list_path_line_to(list, b);
  10069     } else {
  10070         nk_draw_list_path_line_to(list, nk_vec2_sub(a,nk_vec2(0.5f,0.5f)));
  10071         nk_draw_list_path_line_to(list, nk_vec2_sub(b,nk_vec2(0.5f,0.5f)));
  10072     }
  10073     nk_draw_list_path_stroke(list,  col, NK_STROKE_OPEN, thickness);
  10074 }
  10075 NK_API void
  10076 nk_draw_list_fill_rect(struct nk_draw_list *list, struct nk_rect rect,
  10077     struct nk_color col, float rounding)
  10078 {
  10079     NK_ASSERT(list);
  10080     if (!list || !col.a) return;
  10081 
  10082     if (list->line_AA == NK_ANTI_ALIASING_ON) {
  10083         nk_draw_list_path_rect_to(list, nk_vec2(rect.x, rect.y),
  10084             nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
  10085     } else {
  10086         nk_draw_list_path_rect_to(list, nk_vec2(rect.x-0.5f, rect.y-0.5f),
  10087             nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
  10088     } nk_draw_list_path_fill(list,  col);
  10089 }
  10090 NK_API void
  10091 nk_draw_list_stroke_rect(struct nk_draw_list *list, struct nk_rect rect,
  10092     struct nk_color col, float rounding, float thickness)
  10093 {
  10094     NK_ASSERT(list);
  10095     if (!list || !col.a) return;
  10096     if (list->line_AA == NK_ANTI_ALIASING_ON) {
  10097         nk_draw_list_path_rect_to(list, nk_vec2(rect.x, rect.y),
  10098             nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
  10099     } else {
  10100         nk_draw_list_path_rect_to(list, nk_vec2(rect.x-0.5f, rect.y-0.5f),
  10101             nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
  10102     } nk_draw_list_path_stroke(list,  col, NK_STROKE_CLOSED, thickness);
  10103 }
  10104 NK_API void
  10105 nk_draw_list_fill_rect_multi_color(struct nk_draw_list *list, struct nk_rect rect,
  10106     struct nk_color left, struct nk_color top, struct nk_color right,
  10107     struct nk_color bottom)
  10108 {
  10109     void *vtx;
  10110     struct nk_colorf col_left, col_top;
  10111     struct nk_colorf col_right, col_bottom;
  10112     nk_draw_index *idx;
  10113     nk_draw_index index;
  10114 
  10115     nk_color_fv(&col_left.r, left);
  10116     nk_color_fv(&col_right.r, right);
  10117     nk_color_fv(&col_top.r, top);
  10118     nk_color_fv(&col_bottom.r, bottom);
  10119 
  10120     NK_ASSERT(list);
  10121     if (!list) return;
  10122 
  10123     nk_draw_list_push_image(list, list->config.null.texture);
  10124     index = (nk_draw_index)list->vertex_count;
  10125     vtx = nk_draw_list_alloc_vertices(list, 4);
  10126     idx = nk_draw_list_alloc_elements(list, 6);
  10127     if (!vtx || !idx) return;
  10128 
  10129     idx[0] = (nk_draw_index)(index+0); idx[1] = (nk_draw_index)(index+1);
  10130     idx[2] = (nk_draw_index)(index+2); idx[3] = (nk_draw_index)(index+0);
  10131     idx[4] = (nk_draw_index)(index+2); idx[5] = (nk_draw_index)(index+3);
  10132 
  10133     vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x, rect.y), list->config.null.uv, col_left);
  10134     vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x + rect.w, rect.y), list->config.null.uv, col_top);
  10135     vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x + rect.w, rect.y + rect.h), list->config.null.uv, col_right);
  10136     vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x, rect.y + rect.h), list->config.null.uv, col_bottom);
  10137 }
  10138 NK_API void
  10139 nk_draw_list_fill_triangle(struct nk_draw_list *list, struct nk_vec2 a,
  10140     struct nk_vec2 b, struct nk_vec2 c, struct nk_color col)
  10141 {
  10142     NK_ASSERT(list);
  10143     if (!list || !col.a) return;
  10144     nk_draw_list_path_line_to(list, a);
  10145     nk_draw_list_path_line_to(list, b);
  10146     nk_draw_list_path_line_to(list, c);
  10147     nk_draw_list_path_fill(list, col);
  10148 }
  10149 NK_API void
  10150 nk_draw_list_stroke_triangle(struct nk_draw_list *list, struct nk_vec2 a,
  10151     struct nk_vec2 b, struct nk_vec2 c, struct nk_color col, float thickness)
  10152 {
  10153     NK_ASSERT(list);
  10154     if (!list || !col.a) return;
  10155     nk_draw_list_path_line_to(list, a);
  10156     nk_draw_list_path_line_to(list, b);
  10157     nk_draw_list_path_line_to(list, c);
  10158     nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
  10159 }
  10160 NK_API void
  10161 nk_draw_list_fill_circle(struct nk_draw_list *list, struct nk_vec2 center,
  10162     float radius, struct nk_color col, unsigned int segs)
  10163 {
  10164     float a_max;
  10165     NK_ASSERT(list);
  10166     if (!list || !col.a) return;
  10167     a_max = NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs;
  10168     nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs);
  10169     nk_draw_list_path_fill(list, col);
  10170 }
  10171 NK_API void
  10172 nk_draw_list_stroke_circle(struct nk_draw_list *list, struct nk_vec2 center,
  10173     float radius, struct nk_color col, unsigned int segs, float thickness)
  10174 {
  10175     float a_max;
  10176     NK_ASSERT(list);
  10177     if (!list || !col.a) return;
  10178     a_max = NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs;
  10179     nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs);
  10180     nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
  10181 }
  10182 NK_API void
  10183 nk_draw_list_stroke_curve(struct nk_draw_list *list, struct nk_vec2 p0,
  10184     struct nk_vec2 cp0, struct nk_vec2 cp1, struct nk_vec2 p1,
  10185     struct nk_color col, unsigned int segments, float thickness)
  10186 {
  10187     NK_ASSERT(list);
  10188     if (!list || !col.a) return;
  10189     nk_draw_list_path_line_to(list, p0);
  10190     nk_draw_list_path_curve_to(list, cp0, cp1, p1, segments);
  10191     nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness);
  10192 }
  10193 NK_INTERN void
  10194 nk_draw_list_push_rect_uv(struct nk_draw_list *list, struct nk_vec2 a,
  10195     struct nk_vec2 c, struct nk_vec2 uva, struct nk_vec2 uvc,
  10196     struct nk_color color)
  10197 {
  10198     void *vtx;
  10199     struct nk_vec2 uvb;
  10200     struct nk_vec2 uvd;
  10201     struct nk_vec2 b;
  10202     struct nk_vec2 d;
  10203 
  10204     struct nk_colorf col;
  10205     nk_draw_index *idx;
  10206     nk_draw_index index;
  10207     NK_ASSERT(list);
  10208     if (!list) return;
  10209 
  10210     nk_color_fv(&col.r, color);
  10211     uvb = nk_vec2(uvc.x, uva.y);
  10212     uvd = nk_vec2(uva.x, uvc.y);
  10213     b = nk_vec2(c.x, a.y);
  10214     d = nk_vec2(a.x, c.y);
  10215 
  10216     index = (nk_draw_index)list->vertex_count;
  10217     vtx = nk_draw_list_alloc_vertices(list, 4);
  10218     idx = nk_draw_list_alloc_elements(list, 6);
  10219     if (!vtx || !idx) return;
  10220 
  10221     idx[0] = (nk_draw_index)(index+0); idx[1] = (nk_draw_index)(index+1);
  10222     idx[2] = (nk_draw_index)(index+2); idx[3] = (nk_draw_index)(index+0);
  10223     idx[4] = (nk_draw_index)(index+2); idx[5] = (nk_draw_index)(index+3);
  10224 
  10225     vtx = nk_draw_vertex(vtx, &list->config, a, uva, col);
  10226     vtx = nk_draw_vertex(vtx, &list->config, b, uvb, col);
  10227     vtx = nk_draw_vertex(vtx, &list->config, c, uvc, col);
  10228     vtx = nk_draw_vertex(vtx, &list->config, d, uvd, col);
  10229 }
  10230 NK_API void
  10231 nk_draw_list_add_image(struct nk_draw_list *list, struct nk_image texture,
  10232     struct nk_rect rect, struct nk_color color)
  10233 {
  10234     NK_ASSERT(list);
  10235     if (!list) return;
  10236     /* push new command with given texture */
  10237     nk_draw_list_push_image(list, texture.handle);
  10238     if (nk_image_is_subimage(&texture)) {
  10239         /* add region inside of the texture  */
  10240         struct nk_vec2 uv[2];
  10241         uv[0].x = (float)texture.region[0]/(float)texture.w;
  10242         uv[0].y = (float)texture.region[1]/(float)texture.h;
  10243         uv[1].x = (float)(texture.region[0] + texture.region[2])/(float)texture.w;
  10244         uv[1].y = (float)(texture.region[1] + texture.region[3])/(float)texture.h;
  10245         nk_draw_list_push_rect_uv(list, nk_vec2(rect.x, rect.y),
  10246             nk_vec2(rect.x + rect.w, rect.y + rect.h),  uv[0], uv[1], color);
  10247     } else nk_draw_list_push_rect_uv(list, nk_vec2(rect.x, rect.y),
  10248             nk_vec2(rect.x + rect.w, rect.y + rect.h),
  10249             nk_vec2(0.0f, 0.0f), nk_vec2(1.0f, 1.0f),color);
  10250 }
  10251 NK_API void
  10252 nk_draw_list_add_text(struct nk_draw_list *list, const struct nk_user_font *font,
  10253     struct nk_rect rect, const char *text, int len, float font_height,
  10254     struct nk_color fg)
  10255 {
  10256     float x = 0;
  10257     int text_len = 0;
  10258     nk_rune unicode = 0;
  10259     nk_rune next = 0;
  10260     int glyph_len = 0;
  10261     int next_glyph_len = 0;
  10262     struct nk_user_font_glyph g;
  10263 
  10264     NK_ASSERT(list);
  10265     if (!list || !len || !text) return;
  10266     if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
  10267         list->clip_rect.x, list->clip_rect.y, list->clip_rect.w, list->clip_rect.h)) return;
  10268 
  10269     nk_draw_list_push_image(list, font->texture);
  10270     x = rect.x;
  10271     glyph_len = nk_utf_decode(text, &unicode, len);
  10272     if (!glyph_len) return;
  10273 
  10274     /* draw every glyph image */
  10275     fg.a = (nk_byte)((float)fg.a * list->config.global_alpha);
  10276     while (text_len < len && glyph_len) {
  10277         float gx, gy, gh, gw;
  10278         float char_width = 0;
  10279         if (unicode == NK_UTF_INVALID) break;
  10280 
  10281         /* query currently drawn glyph information */
  10282         next_glyph_len = nk_utf_decode(text + text_len + glyph_len, &next, (int)len - text_len);
  10283         font->query(font->userdata, font_height, &g, unicode,
  10284                     (next == NK_UTF_INVALID) ? '\0' : next);
  10285 
  10286         /* calculate and draw glyph drawing rectangle and image */
  10287         gx = x + g.offset.x;
  10288         gy = rect.y + g.offset.y;
  10289         gw = g.width; gh = g.height;
  10290         char_width = g.xadvance;
  10291         nk_draw_list_push_rect_uv(list, nk_vec2(gx,gy), nk_vec2(gx + gw, gy+ gh),
  10292             g.uv[0], g.uv[1], fg);
  10293 
  10294         /* offset next glyph */
  10295         text_len += glyph_len;
  10296         x += char_width;
  10297         glyph_len = next_glyph_len;
  10298         unicode = next;
  10299     }
  10300 }
  10301 NK_API nk_flags
  10302 nk_convert(struct nk_context *ctx, struct nk_buffer *cmds,
  10303     struct nk_buffer *vertices, struct nk_buffer *elements,
  10304     const struct nk_convert_config *config)
  10305 {
  10306     nk_flags res = NK_CONVERT_SUCCESS;
  10307     const struct nk_command *cmd;
  10308     NK_ASSERT(ctx);
  10309     NK_ASSERT(cmds);
  10310     NK_ASSERT(vertices);
  10311     NK_ASSERT(elements);
  10312     NK_ASSERT(config);
  10313     NK_ASSERT(config->vertex_layout);
  10314     NK_ASSERT(config->vertex_size);
  10315     if (!ctx || !cmds || !vertices || !elements || !config || !config->vertex_layout)
  10316         return NK_CONVERT_INVALID_PARAM;
  10317 
  10318     nk_draw_list_setup(&ctx->draw_list, config, cmds, vertices, elements,
  10319         config->line_AA, config->shape_AA);
  10320     nk_foreach(cmd, ctx)
  10321     {
  10322 #ifdef NK_INCLUDE_COMMAND_USERDATA
  10323         ctx->draw_list.userdata = cmd->userdata;
  10324 #endif
  10325         switch (cmd->type) {
  10326         case NK_COMMAND_NOP: break;
  10327         case NK_COMMAND_SCISSOR: {
  10328             const struct nk_command_scissor *s = (const struct nk_command_scissor*)cmd;
  10329             nk_draw_list_add_clip(&ctx->draw_list, nk_rect(s->x, s->y, s->w, s->h));
  10330         } break;
  10331         case NK_COMMAND_LINE: {
  10332             const struct nk_command_line *l = (const struct nk_command_line*)cmd;
  10333             nk_draw_list_stroke_line(&ctx->draw_list, nk_vec2(l->begin.x, l->begin.y),
  10334                 nk_vec2(l->end.x, l->end.y), l->color, l->line_thickness);
  10335         } break;
  10336         case NK_COMMAND_CURVE: {
  10337             const struct nk_command_curve *q = (const struct nk_command_curve*)cmd;
  10338             nk_draw_list_stroke_curve(&ctx->draw_list, nk_vec2(q->begin.x, q->begin.y),
  10339                 nk_vec2(q->ctrl[0].x, q->ctrl[0].y), nk_vec2(q->ctrl[1].x,
  10340                 q->ctrl[1].y), nk_vec2(q->end.x, q->end.y), q->color,
  10341                 config->curve_segment_count, q->line_thickness);
  10342         } break;
  10343         case NK_COMMAND_RECT: {
  10344             const struct nk_command_rect *r = (const struct nk_command_rect*)cmd;
  10345             nk_draw_list_stroke_rect(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h),
  10346                 r->color, (float)r->rounding, r->line_thickness);
  10347         } break;
  10348         case NK_COMMAND_RECT_FILLED: {
  10349             const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled*)cmd;
  10350             nk_draw_list_fill_rect(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h),
  10351                 r->color, (float)r->rounding);
  10352         } break;
  10353         case NK_COMMAND_RECT_MULTI_COLOR: {
  10354             const struct nk_command_rect_multi_color *r = (const struct nk_command_rect_multi_color*)cmd;
  10355             nk_draw_list_fill_rect_multi_color(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h),
  10356                 r->left, r->top, r->right, r->bottom);
  10357         } break;
  10358         case NK_COMMAND_CIRCLE: {
  10359             const struct nk_command_circle *c = (const struct nk_command_circle*)cmd;
  10360             nk_draw_list_stroke_circle(&ctx->draw_list, nk_vec2((float)c->x + (float)c->w/2,
  10361                 (float)c->y + (float)c->h/2), (float)c->w/2, c->color,
  10362                 config->circle_segment_count, c->line_thickness);
  10363         } break;
  10364         case NK_COMMAND_CIRCLE_FILLED: {
  10365             const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
  10366             nk_draw_list_fill_circle(&ctx->draw_list, nk_vec2((float)c->x + (float)c->w/2,
  10367                 (float)c->y + (float)c->h/2), (float)c->w/2, c->color,
  10368                 config->circle_segment_count);
  10369         } break;
  10370         case NK_COMMAND_ARC: {
  10371             const struct nk_command_arc *c = (const struct nk_command_arc*)cmd;
  10372             nk_draw_list_path_line_to(&ctx->draw_list, nk_vec2(c->cx, c->cy));
  10373             nk_draw_list_path_arc_to(&ctx->draw_list, nk_vec2(c->cx, c->cy), c->r,
  10374                 c->a[0], c->a[1], config->arc_segment_count);
  10375             nk_draw_list_path_stroke(&ctx->draw_list, c->color, NK_STROKE_CLOSED, c->line_thickness);
  10376         } break;
  10377         case NK_COMMAND_ARC_FILLED: {
  10378             const struct nk_command_arc_filled *c = (const struct nk_command_arc_filled*)cmd;
  10379             nk_draw_list_path_line_to(&ctx->draw_list, nk_vec2(c->cx, c->cy));
  10380             nk_draw_list_path_arc_to(&ctx->draw_list, nk_vec2(c->cx, c->cy), c->r,
  10381                 c->a[0], c->a[1], config->arc_segment_count);
  10382             nk_draw_list_path_fill(&ctx->draw_list, c->color);
  10383         } break;
  10384         case NK_COMMAND_TRIANGLE: {
  10385             const struct nk_command_triangle *t = (const struct nk_command_triangle*)cmd;
  10386             nk_draw_list_stroke_triangle(&ctx->draw_list, nk_vec2(t->a.x, t->a.y),
  10387                 nk_vec2(t->b.x, t->b.y), nk_vec2(t->c.x, t->c.y), t->color,
  10388                 t->line_thickness);
  10389         } break;
  10390         case NK_COMMAND_TRIANGLE_FILLED: {
  10391             const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled*)cmd;
  10392             nk_draw_list_fill_triangle(&ctx->draw_list, nk_vec2(t->a.x, t->a.y),
  10393                 nk_vec2(t->b.x, t->b.y), nk_vec2(t->c.x, t->c.y), t->color);
  10394         } break;
  10395         case NK_COMMAND_POLYGON: {
  10396             int i;
  10397             const struct nk_command_polygon*p = (const struct nk_command_polygon*)cmd;
  10398             for (i = 0; i < p->point_count; ++i) {
  10399                 struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y);
  10400                 nk_draw_list_path_line_to(&ctx->draw_list, pnt);
  10401             }
  10402             nk_draw_list_path_stroke(&ctx->draw_list, p->color, NK_STROKE_CLOSED, p->line_thickness);
  10403         } break;
  10404         case NK_COMMAND_POLYGON_FILLED: {
  10405             int i;
  10406             const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled*)cmd;
  10407             for (i = 0; i < p->point_count; ++i) {
  10408                 struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y);
  10409                 nk_draw_list_path_line_to(&ctx->draw_list, pnt);
  10410             }
  10411             nk_draw_list_path_fill(&ctx->draw_list, p->color);
  10412         } break;
  10413         case NK_COMMAND_POLYLINE: {
  10414             int i;
  10415             const struct nk_command_polyline *p = (const struct nk_command_polyline*)cmd;
  10416             for (i = 0; i < p->point_count; ++i) {
  10417                 struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y);
  10418                 nk_draw_list_path_line_to(&ctx->draw_list, pnt);
  10419             }
  10420             nk_draw_list_path_stroke(&ctx->draw_list, p->color, NK_STROKE_OPEN, p->line_thickness);
  10421         } break;
  10422         case NK_COMMAND_TEXT: {
  10423             const struct nk_command_text *t = (const struct nk_command_text*)cmd;
  10424             nk_draw_list_add_text(&ctx->draw_list, t->font, nk_rect(t->x, t->y, t->w, t->h),
  10425                 t->string, t->length, t->height, t->foreground);
  10426         } break;
  10427         case NK_COMMAND_IMAGE: {
  10428             const struct nk_command_image *i = (const struct nk_command_image*)cmd;
  10429             nk_draw_list_add_image(&ctx->draw_list, i->img, nk_rect(i->x, i->y, i->w, i->h), i->col);
  10430         } break;
  10431         case NK_COMMAND_CUSTOM: {
  10432             const struct nk_command_custom *c = (const struct nk_command_custom*)cmd;
  10433             c->callback(&ctx->draw_list, c->x, c->y, c->w, c->h, c->callback_data);
  10434         } break;
  10435         default: break;
  10436         }
  10437     }
  10438     res |= (cmds->needed > cmds->allocated + (cmds->memory.size - cmds->size)) ? NK_CONVERT_COMMAND_BUFFER_FULL: 0;
  10439     res |= (vertices->needed > vertices->allocated) ? NK_CONVERT_VERTEX_BUFFER_FULL: 0;
  10440     res |= (elements->needed > elements->allocated) ? NK_CONVERT_ELEMENT_BUFFER_FULL: 0;
  10441     return res;
  10442 }
  10443 NK_API const struct nk_draw_command*
  10444 nk__draw_begin(const struct nk_context *ctx,
  10445     const struct nk_buffer *buffer)
  10446 {
  10447     return nk__draw_list_begin(&ctx->draw_list, buffer);
  10448 }
  10449 NK_API const struct nk_draw_command*
  10450 nk__draw_end(const struct nk_context *ctx, const struct nk_buffer *buffer)
  10451 {
  10452     return nk__draw_list_end(&ctx->draw_list, buffer);
  10453 }
  10454 NK_API const struct nk_draw_command*
  10455 nk__draw_next(const struct nk_draw_command *cmd,
  10456     const struct nk_buffer *buffer, const struct nk_context *ctx)
  10457 {
  10458     return nk__draw_list_next(cmd, buffer, &ctx->draw_list);
  10459 }
  10460 #endif
  10461 
  10462 
  10463 
  10464 
  10465 
  10466 #ifdef NK_INCLUDE_FONT_BAKING
  10467 /* -------------------------------------------------------------
  10468  *
  10469  *                          RECT PACK
  10470  *
  10471  * --------------------------------------------------------------*/
  10472 /* stb_rect_pack.h - v0.05 - public domain - rectangle packing */
  10473 /* Sean Barrett 2014 */
  10474 #define NK_RP__MAXVAL  0xffff
  10475 typedef unsigned short nk_rp_coord;
  10476 
  10477 struct nk_rp_rect {
  10478     /* reserved for your use: */
  10479     int id;
  10480     /* input: */
  10481     nk_rp_coord w, h;
  10482     /* output: */
  10483     nk_rp_coord x, y;
  10484     int was_packed;
  10485     /* non-zero if valid packing */
  10486 }; /* 16 bytes, nominally */
  10487 
  10488 struct nk_rp_node {
  10489     nk_rp_coord  x,y;
  10490     struct nk_rp_node  *next;
  10491 };
  10492 
  10493 struct nk_rp_context {
  10494     int width;
  10495     int height;
  10496     int align;
  10497     int init_mode;
  10498     int heuristic;
  10499     int num_nodes;
  10500     struct nk_rp_node *active_head;
  10501     struct nk_rp_node *free_head;
  10502     struct nk_rp_node extra[2];
  10503     /* we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' */
  10504 };
  10505 
  10506 struct nk_rp__findresult {
  10507     int x,y;
  10508     struct nk_rp_node **prev_link;
  10509 };
  10510 
  10511 enum NK_RP_HEURISTIC {
  10512     NK_RP_HEURISTIC_Skyline_default=0,
  10513     NK_RP_HEURISTIC_Skyline_BL_sortHeight = NK_RP_HEURISTIC_Skyline_default,
  10514     NK_RP_HEURISTIC_Skyline_BF_sortHeight
  10515 };
  10516 enum NK_RP_INIT_STATE{NK_RP__INIT_skyline = 1};
  10517 
  10518 NK_INTERN void
  10519 nk_rp_setup_allow_out_of_mem(struct nk_rp_context *context, int allow_out_of_mem)
  10520 {
  10521     if (allow_out_of_mem)
  10522         /* if it's ok to run out of memory, then don't bother aligning them; */
  10523         /* this gives better packing, but may fail due to OOM (even though */
  10524         /* the rectangles easily fit). @TODO a smarter approach would be to only */
  10525         /* quantize once we've hit OOM, then we could get rid of this parameter. */
  10526         context->align = 1;
  10527     else {
  10528         /* if it's not ok to run out of memory, then quantize the widths */
  10529         /* so that num_nodes is always enough nodes. */
  10530         /* */
  10531         /* I.e. num_nodes * align >= width */
  10532         /*                  align >= width / num_nodes */
  10533         /*                  align = ceil(width/num_nodes) */
  10534         context->align = (context->width + context->num_nodes-1) / context->num_nodes;
  10535     }
  10536 }
  10537 NK_INTERN void
  10538 nk_rp_init_target(struct nk_rp_context *context, int width, int height,
  10539     struct nk_rp_node *nodes, int num_nodes)
  10540 {
  10541     int i;
  10542 #ifndef STBRP_LARGE_RECTS
  10543     NK_ASSERT(width <= 0xffff && height <= 0xffff);
  10544 #endif
  10545 
  10546     for (i=0; i < num_nodes-1; ++i)
  10547         nodes[i].next = &nodes[i+1];
  10548     nodes[i].next = 0;
  10549     context->init_mode = NK_RP__INIT_skyline;
  10550     context->heuristic = NK_RP_HEURISTIC_Skyline_default;
  10551     context->free_head = &nodes[0];
  10552     context->active_head = &context->extra[0];
  10553     context->width = width;
  10554     context->height = height;
  10555     context->num_nodes = num_nodes;
  10556     nk_rp_setup_allow_out_of_mem(context, 0);
  10557 
  10558     /* node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) */
  10559     context->extra[0].x = 0;
  10560     context->extra[0].y = 0;
  10561     context->extra[0].next = &context->extra[1];
  10562     context->extra[1].x = (nk_rp_coord) width;
  10563     context->extra[1].y = 65535;
  10564     context->extra[1].next = 0;
  10565 }
  10566 /* find minimum y position if it starts at x1 */
  10567 NK_INTERN int
  10568 nk_rp__skyline_find_min_y(struct nk_rp_context *c, struct nk_rp_node *first,
  10569     int x0, int width, int *pwaste)
  10570 {
  10571     struct nk_rp_node *node = first;
  10572     int x1 = x0 + width;
  10573     int min_y, visited_width, waste_area;
  10574     NK_ASSERT(first->x <= x0);
  10575     NK_UNUSED(c);
  10576 
  10577     NK_ASSERT(node->next->x > x0);
  10578     /* we ended up handling this in the caller for efficiency */
  10579     NK_ASSERT(node->x <= x0);
  10580 
  10581     min_y = 0;
  10582     waste_area = 0;
  10583     visited_width = 0;
  10584     while (node->x < x1)
  10585     {
  10586         if (node->y > min_y) {
  10587             /* raise min_y higher. */
  10588             /* we've accounted for all waste up to min_y, */
  10589             /* but we'll now add more waste for everything we've visited */
  10590             waste_area += visited_width * (node->y - min_y);
  10591             min_y = node->y;
  10592             /* the first time through, visited_width might be reduced */
  10593             if (node->x < x0)
  10594             visited_width += node->next->x - x0;
  10595             else
  10596             visited_width += node->next->x - node->x;
  10597         } else {
  10598             /* add waste area */
  10599             int under_width = node->next->x - node->x;
  10600             if (under_width + visited_width > width)
  10601             under_width = width - visited_width;
  10602             waste_area += under_width * (min_y - node->y);
  10603             visited_width += under_width;
  10604         }
  10605         node = node->next;
  10606     }
  10607     *pwaste = waste_area;
  10608     return min_y;
  10609 }
  10610 NK_INTERN struct nk_rp__findresult
  10611 nk_rp__skyline_find_best_pos(struct nk_rp_context *c, int width, int height)
  10612 {
  10613     int best_waste = (1<<30), best_x, best_y = (1 << 30);
  10614     struct nk_rp__findresult fr;
  10615     struct nk_rp_node **prev, *node, *tail, **best = 0;
  10616 
  10617     /* align to multiple of c->align */
  10618     width = (width + c->align - 1);
  10619     width -= width % c->align;
  10620     NK_ASSERT(width % c->align == 0);
  10621 
  10622     node = c->active_head;
  10623     prev = &c->active_head;
  10624     while (node->x + width <= c->width) {
  10625         int y,waste;
  10626         y = nk_rp__skyline_find_min_y(c, node, node->x, width, &waste);
  10627         /* actually just want to test BL */
  10628         if (c->heuristic == NK_RP_HEURISTIC_Skyline_BL_sortHeight) {
  10629             /* bottom left */
  10630             if (y < best_y) {
  10631             best_y = y;
  10632             best = prev;
  10633             }
  10634         } else {
  10635             /* best-fit */
  10636             if (y + height <= c->height) {
  10637                 /* can only use it if it first vertically */
  10638                 if (y < best_y || (y == best_y && waste < best_waste)) {
  10639                     best_y = y;
  10640                     best_waste = waste;
  10641                     best = prev;
  10642                 }
  10643             }
  10644         }
  10645         prev = &node->next;
  10646         node = node->next;
  10647     }
  10648     best_x = (best == 0) ? 0 : (*best)->x;
  10649 
  10650     /* if doing best-fit (BF), we also have to try aligning right edge to each node position */
  10651     /* */
  10652     /* e.g, if fitting */
  10653     /* */
  10654     /*     ____________________ */
  10655     /*    |____________________| */
  10656     /* */
  10657     /*            into */
  10658     /* */
  10659     /*   |                         | */
  10660     /*   |             ____________| */
  10661     /*   |____________| */
  10662     /* */
  10663     /* then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned */
  10664     /* */
  10665     /* This makes BF take about 2x the time */
  10666     if (c->heuristic == NK_RP_HEURISTIC_Skyline_BF_sortHeight)
  10667     {
  10668         tail = c->active_head;
  10669         node = c->active_head;
  10670         prev = &c->active_head;
  10671         /* find first node that's admissible */
  10672         while (tail->x < width)
  10673             tail = tail->next;
  10674         while (tail)
  10675         {
  10676             int xpos = tail->x - width;
  10677             int y,waste;
  10678             NK_ASSERT(xpos >= 0);
  10679             /* find the left position that matches this */
  10680             while (node->next->x <= xpos) {
  10681                 prev = &node->next;
  10682                 node = node->next;
  10683             }
  10684             NK_ASSERT(node->next->x > xpos && node->x <= xpos);
  10685             y = nk_rp__skyline_find_min_y(c, node, xpos, width, &waste);
  10686             if (y + height < c->height) {
  10687                 if (y <= best_y) {
  10688                     if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
  10689                         best_x = xpos;
  10690                         NK_ASSERT(y <= best_y);
  10691                         best_y = y;
  10692                         best_waste = waste;
  10693                         best = prev;
  10694                     }
  10695                 }
  10696             }
  10697             tail = tail->next;
  10698         }
  10699     }
  10700     fr.prev_link = best;
  10701     fr.x = best_x;
  10702     fr.y = best_y;
  10703     return fr;
  10704 }
  10705 NK_INTERN struct nk_rp__findresult
  10706 nk_rp__skyline_pack_rectangle(struct nk_rp_context *context, int width, int height)
  10707 {
  10708     /* find best position according to heuristic */
  10709     struct nk_rp__findresult res = nk_rp__skyline_find_best_pos(context, width, height);
  10710     struct nk_rp_node *node, *cur;
  10711 
  10712     /* bail if: */
  10713     /*    1. it failed */
  10714     /*    2. the best node doesn't fit (we don't always check this) */
  10715     /*    3. we're out of memory */
  10716     if (res.prev_link == 0 || res.y + height > context->height || context->free_head == 0) {
  10717         res.prev_link = 0;
  10718         return res;
  10719     }
  10720 
  10721     /* on success, create new node */
  10722     node = context->free_head;
  10723     node->x = (nk_rp_coord) res.x;
  10724     node->y = (nk_rp_coord) (res.y + height);
  10725 
  10726     context->free_head = node->next;
  10727 
  10728     /* insert the new node into the right starting point, and */
  10729     /* let 'cur' point to the remaining nodes needing to be */
  10730     /* stitched back in */
  10731     cur = *res.prev_link;
  10732     if (cur->x < res.x) {
  10733         /* preserve the existing one, so start testing with the next one */
  10734         struct nk_rp_node *next = cur->next;
  10735         cur->next = node;
  10736         cur = next;
  10737     } else {
  10738         *res.prev_link = node;
  10739     }
  10740 
  10741     /* from here, traverse cur and free the nodes, until we get to one */
  10742     /* that shouldn't be freed */
  10743     while (cur->next && cur->next->x <= res.x + width) {
  10744         struct nk_rp_node *next = cur->next;
  10745         /* move the current node to the free list */
  10746         cur->next = context->free_head;
  10747         context->free_head = cur;
  10748         cur = next;
  10749     }
  10750     /* stitch the list back in */
  10751     node->next = cur;
  10752 
  10753     if (cur->x < res.x + width)
  10754         cur->x = (nk_rp_coord) (res.x + width);
  10755     return res;
  10756 }
  10757 NK_INTERN int
  10758 nk_rect_height_compare(const void *a, const void *b)
  10759 {
  10760     const struct nk_rp_rect *p = (const struct nk_rp_rect *) a;
  10761     const struct nk_rp_rect *q = (const struct nk_rp_rect *) b;
  10762     if (p->h > q->h)
  10763         return -1;
  10764     if (p->h < q->h)
  10765         return  1;
  10766     return (p->w > q->w) ? -1 : (p->w < q->w);
  10767 }
  10768 NK_INTERN int
  10769 nk_rect_original_order(const void *a, const void *b)
  10770 {
  10771     const struct nk_rp_rect *p = (const struct nk_rp_rect *) a;
  10772     const struct nk_rp_rect *q = (const struct nk_rp_rect *) b;
  10773     return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
  10774 }
  10775 NK_INTERN void
  10776 nk_rp_qsort(struct nk_rp_rect *array, unsigned int len, int(*cmp)(const void*,const void*))
  10777 {
  10778     /* iterative quick sort */
  10779     #define NK_MAX_SORT_STACK 64
  10780     unsigned right, left = 0, stack[NK_MAX_SORT_STACK], pos = 0;
  10781     unsigned seed = len/2 * 69069+1;
  10782     for (;;) {
  10783         for (; left+1 < len; len++) {
  10784             struct nk_rp_rect pivot, tmp;
  10785             if (pos == NK_MAX_SORT_STACK) len = stack[pos = 0];
  10786             pivot = array[left+seed%(len-left)];
  10787             seed = seed * 69069 + 1;
  10788             stack[pos++] = len;
  10789             for (right = left-1;;) {
  10790                 while (cmp(&array[++right], &pivot) < 0);
  10791                 while (cmp(&pivot, &array[--len]) < 0);
  10792                 if (right >= len) break;
  10793                 tmp = array[right];
  10794                 array[right] = array[len];
  10795                 array[len] = tmp;
  10796             }
  10797         }
  10798         if (pos == 0) break;
  10799         left = len;
  10800         len = stack[--pos];
  10801     }
  10802     #undef NK_MAX_SORT_STACK
  10803 }
  10804 NK_INTERN void
  10805 nk_rp_pack_rects(struct nk_rp_context *context, struct nk_rp_rect *rects, int num_rects)
  10806 {
  10807     int i;
  10808     /* we use the 'was_packed' field internally to allow sorting/unsorting */
  10809     for (i=0; i < num_rects; ++i) {
  10810         rects[i].was_packed = i;
  10811     }
  10812 
  10813     /* sort according to heuristic */
  10814     nk_rp_qsort(rects, (unsigned)num_rects, nk_rect_height_compare);
  10815 
  10816     for (i=0; i < num_rects; ++i) {
  10817         struct nk_rp__findresult fr = nk_rp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
  10818         if (fr.prev_link) {
  10819             rects[i].x = (nk_rp_coord) fr.x;
  10820             rects[i].y = (nk_rp_coord) fr.y;
  10821         } else {
  10822             rects[i].x = rects[i].y = NK_RP__MAXVAL;
  10823         }
  10824     }
  10825 
  10826     /* unsort */
  10827     nk_rp_qsort(rects, (unsigned)num_rects, nk_rect_original_order);
  10828 
  10829     /* set was_packed flags */
  10830     for (i=0; i < num_rects; ++i)
  10831         rects[i].was_packed = !(rects[i].x == NK_RP__MAXVAL && rects[i].y == NK_RP__MAXVAL);
  10832 }
  10833 
  10834 /*
  10835  * ==============================================================
  10836  *
  10837  *                          TRUETYPE
  10838  *
  10839  * ===============================================================
  10840  */
  10841 /* stb_truetype.h - v1.07 - public domain */
  10842 #define NK_TT_MAX_OVERSAMPLE   8
  10843 #define NK_TT__OVER_MASK  (NK_TT_MAX_OVERSAMPLE-1)
  10844 
  10845 struct nk_tt_bakedchar {
  10846     unsigned short x0,y0,x1,y1;
  10847     /* coordinates of bbox in bitmap */
  10848     float xoff,yoff,xadvance;
  10849 };
  10850 
  10851 struct nk_tt_aligned_quad{
  10852     float x0,y0,s0,t0; /* top-left */
  10853     float x1,y1,s1,t1; /* bottom-right */
  10854 };
  10855 
  10856 struct nk_tt_packedchar {
  10857     unsigned short x0,y0,x1,y1;
  10858     /* coordinates of bbox in bitmap */
  10859     float xoff,yoff,xadvance;
  10860     float xoff2,yoff2;
  10861 };
  10862 
  10863 struct nk_tt_pack_range {
  10864     float font_size;
  10865     int first_unicode_codepoint_in_range;
  10866     /* if non-zero, then the chars are continuous, and this is the first codepoint */
  10867     int *array_of_unicode_codepoints;
  10868     /* if non-zero, then this is an array of unicode codepoints */
  10869     int num_chars;
  10870     struct nk_tt_packedchar *chardata_for_range; /* output */
  10871     unsigned char h_oversample, v_oversample;
  10872     /* don't set these, they're used internally */
  10873 };
  10874 
  10875 struct nk_tt_pack_context {
  10876     void *pack_info;
  10877     int   width;
  10878     int   height;
  10879     int   stride_in_bytes;
  10880     int   padding;
  10881     unsigned int   h_oversample, v_oversample;
  10882     unsigned char *pixels;
  10883     void  *nodes;
  10884 };
  10885 
  10886 struct nk_tt_fontinfo {
  10887     const unsigned char* data; /* pointer to .ttf file */
  10888     int fontstart;/* offset of start of font */
  10889     int numGlyphs;/* number of glyphs, needed for range checking */
  10890     int loca,head,glyf,hhea,hmtx,kern; /* table locations as offset from start of .ttf */
  10891     int index_map; /* a cmap mapping for our chosen character encoding */
  10892     int indexToLocFormat; /* format needed to map from glyph index to glyph */
  10893 };
  10894 
  10895 enum {
  10896   NK_TT_vmove=1,
  10897   NK_TT_vline,
  10898   NK_TT_vcurve
  10899 };
  10900 
  10901 struct nk_tt_vertex {
  10902     short x,y,cx,cy;
  10903     unsigned char type,padding;
  10904 };
  10905 
  10906 struct nk_tt__bitmap{
  10907    int w,h,stride;
  10908    unsigned char *pixels;
  10909 };
  10910 
  10911 struct nk_tt__hheap_chunk {
  10912     struct nk_tt__hheap_chunk *next;
  10913 };
  10914 struct nk_tt__hheap {
  10915     struct nk_allocator alloc;
  10916     struct nk_tt__hheap_chunk *head;
  10917     void   *first_free;
  10918     int    num_remaining_in_head_chunk;
  10919 };
  10920 
  10921 struct nk_tt__edge {
  10922     float x0,y0, x1,y1;
  10923     int invert;
  10924 };
  10925 
  10926 struct nk_tt__active_edge {
  10927     struct nk_tt__active_edge *next;
  10928     float fx,fdx,fdy;
  10929     float direction;
  10930     float sy;
  10931     float ey;
  10932 };
  10933 struct nk_tt__point {float x,y;};
  10934 
  10935 #define NK_TT_MACSTYLE_DONTCARE     0
  10936 #define NK_TT_MACSTYLE_BOLD         1
  10937 #define NK_TT_MACSTYLE_ITALIC       2
  10938 #define NK_TT_MACSTYLE_UNDERSCORE   4
  10939 #define NK_TT_MACSTYLE_NONE         8
  10940 /* <= not same as 0, this makes us check the bitfield is 0 */
  10941 
  10942 enum { /* platformID */
  10943    NK_TT_PLATFORM_ID_UNICODE   =0,
  10944    NK_TT_PLATFORM_ID_MAC       =1,
  10945    NK_TT_PLATFORM_ID_ISO       =2,
  10946    NK_TT_PLATFORM_ID_MICROSOFT =3
  10947 };
  10948 
  10949 enum { /* encodingID for NK_TT_PLATFORM_ID_UNICODE */
  10950    NK_TT_UNICODE_EID_UNICODE_1_0    =0,
  10951    NK_TT_UNICODE_EID_UNICODE_1_1    =1,
  10952    NK_TT_UNICODE_EID_ISO_10646      =2,
  10953    NK_TT_UNICODE_EID_UNICODE_2_0_BMP=3,
  10954    NK_TT_UNICODE_EID_UNICODE_2_0_FULL=4
  10955 };
  10956 
  10957 enum { /* encodingID for NK_TT_PLATFORM_ID_MICROSOFT */
  10958    NK_TT_MS_EID_SYMBOL        =0,
  10959    NK_TT_MS_EID_UNICODE_BMP   =1,
  10960    NK_TT_MS_EID_SHIFTJIS      =2,
  10961    NK_TT_MS_EID_UNICODE_FULL  =10
  10962 };
  10963 
  10964 enum { /* encodingID for NK_TT_PLATFORM_ID_MAC; same as Script Manager codes */
  10965    NK_TT_MAC_EID_ROMAN        =0,   NK_TT_MAC_EID_ARABIC       =4,
  10966    NK_TT_MAC_EID_JAPANESE     =1,   NK_TT_MAC_EID_HEBREW       =5,
  10967    NK_TT_MAC_EID_CHINESE_TRAD =2,   NK_TT_MAC_EID_GREEK        =6,
  10968    NK_TT_MAC_EID_KOREAN       =3,   NK_TT_MAC_EID_RUSSIAN      =7
  10969 };
  10970 
  10971 enum { /* languageID for NK_TT_PLATFORM_ID_MICROSOFT; same as LCID... */
  10972        /* problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs */
  10973    NK_TT_MS_LANG_ENGLISH     =0x0409,   NK_TT_MS_LANG_ITALIAN     =0x0410,
  10974    NK_TT_MS_LANG_CHINESE     =0x0804,   NK_TT_MS_LANG_JAPANESE    =0x0411,
  10975    NK_TT_MS_LANG_DUTCH       =0x0413,   NK_TT_MS_LANG_KOREAN      =0x0412,
  10976    NK_TT_MS_LANG_FRENCH      =0x040c,   NK_TT_MS_LANG_RUSSIAN     =0x0419,
  10977    NK_TT_MS_LANG_GERMAN      =0x0407,   NK_TT_MS_LANG_SPANISH     =0x0409,
  10978    NK_TT_MS_LANG_HEBREW      =0x040d,   NK_TT_MS_LANG_SWEDISH     =0x041D
  10979 };
  10980 
  10981 enum { /* languageID for NK_TT_PLATFORM_ID_MAC */
  10982    NK_TT_MAC_LANG_ENGLISH      =0 ,   NK_TT_MAC_LANG_JAPANESE     =11,
  10983    NK_TT_MAC_LANG_ARABIC       =12,   NK_TT_MAC_LANG_KOREAN       =23,
  10984    NK_TT_MAC_LANG_DUTCH        =4 ,   NK_TT_MAC_LANG_RUSSIAN      =32,
  10985    NK_TT_MAC_LANG_FRENCH       =1 ,   NK_TT_MAC_LANG_SPANISH      =6 ,
  10986    NK_TT_MAC_LANG_GERMAN       =2 ,   NK_TT_MAC_LANG_SWEDISH      =5 ,
  10987    NK_TT_MAC_LANG_HEBREW       =10,   NK_TT_MAC_LANG_CHINESE_SIMPLIFIED =33,
  10988    NK_TT_MAC_LANG_ITALIAN      =3 ,   NK_TT_MAC_LANG_CHINESE_TRAD =19
  10989 };
  10990 
  10991 #define nk_ttBYTE(p)     (* (const nk_byte *) (p))
  10992 #define nk_ttCHAR(p)     (* (const char *) (p))
  10993 
  10994 #if defined(NK_BIGENDIAN) && !defined(NK_ALLOW_UNALIGNED_TRUETYPE)
  10995    #define nk_ttUSHORT(p)   (* (nk_ushort *) (p))
  10996    #define nk_ttSHORT(p)    (* (nk_short *) (p))
  10997    #define nk_ttULONG(p)    (* (nk_uint *) (p))
  10998    #define nk_ttLONG(p)     (* (nk_int *) (p))
  10999 #else
  11000     static nk_ushort nk_ttUSHORT(const nk_byte *p) { return (nk_ushort)(p[0]*256 + p[1]); }
  11001     static nk_short nk_ttSHORT(const nk_byte *p)   { return (nk_short)(p[0]*256 + p[1]); }
  11002     static nk_uint nk_ttULONG(const nk_byte *p)  { return (nk_uint)((p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]); }
  11003 #endif
  11004 
  11005 #define nk_tt_tag4(p,c0,c1,c2,c3)\
  11006     ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3))
  11007 #define nk_tt_tag(p,str) nk_tt_tag4(p,str[0],str[1],str[2],str[3])
  11008 
  11009 NK_INTERN int nk_tt_GetGlyphShape(const struct nk_tt_fontinfo *info, struct nk_allocator *alloc,
  11010                                 int glyph_index, struct nk_tt_vertex **pvertices);
  11011 
  11012 NK_INTERN nk_uint
  11013 nk_tt__find_table(const nk_byte *data, nk_uint fontstart, const char *tag)
  11014 {
  11015     /* @OPTIMIZE: binary search */
  11016     nk_int num_tables = nk_ttUSHORT(data+fontstart+4);
  11017     nk_uint tabledir = fontstart + 12;
  11018     nk_int i;
  11019     for (i = 0; i < num_tables; ++i) {
  11020         nk_uint loc = tabledir + (nk_uint)(16*i);
  11021         if (nk_tt_tag(data+loc+0, tag))
  11022             return nk_ttULONG(data+loc+8);
  11023     }
  11024     return 0;
  11025 }
  11026 NK_INTERN int
  11027 nk_tt_InitFont(struct nk_tt_fontinfo *info, const unsigned char *data2, int fontstart)
  11028 {
  11029     nk_uint cmap, t;
  11030     nk_int i,numTables;
  11031     const nk_byte *data = (const nk_byte *) data2;
  11032 
  11033     info->data = data;
  11034     info->fontstart = fontstart;
  11035 
  11036     cmap = nk_tt__find_table(data, (nk_uint)fontstart, "cmap");       /* required */
  11037     info->loca = (int)nk_tt__find_table(data, (nk_uint)fontstart, "loca"); /* required */
  11038     info->head = (int)nk_tt__find_table(data, (nk_uint)fontstart, "head"); /* required */
  11039     info->glyf = (int)nk_tt__find_table(data, (nk_uint)fontstart, "glyf"); /* required */
  11040     info->hhea = (int)nk_tt__find_table(data, (nk_uint)fontstart, "hhea"); /* required */
  11041     info->hmtx = (int)nk_tt__find_table(data, (nk_uint)fontstart, "hmtx"); /* required */
  11042     info->kern = (int)nk_tt__find_table(data, (nk_uint)fontstart, "kern"); /* not required */
  11043     if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx)
  11044         return 0;
  11045 
  11046     t = nk_tt__find_table(data, (nk_uint)fontstart, "maxp");
  11047     if (t) info->numGlyphs = nk_ttUSHORT(data+t+4);
  11048     else info->numGlyphs = 0xffff;
  11049 
  11050     /* find a cmap encoding table we understand *now* to avoid searching */
  11051     /* later. (todo: could make this installable) */
  11052     /* the same regardless of glyph. */
  11053     numTables = nk_ttUSHORT(data + cmap + 2);
  11054     info->index_map = 0;
  11055     for (i=0; i < numTables; ++i)
  11056     {
  11057         nk_uint encoding_record = cmap + 4 + 8 * (nk_uint)i;
  11058         /* find an encoding we understand: */
  11059         switch(nk_ttUSHORT(data+encoding_record)) {
  11060         case NK_TT_PLATFORM_ID_MICROSOFT:
  11061             switch (nk_ttUSHORT(data+encoding_record+2)) {
  11062             case NK_TT_MS_EID_UNICODE_BMP:
  11063             case NK_TT_MS_EID_UNICODE_FULL:
  11064                 /* MS/Unicode */
  11065                 info->index_map = (int)(cmap + nk_ttULONG(data+encoding_record+4));
  11066                 break;
  11067             default: break;
  11068             } break;
  11069         case NK_TT_PLATFORM_ID_UNICODE:
  11070             /* Mac/iOS has these */
  11071             /* all the encodingIDs are unicode, so we don't bother to check it */
  11072             info->index_map = (int)(cmap + nk_ttULONG(data+encoding_record+4));
  11073             break;
  11074         default: break;
  11075         }
  11076     }
  11077     if (info->index_map == 0)
  11078         return 0;
  11079     info->indexToLocFormat = nk_ttUSHORT(data+info->head + 50);
  11080     return 1;
  11081 }
  11082 NK_INTERN int
  11083 nk_tt_FindGlyphIndex(const struct nk_tt_fontinfo *info, int unicode_codepoint)
  11084 {
  11085     const nk_byte *data = info->data;
  11086     nk_uint index_map = (nk_uint)info->index_map;
  11087 
  11088     nk_ushort format = nk_ttUSHORT(data + index_map + 0);
  11089     if (format == 0) { /* apple byte encoding */
  11090         nk_int bytes = nk_ttUSHORT(data + index_map + 2);
  11091         if (unicode_codepoint < bytes-6)
  11092             return nk_ttBYTE(data + index_map + 6 + unicode_codepoint);
  11093         return 0;
  11094     } else if (format == 6) {
  11095         nk_uint first = nk_ttUSHORT(data + index_map + 6);
  11096         nk_uint count = nk_ttUSHORT(data + index_map + 8);
  11097         if ((nk_uint) unicode_codepoint >= first && (nk_uint) unicode_codepoint < first+count)
  11098             return nk_ttUSHORT(data + index_map + 10 + (unicode_codepoint - (int)first)*2);
  11099         return 0;
  11100     } else if (format == 2) {
  11101         NK_ASSERT(0); /* @TODO: high-byte mapping for japanese/chinese/korean */
  11102         return 0;
  11103     } else if (format == 4) { /* standard mapping for windows fonts: binary search collection of ranges */
  11104         nk_ushort segcount = nk_ttUSHORT(data+index_map+6) >> 1;
  11105         nk_ushort searchRange = nk_ttUSHORT(data+index_map+8) >> 1;
  11106         nk_ushort entrySelector = nk_ttUSHORT(data+index_map+10);
  11107         nk_ushort rangeShift = nk_ttUSHORT(data+index_map+12) >> 1;
  11108 
  11109         /* do a binary search of the segments */
  11110         nk_uint endCount = index_map + 14;
  11111         nk_uint search = endCount;
  11112 
  11113         if (unicode_codepoint > 0xffff)
  11114             return 0;
  11115 
  11116         /* they lie from endCount .. endCount + segCount */
  11117         /* but searchRange is the nearest power of two, so... */
  11118         if (unicode_codepoint >= nk_ttUSHORT(data + search + rangeShift*2))
  11119             search += (nk_uint)(rangeShift*2);
  11120