From e16994e3566579a8e22e69aced18e23fda28f7d5 Mon Sep 17 00:00:00 2001 From: Anthony Pesch Date: Thu, 8 Jun 2017 01:28:02 -0400 Subject: [PATCH] remove nuklear source --- deps/nuklear/.gitattributes | 3 - deps/nuklear/.gitignore | 2 - deps/nuklear/.travis.yml | 15 - deps/nuklear/CHANGELOG.md | 192 - deps/nuklear/Readme.md | 112 - deps/nuklear/demo/calculator.c | 64 - deps/nuklear/demo/d3d11/build.bat | 9 - deps/nuklear/demo/d3d11/main.c | 278 - deps/nuklear/demo/d3d11/nuklear_d3d11.h | 617 - deps/nuklear/demo/d3d11/nuklear_d3d11.hlsl | 36 - .../demo/d3d11/nuklear_d3d11_pixel_shader.h | 179 - .../demo/d3d11/nuklear_d3d11_vertex_shader.h | 350 - deps/nuklear/demo/gdi/build.bat | 6 - deps/nuklear/demo/gdi/main.c | 161 - deps/nuklear/demo/gdi/nuklear_gdi.h | 761 - deps/nuklear/demo/gdip/build.bat | 5 - deps/nuklear/demo/gdip/main.c | 155 - deps/nuklear/demo/gdip/nuklear_gdip.h | 1006 - deps/nuklear/demo/glfw_opengl2/main.c | 165 - .../demo/glfw_opengl2/nuklear_glfw_gl2.h | 350 - deps/nuklear/demo/glfw_opengl3/main.c | 180 - .../demo/glfw_opengl3/nuklear_glfw_gl3.h | 456 - deps/nuklear/demo/node_editor.c | 343 - deps/nuklear/demo/overview.c | 1188 - deps/nuklear/demo/sdl_opengl2/main.c | 181 - .../demo/sdl_opengl2/nuklear_sdl_gl2.h | 342 - deps/nuklear/demo/sdl_opengl3/main.c | 195 - .../demo/sdl_opengl3/nuklear_sdl_gl3.h | 437 - deps/nuklear/demo/style.c | 132 - deps/nuklear/demo/x11/main.c | 203 - deps/nuklear/demo/x11/nuklear_xlib.h | 693 - deps/nuklear/demo/x11_opengl2/main.c | 320 - .../demo/x11_opengl2/nuklear_xlib_gl2.h | 357 - deps/nuklear/demo/x11_opengl3/main.c | 317 - .../demo/x11_opengl3/nuklear_xlib_gl3.h | 725 - deps/nuklear/example/canvas.c | 489 - deps/nuklear/example/extended.c | 906 - deps/nuklear/example/file_browser.c | 910 - deps/nuklear/example/icon/checked.png | Bin 1813 -> 0 bytes deps/nuklear/example/icon/cloud.png | Bin 7509 -> 0 bytes deps/nuklear/example/icon/computer.png | Bin 620 -> 0 bytes deps/nuklear/example/icon/copy.png | Bin 655 -> 0 bytes deps/nuklear/example/icon/default.png | Bin 460 -> 0 bytes deps/nuklear/example/icon/delete.png | Bin 11040 -> 0 bytes deps/nuklear/example/icon/desktop.png | Bin 583 -> 0 bytes deps/nuklear/example/icon/directory.png | Bin 533 -> 0 bytes deps/nuklear/example/icon/edit.png | Bin 14998 -> 0 bytes deps/nuklear/example/icon/export.png | Bin 13336 -> 0 bytes deps/nuklear/example/icon/font.png | Bin 561 -> 0 bytes deps/nuklear/example/icon/home.png | Bin 819 -> 0 bytes deps/nuklear/example/icon/img.png | Bin 648 -> 0 bytes deps/nuklear/example/icon/movie.png | Bin 626 -> 0 bytes deps/nuklear/example/icon/music.png | Bin 610 -> 0 bytes deps/nuklear/example/icon/next.png | Bin 703 -> 0 bytes deps/nuklear/example/icon/pause.png | Bin 1338 -> 0 bytes deps/nuklear/example/icon/pen.png | Bin 5949 -> 0 bytes deps/nuklear/example/icon/phone.png | Bin 15778 -> 0 bytes deps/nuklear/example/icon/plane.png | Bin 13546 -> 0 bytes deps/nuklear/example/icon/play.png | Bin 566 -> 0 bytes deps/nuklear/example/icon/prev.png | Bin 701 -> 0 bytes deps/nuklear/example/icon/rocket.png | Bin 1121 -> 0 bytes deps/nuklear/example/icon/settings.png | Bin 15671 -> 0 bytes deps/nuklear/example/icon/stop.png | Bin 520 -> 0 bytes deps/nuklear/example/icon/text.png | Bin 601 -> 0 bytes deps/nuklear/example/icon/tools.png | Bin 24483 -> 0 bytes deps/nuklear/example/icon/unchecked.png | Bin 1044 -> 0 bytes deps/nuklear/example/icon/volume.png | Bin 25438 -> 0 bytes deps/nuklear/example/icon/wifi.png | Bin 18857 -> 0 bytes deps/nuklear/example/images/image1.png | Bin 42882 -> 0 bytes deps/nuklear/example/images/image2.png | Bin 5671 -> 0 bytes deps/nuklear/example/images/image3.png | Bin 131502 -> 0 bytes deps/nuklear/example/images/image4.png | Bin 185821 -> 0 bytes deps/nuklear/example/images/image5.png | Bin 98475 -> 0 bytes deps/nuklear/example/images/image6.png | Bin 35633 -> 0 bytes deps/nuklear/example/images/image7.png | Bin 13960 -> 0 bytes deps/nuklear/example/images/image8.png | Bin 45987 -> 0 bytes deps/nuklear/example/images/image9.png | Bin 30759 -> 0 bytes deps/nuklear/example/skinning.c | 825 - deps/nuklear/example/skins/gwen.png | Bin 24565 -> 0 bytes deps/nuklear/example/stb_image.h | 6509 ----- deps/nuklear/extra_font/Cousine-Regular.ttf | Bin 43912 -> 0 bytes deps/nuklear/extra_font/DroidSans.ttf | Bin 190044 -> 0 bytes deps/nuklear/extra_font/Karla-Regular.ttf | Bin 16848 -> 0 bytes deps/nuklear/extra_font/ProggyClean.ttf | Bin 41208 -> 0 bytes deps/nuklear/extra_font/ProggyTiny.ttf | Bin 35656 -> 0 bytes deps/nuklear/extra_font/Raleway-Bold.ttf | Bin 176280 -> 0 bytes deps/nuklear/extra_font/Roboto-Bold.ttf | Bin 135820 -> 0 bytes deps/nuklear/extra_font/Roboto-Light.ttf | Bin 140276 -> 0 bytes deps/nuklear/extra_font/Roboto-Regular.ttf | Bin 145348 -> 0 bytes deps/nuklear/extra_font/kenvector_future.ttf | Bin 34136 -> 0 bytes .../extra_font/kenvector_future_thin.ttf | Bin 34100 -> 0 bytes deps/nuklear/nuklear.h | 22007 ---------------- deps/nuklear/package.json | 8 - 93 files changed, 42189 deletions(-) delete mode 100644 deps/nuklear/.gitattributes delete mode 100644 deps/nuklear/.gitignore delete mode 100644 deps/nuklear/.travis.yml delete mode 100644 deps/nuklear/CHANGELOG.md delete mode 100644 deps/nuklear/Readme.md delete mode 100644 deps/nuklear/demo/calculator.c delete mode 100644 deps/nuklear/demo/d3d11/build.bat delete mode 100644 deps/nuklear/demo/d3d11/main.c delete mode 100644 deps/nuklear/demo/d3d11/nuklear_d3d11.h delete mode 100644 deps/nuklear/demo/d3d11/nuklear_d3d11.hlsl delete mode 100644 deps/nuklear/demo/d3d11/nuklear_d3d11_pixel_shader.h delete mode 100644 deps/nuklear/demo/d3d11/nuklear_d3d11_vertex_shader.h delete mode 100644 deps/nuklear/demo/gdi/build.bat delete mode 100644 deps/nuklear/demo/gdi/main.c delete mode 100644 deps/nuklear/demo/gdi/nuklear_gdi.h delete mode 100644 deps/nuklear/demo/gdip/build.bat delete mode 100644 deps/nuklear/demo/gdip/main.c delete mode 100644 deps/nuklear/demo/gdip/nuklear_gdip.h delete mode 100644 deps/nuklear/demo/glfw_opengl2/main.c delete mode 100644 deps/nuklear/demo/glfw_opengl2/nuklear_glfw_gl2.h delete mode 100644 deps/nuklear/demo/glfw_opengl3/main.c delete mode 100644 deps/nuklear/demo/glfw_opengl3/nuklear_glfw_gl3.h delete mode 100644 deps/nuklear/demo/node_editor.c delete mode 100644 deps/nuklear/demo/overview.c delete mode 100644 deps/nuklear/demo/sdl_opengl2/main.c delete mode 100644 deps/nuklear/demo/sdl_opengl2/nuklear_sdl_gl2.h delete mode 100644 deps/nuklear/demo/sdl_opengl3/main.c delete mode 100644 deps/nuklear/demo/sdl_opengl3/nuklear_sdl_gl3.h delete mode 100644 deps/nuklear/demo/style.c delete mode 100644 deps/nuklear/demo/x11/main.c delete mode 100644 deps/nuklear/demo/x11/nuklear_xlib.h delete mode 100644 deps/nuklear/demo/x11_opengl2/main.c delete mode 100644 deps/nuklear/demo/x11_opengl2/nuklear_xlib_gl2.h delete mode 100644 deps/nuklear/demo/x11_opengl3/main.c delete mode 100644 deps/nuklear/demo/x11_opengl3/nuklear_xlib_gl3.h delete mode 100644 deps/nuklear/example/canvas.c delete mode 100644 deps/nuklear/example/extended.c delete mode 100644 deps/nuklear/example/file_browser.c delete mode 100644 deps/nuklear/example/icon/checked.png delete mode 100644 deps/nuklear/example/icon/cloud.png delete mode 100644 deps/nuklear/example/icon/computer.png delete mode 100644 deps/nuklear/example/icon/copy.png delete mode 100644 deps/nuklear/example/icon/default.png delete mode 100644 deps/nuklear/example/icon/delete.png delete mode 100644 deps/nuklear/example/icon/desktop.png delete mode 100644 deps/nuklear/example/icon/directory.png delete mode 100644 deps/nuklear/example/icon/edit.png delete mode 100644 deps/nuklear/example/icon/export.png delete mode 100644 deps/nuklear/example/icon/font.png delete mode 100644 deps/nuklear/example/icon/home.png delete mode 100644 deps/nuklear/example/icon/img.png delete mode 100644 deps/nuklear/example/icon/movie.png delete mode 100644 deps/nuklear/example/icon/music.png delete mode 100644 deps/nuklear/example/icon/next.png delete mode 100644 deps/nuklear/example/icon/pause.png delete mode 100644 deps/nuklear/example/icon/pen.png delete mode 100644 deps/nuklear/example/icon/phone.png delete mode 100644 deps/nuklear/example/icon/plane.png delete mode 100644 deps/nuklear/example/icon/play.png delete mode 100644 deps/nuklear/example/icon/prev.png delete mode 100644 deps/nuklear/example/icon/rocket.png delete mode 100644 deps/nuklear/example/icon/settings.png delete mode 100644 deps/nuklear/example/icon/stop.png delete mode 100644 deps/nuklear/example/icon/text.png delete mode 100644 deps/nuklear/example/icon/tools.png delete mode 100644 deps/nuklear/example/icon/unchecked.png delete mode 100644 deps/nuklear/example/icon/volume.png delete mode 100644 deps/nuklear/example/icon/wifi.png delete mode 100644 deps/nuklear/example/images/image1.png delete mode 100644 deps/nuklear/example/images/image2.png delete mode 100644 deps/nuklear/example/images/image3.png delete mode 100644 deps/nuklear/example/images/image4.png delete mode 100644 deps/nuklear/example/images/image5.png delete mode 100644 deps/nuklear/example/images/image6.png delete mode 100644 deps/nuklear/example/images/image7.png delete mode 100644 deps/nuklear/example/images/image8.png delete mode 100644 deps/nuklear/example/images/image9.png delete mode 100644 deps/nuklear/example/skinning.c delete mode 100644 deps/nuklear/example/skins/gwen.png delete mode 100644 deps/nuklear/example/stb_image.h delete mode 100644 deps/nuklear/extra_font/Cousine-Regular.ttf delete mode 100644 deps/nuklear/extra_font/DroidSans.ttf delete mode 100644 deps/nuklear/extra_font/Karla-Regular.ttf delete mode 100644 deps/nuklear/extra_font/ProggyClean.ttf delete mode 100644 deps/nuklear/extra_font/ProggyTiny.ttf delete mode 100644 deps/nuklear/extra_font/Raleway-Bold.ttf delete mode 100644 deps/nuklear/extra_font/Roboto-Bold.ttf delete mode 100644 deps/nuklear/extra_font/Roboto-Light.ttf delete mode 100644 deps/nuklear/extra_font/Roboto-Regular.ttf delete mode 100644 deps/nuklear/extra_font/kenvector_future.ttf delete mode 100644 deps/nuklear/extra_font/kenvector_future_thin.ttf delete mode 100644 deps/nuklear/nuklear.h delete mode 100644 deps/nuklear/package.json diff --git a/deps/nuklear/.gitattributes b/deps/nuklear/.gitattributes deleted file mode 100644 index 5a5328c3..00000000 --- a/deps/nuklear/.gitattributes +++ /dev/null @@ -1,3 +0,0 @@ -# Github language settings -*.h linguist-language=c -*.c linguist-language=c diff --git a/deps/nuklear/.gitignore b/deps/nuklear/.gitignore deleted file mode 100644 index a9f3b636..00000000 --- a/deps/nuklear/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -demo/*/*.exe -demo/*/*.obj diff --git a/deps/nuklear/.travis.yml b/deps/nuklear/.travis.yml deleted file mode 100644 index 6d13e555..00000000 --- a/deps/nuklear/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: c - -os: - - linux - -compiler: - - gcc - - clang - -before_install: - - if [ $TRAVIS_OS_NAME == linux ]; then sudo add-apt-repository -y ppa:pyglfw/pyglfw && sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends libglfw3 libglfw3-dev libglew-dev; fi - -script: - - make -C demo/glfw_opengl3 - - make -C demo/glfw_opengl2 diff --git a/deps/nuklear/CHANGELOG.md b/deps/nuklear/CHANGELOG.md deleted file mode 100644 index fd981d4d..00000000 --- a/deps/nuklear/CHANGELOG.md +++ /dev/null @@ -1,192 +0,0 @@ -# Changelog -- 2016/12/31 (1.20) - Extended scrollbar offset from 16-bit to 32-bit -- 2016/12/31 (1.192)- Fixed closing window bug of minimized windows -- 2016/12/03 (1.191)- Fixed wrapped text with no seperator and C89 error -- 2016/12/03 (1.19) - Changed text wrapping to process words not characters -- 2016/11/22 (1.184)- Fixed window minimized closing bug -- 2016/11/19 (1.184)- Fixed abstract combo box closing behavior -- 2016/11/19 (1.184)- Fixed tooltip flickering -- 2016/11/19 (1.183)- Fixed memory leak caused by popup repeated closing -- 2016/11/18 (1.182)- Fixed memory leak caused by popup panel allocation -- 2016/11/10 (1.181)- Fixed some warnings and C++ error -- 2016/11/10 (1.180)- Added additional `nk_button` versions which allows to directly - pass in a style struct to change buttons visual. -- 2016/11/10 (1.180)- Added additional 'nk_tree' versions to support external state - storage. Just like last the `nk_group` commit the main - advantage is that you optionally can minimize nuklears runtime - memory consumption or handle hash collisions. -- 2016/11/09 (1.180)- Added additional `nk_group` version to support external scrollbar - offset storage. Main advantage is that you can externalize - the memory management for the offset. It could also be helpful - if you have a hash collision in `nk_group_begin` but really - want the name. In addition I added `nk_list_view` which allows - to draw big lists inside a group without actually having to - commit the whole list to nuklear (issue #269). -- 2016/10/30 (1.171)- Fixed clipping rectangle bug inside `nk_draw_list` -- 2016/10/29 (1.170)- Pulled `nk_panel` memory management into nuklear and out of - the hands of the user. From now on users don't have to care - about panels unless they care about some information. If you - still need the panel just call `nk_window_get_panel`. -- 2016/10/21 (1.160)- Changed widget border drawing to stroked rectangle from filled - rectangle for less overdraw and widget background transparency. -- 2016/10/18 (1.160)- Added `nk_edit_focus` for manually edit widget focus control -- 2016/09/29 (1.157)- Fixed deduction of basic type in non `` compilation -- 2016/09/29 (1.156)- Fixed edit widget UTF-8 text cursor drawing bug -- 2016/09/28 (1.156)- Fixed edit widget UTF-8 text appending/inserting/removing -- 2016/09/28 (1.156)- Fixed drawing bug inside edit widgets which offset all text - text in every edit widget if one of them is scrolled. -- 2016/09/28 (1.155)- Fixed small bug in edit widgets if not active. The wrong - text length is passed. It should have been in bytes but - was passed as glyphes. -- 2016/09/20 (1.154)- Fixed color button size calculation -- 2016/09/20 (1.153)- Fixed some `nk_vsnprintf` behavior bugs and removed - `` again from `NK_INCLUDE_STANDARD_VARARGS`. -- 2016/09/18 (1.152)- C89 does not support vsnprintf only C99 and newer as well - as C++11 and newer. In addition to use vsnprintf you have - to include . So just defining `NK_INCLUDE_STD_VAR_ARGS` - is not enough. That behavior is now fixed. By default if - both varargs as well as stdio is selected I try to use - vsnprintf if not possible I will revert to vsprintf. If - varargs but not stdio was defined I will use my own function. -- 2016/09/15 (1.151)- Fixed panel `close` behavior for deeper panel levels -- 2016/09/15 (1.151)- Fixed C++ errors and wrong argument to `nk_panel_get_xxxx` -- 2016/09/13 (1.15) - !BREAKING! Fixed nonblocking popup behavior in menu, combo, - and contextual which prevented closing in y-direction if - popup did not reach max height. - In addition the height parameter was changed into vec2 - for width and height to have more control over the popup size. -- 2016/09/13 (1.15) - Cleaned up and extended type selection -- 2016/09/13 (1.141)- Fixed slider behavior hopefully for the last time. This time - all calculation are correct so no more hackery. -- 2016/09/13 (1.141)- Internal change to divide window/panel flags into panel flags and types. - Suprisinly spend years in C and still happened to confuse types - with flags. Probably something to take note. -- 2016/09/08 (1.14)- Added additional helper function to make it easier to just - take the produced buffers from `nk_convert` and unplug the - iteration process from `nk_context`. So now you can - just use the vertex,element and command buffer + two pointer - inside the command buffer retrieved by calls `nk__draw_begin` - and `nk__draw_end` and macro `nk_draw_foreach_bounded`. -- 2016/09/08 (1.14)- Added additional asserts to make sure every `nk_xxx_begin` call - for windows, popups, combobox, menu and contextual is guarded by - `if` condition and does not produce false drawing output. -- 2016/09/08 (1.14)- Changed confusing name for `NK_SYMBOL_RECT_FILLED`, `NK_SYMBOL_RECT` - to hopefully easier to understand `NK_SYMBOL_RECT_FILLED` and - `NK_SYMBOL_RECT_OUTLINE`. -- 2016/09/08 (1.14)- Changed confusing name for `NK_SYMBOL_CIRLCE_FILLED`, `NK_SYMBOL_CIRCLE` - to hopefully easier to understand `NK_SYMBOL_CIRCLE_FILLED` and - `NK_SYMBOL_CIRCLE_OUTLINE`. -- 2016/09/08 (1.14)- Added additional checks to select correct types if `NK_INCLUDE_FIXED_TYPES` - is not defined by supporting the biggest compiler GCC, clang and MSVC. -- 2016/09/07 (1.133)- Fixed `NK_INCLUDE_COMMAND_USERDATA` define to not cause an error -- 2016/09/04 (1.132)- Fixed wrong combobox height calculation -- 2016/09/03 (1.131)- Fixed gaps inside combo boxes in OpenGL -- 2016/09/02 (1.13) - Changed nuklear to not have any default vertex layout and - instead made it user provided. The range of types to convert - to is quite limited at the moment, but I would be more than - happy to accept PRs to add additional. -- 2016/08/30 (1.12) - Removed unused variables -- 2016/08/30 (1.12) - Fixed C++ build errors -- 2016/08/30 (1.12) - Removed mouse dragging from SDL demo since it does not work correctly -- 2016/08/30 (1.12) - Tweaked some default styling variables -- 2016/08/30 (1.12) - Hopefully fixed drawing bug in slider, in general I would - refrain from using slider with a big number of steps. -- 2016/08/30 (1.12) - Fixed close and minimize button which would fire even if the - window was in Read Only Mode. -- 2016/08/30 (1.12) - Fixed popup panel padding handling which was previously just - a hack for combo box and menu. -- 2016/08/30 (1.12) - Removed `NK_WINDOW_DYNAMIC` flag from public API since - it is bugged and causes issues in window selection. -- 2016/08/30 (1.12) - Removed scaler size. The size of the scaler is now - determined by the scrollbar size -- 2016/08/30 (1.12) - Fixed some drawing bugs caused by changes from 1.11 -- 2016/08/30 (1.12) - Fixed overlapping minimized window selection -- 2016/08/30 (1.11) - Removed some internal complexity and overly complex code - handling panel padding and panel border. -- 2016/08/29 (1.10) - Added additional height parameter to `nk_combobox_xxx` -- 2016/08/29 (1.10) - Fixed drawing bug in dynamic popups -- 2016/08/29 (1.10) - Added experimental mouse scrolling to popups, menus and comboboxes -- 2016/08/26 (1.10) - Added window name string prepresentation to account for - hash collisions. Currently limited to NK_WINDOW_MAX_NAME - which in term can be redefined if not big enough. -- 2016/08/26 (1.10) - Added stacks for temporary style/UI changes in code -- 2016/08/25 (1.10) - Changed `nk_input_is_key_pressed` and 'nk_input_is_key_released' - to account for key press and release happening in one frame. -- 2016/08/25 (1.10) - Added additional nk_edit flag to directly jump to the end on activate -- 2016/08/17 (1.096)- Removed invalid check for value zero in nk_propertyx -- 2016/08/16 (1.095)- Fixed ROM mode for deeper levels of popup windows parents. -- 2016/08/15 (1.094)- Editbox are now still active if enter was pressed with flag - `NK_EDIT_SIG_ENTER`. Main reasoning is to be able to keep - typing after commiting. -- 2016/08/15 (1.094)- Removed redundant code -- 2016/08/15 (1.094)- Fixed negative numbers in `nk_strtoi` and remove unused variable -- 2016/08/15 (1.093)- Fixed `NK_WINDOW_BACKGROUND` flag behavior to select a background - window only as selected by hovering and not by clicking. -- 2016/08/14 (1.092)- Fixed a bug in font atlas which caused wrong loading - of glyphes for font with multiple ranges. -- 2016/08/12 (1.091)- Added additional function to check if window is currently - hidden and therefore not visible. -- 2016/08/12 (1.091)- nk_window_is_closed now queries the correct flag `NK_WINDOW_CLOSED` - instead of the old flag `NK_WINDOW_HIDDEN` -- 2016/08/09 (1.09) - Added additional double version to nk_property and changed - the underlying implementation to not cast to float and instead - work directly on the given values. -- 2016/08/09 (1.08) - Added additional define to overwrite library internal - floating pointer number to string conversion for additional - precision. -- 2016/08/09 (1.08) - Added additional define to overwrite library internal - string to floating point number conversion for additional - precision. -- 2016/08/08 (1.072)- Fixed compiling error without define NK_INCLUDE_FIXED_TYPE -- 2016/08/08 (1.071)- Fixed possible floating point error inside `nk_widget` leading - to wrong wiget width calculation which results in widgets falsly - becomming tagged as not inside window and cannot be accessed. -- 2016/08/08 (1.07) - Nuklear now differentiates between hiding a window (NK_WINDOW_HIDDEN) and - closing a window (NK_WINDOW_CLOSED). A window can be hidden/shown - by using `nk_window_show` and closed by either clicking the close - icon in a window or by calling `nk_window_close`. Only closed - windows get removed at the end of the frame while hidden windows - remain. -- 2016/08/08 (1.06) - Added `nk_edit_string_zero_terminated` as a second option to - `nk_edit_string` which takes, edits and outputs a '\0' terminated string. -- 2016/08/08 (1.054)- Fixed scrollbar auto hiding behavior -- 2016/08/08 (1.053)- Fixed wrong panel padding selection in `nk_layout_widget_space` -- 2016/08/07 (1.052)- Fixed old bug in dynamic immediate mode layout API, calculating - wrong item spacing and panel width. -- 2016/08/07 (1.051)- Hopefully finally fixed combobox popup drawing bug -- 2016/08/07 (1.05) - Split varargs away from NK_INCLUDE_STANDARD_IO into own - define NK_INCLUDE_STANDARD_VARARGS to allow more fine - grained controlled over library includes. -- 2016/08/06 (1.045)- Changed memset calls to NK_MEMSET -- 2016/08/04 (1.044)- Fixed fast window scaling behavior -- 2016/08/04 (1.043)- Fixed window scaling, movement bug which appears if you - move/scale a window and another window is behind it. - If you are fast enough then the window behind gets activated - and the operation is blocked. I now require activating - by hovering only if mouse is not pressed. -- 2016/08/04 (1.042)- Fixed changing fonts -- 2016/08/03 (1.041)- Fixed `NK_WINDOW_BACKGROUND` behavior -- 2016/08/03 (1.04) - Added color parameter to `nk_draw_image` -- 2016/08/03 (1.04) - Added additional window padding style attributes for - sub windows (combo, menu, ...) -- 2016/08/03 (1.04) - Added functions to show/hide software cursor -- 2016/08/03 (1.04) - Added `NK_WINDOW_BACKGROUND` flag to force a window - to be always in the background of the screen -- 2016/08/03 (1.032)- Removed invalid assert macro for NK_RGB color picker -- 2016/08/01 (1.031)- Added helper macros into header include guard -- 2016/07/29 (1.03) - Moved the window/table pool into the header part to - simplify memory management by removing the need to - allocate the pool. -- 2016/07/29 (1.03) - Added auto scrollbar hiding window flag which if enabled - will hide the window scrollbar after NK_SCROLLBAR_HIDING_TIMEOUT - seconds without window interaction. To make it work - you have to also set a delta time inside the `nk_context`. -- 2016/07/25 (1.02) - Fixed small panel and panel border drawing bugs -- 2016/07/15 (1.01) - Added software cursor to `nk_style` and `nk_context` -- 2016/07/15 (1.01) - Added const correctness to `nk_buffer_push' data argument -- 2016/07/15 (1.01) - Removed internal font baking API and simplified - font atlas memory management by converting pointer - arrays for fonts and font configurations to lists. -- 2016/07/15 (1.01) - Changed button API to use context dependend button - behavior instead of passing it for every function call. - diff --git a/deps/nuklear/Readme.md b/deps/nuklear/Readme.md deleted file mode 100644 index 665b05bc..00000000 --- a/deps/nuklear/Readme.md +++ /dev/null @@ -1,112 +0,0 @@ -[![Build Status](https://travis-ci.org/vurtun/nuklear.svg)](https://travis-ci.org/vurtun/nuklear) - -# Nuklear -This is a minimal state immediate mode graphical user interface toolkit -written in ANSI C and licensed under public domain. It was designed as a simple -embeddable user interface for application and does not have any dependencies, -a default renderbackend or OS window and input handling but instead provides a very modular -library approach by using simple input state for input and draw -commands describing primitive shapes as output. So instead of providing a -layered library that tries to abstract over a number of platform and -render backends it only focuses on the actual UI. - -## Features -- Immediate mode graphical user interface toolkit -- Single header library -- Written in C89 (ANSI C) -- Small codebase (~15kLOC) -- Focus on portability, efficiency and simplicity -- No dependencies (not even the standard library if not wanted) -- Fully skinnable and customizable -- Low memory footprint with total memory control if needed or wanted -- UTF-8 support -- No global or hidden state -- Customizable library modules (you can compile and use only what you need) -- Optional font baker and vertex buffer output - -## Building -This library is self contained in one single header file and can be used either -in header only mode or in implementation mode. The header only mode is used -by default when included and allows including this header in other headers -and does not contain the actual implementation. - -The implementation mode requires to define the preprocessor macro -`NK_IMPLEMENTATION` in *one* .c/.cpp file before `#include`ing this file, e.g.: -```c -#define NK_IMPLEMENTATION -#include "nuklear.h" -``` -IMPORTANT: Every time you include "nuklear.h" you have to define the same optional flags. -This is very important not doing it either leads to compiler errors or even worse stack corruptions. - -## Gallery -![screenshot](https://cloud.githubusercontent.com/assets/8057201/11761525/ae06f0ca-a0c6-11e5-819d-5610b25f6ef4.gif) -![screen](https://cloud.githubusercontent.com/assets/8057201/13538240/acd96876-e249-11e5-9547-5ac0b19667a0.png) -![screen2](https://cloud.githubusercontent.com/assets/8057201/13538243/b04acd4c-e249-11e5-8fd2-ad7744a5b446.png) -![node](https://cloud.githubusercontent.com/assets/8057201/9976995/e81ac04a-5ef7-11e5-872b-acd54fbeee03.gif) -![skinning](https://cloud.githubusercontent.com/assets/8057201/15991632/76494854-30b8-11e6-9555-a69840d0d50b.png) -![gamepad](https://cloud.githubusercontent.com/assets/8057201/14902576/339926a8-0d9c-11e6-9fee-a8b73af04473.png) - -## Example -```c -/* init gui state */ -struct nk_context ctx; -nk_init_fixed(&ctx, calloc(1, MAX_MEMORY), MAX_MEMORY, &font); - -enum {EASY, HARD}; -int op = EASY; -float value = 0.6f; -int i = 20; - -if (nk_begin(&ctx, "Show", nk_rect(50, 50, 220, 220), - NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_CLOSABLE)) { - /* fixed widget pixel width */ - nk_layout_row_static(&ctx, 30, 80, 1); - if (nk_button_label(&ctx, "button")) { - /* event handling */ - } - - /* fixed widget window ratio width */ - nk_layout_row_dynamic(&ctx, 30, 2); - if (nk_option_label(&ctx, "easy", op == EASY)) op = EASY; - if (nk_option_label(&ctx, "hard", op == HARD)) op = HARD; - - /* custom widget pixel width */ - nk_layout_row_begin(&ctx, NK_STATIC, 30, 2); - { - nk_layout_row_push(&ctx, 50); - nk_label(&ctx, "Volume:", NK_TEXT_LEFT); - nk_layout_row_push(&ctx, 110); - nk_slider_float(&ctx, 0, &value, 1.0f, 0.1f); - } - nk_layout_row_end(&ctx); -} -nk_end(&ctx); -``` -![example](https://cloud.githubusercontent.com/assets/8057201/10187981/584ecd68-675c-11e5-897c-822ef534a876.png) - -## Bindings: -Java: https://github.com/glegris/nuklear4j -Golang: https://github.com/golang-ui/nuklear -Rust: https://github.com/snuk182/nuklear-rust -Chicken: https://github.com/wasamasa/nuklear - -## Credits: -Developed by Micha Mettke and every direct or indirect contributor to the GitHub. - - -Embeds `stb_texedit`, `stb_truetype` and `stb_rectpack` by Sean Barret (public domain) -Embeds `ProggyClean.ttf` font by Tristan Grimmer (MIT license). - - -Big thank you to Omar Cornut (ocornut@github) for his [imgui](https://github.com/ocornut/imgui) library and -giving me the inspiration for this library, Casey Muratori for handmade hero -and his original immediate mode graphical user interface idea and Sean -Barret for his amazing single header [libraries](https://github.com/nothings/stb) which restored my faith -in libraries and brought me to create some of my own. - -## License: -This software is dual-licensed to the public domain and under the following -license: you are granted a perpetual, irrevocable license to copy, modify, -publish and distribute this file as you see fit. - diff --git a/deps/nuklear/demo/calculator.c b/deps/nuklear/demo/calculator.c deleted file mode 100644 index b871301b..00000000 --- a/deps/nuklear/demo/calculator.c +++ /dev/null @@ -1,64 +0,0 @@ -/* nuklear - v1.00 - public domain */ -static void -calculator(struct nk_context *ctx) -{ - if (nk_begin(ctx, "Calculator", nk_rect(10, 10, 180, 250), - NK_WINDOW_BORDER|NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_MOVABLE)) - { - static int set = 0, prev = 0, op = 0; - static const char numbers[] = "789456123"; - static const char ops[] = "+-*/"; - static double a = 0, b = 0; - static double *current = &a; - - size_t i = 0; - int solve = 0; - {int len; char buffer[256]; - nk_layout_row_dynamic(ctx, 35, 1); - len = snprintf(buffer, 256, "%.2f", *current); - nk_edit_string(ctx, NK_EDIT_SIMPLE, buffer, &len, 255, nk_filter_float); - buffer[len] = 0; - *current = atof(buffer);} - - nk_layout_row_dynamic(ctx, 35, 4); - for (i = 0; i < 16; ++i) { - if (i >= 12 && i < 15) { - if (i > 12) continue; - if (nk_button_label(ctx, "C")) { - a = b = op = 0; current = &a; set = 0; - } if (nk_button_label(ctx, "0")) { - *current = *current*10.0f; set = 0; - } if (nk_button_label(ctx, "=")) { - solve = 1; prev = op; op = 0; - } - } else if (((i+1) % 4)) { - if (nk_button_text(ctx, &numbers[(i/4)*3+i%4], 1)) { - *current = *current * 10.0f + numbers[(i/4)*3+i%4] - '0'; - set = 0; - } - } else if (nk_button_text(ctx, &ops[i/4], 1)) { - if (!set) { - if (current != &b) { - current = &b; - } else { - prev = op; - solve = 1; - } - } - op = ops[i/4]; - set = 1; - } - } - if (solve) { - if (prev == '+') a = a + b; - if (prev == '-') a = a - b; - if (prev == '*') a = a * b; - if (prev == '/') a = a / b; - current = &a; - if (set) current = &b; - b = 0; set = 0; - } - } - nk_end(ctx); -} - diff --git a/deps/nuklear/demo/d3d11/build.bat b/deps/nuklear/demo/d3d11/build.bat deleted file mode 100644 index 31bd0e05..00000000 --- a/deps/nuklear/demo/d3d11/build.bat +++ /dev/null @@ -1,9 +0,0 @@ -@echo off - -rem This will use VS2015 for compiler -call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86 - -fxc.exe /nologo /T vs_4_0_level_9_0 /E vs /O3 /Zpc /Ges /Fh nuklear_d3d11_vertex_shader.h /Vn nk_d3d11_vertex_shader /Qstrip_reflect /Qstrip_debug /Qstrip_priv nuklear_d3d11.hlsl -fxc.exe /nologo /T ps_4_0_level_9_0 /E ps /O3 /Zpc /Ges /Fh nuklear_d3d11_pixel_shader.h /Vn nk_d3d11_pixel_shader /Qstrip_reflect /Qstrip_debug /Qstrip_priv nuklear_d3d11.hlsl - -cl /D_CRT_SECURE_NO_DEPRECATE /nologo /W3 /O2 /fp:fast /Gm- /Fedemo.exe main.c user32.lib dxguid.lib d3d11.lib /link /incremental:no diff --git a/deps/nuklear/demo/d3d11/main.c b/deps/nuklear/demo/d3d11/main.c deleted file mode 100644 index 92ece1bb..00000000 --- a/deps/nuklear/demo/d3d11/main.c +++ /dev/null @@ -1,278 +0,0 @@ -/* nuklear - v1.17 - public domain */ -#define COBJMACROS -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#include -#include - -#define WINDOW_WIDTH 800 -#define WINDOW_HEIGHT 600 - -#define MAX_VERTEX_BUFFER 512 * 1024 -#define MAX_INDEX_BUFFER 128 * 1024 - -#define NK_INCLUDE_FIXED_TYPES -#define NK_INCLUDE_STANDARD_IO -#define NK_INCLUDE_STANDARD_VARARGS -#define NK_INCLUDE_DEFAULT_ALLOCATOR -#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT -#define NK_INCLUDE_FONT_BAKING -#define NK_INCLUDE_DEFAULT_FONT -#define NK_IMPLEMENTATION -#define NK_D3D11_IMPLEMENTATION -#include "../../nuklear.h" -#include "nuklear_d3d11.h" - -/* =============================================================== - * - * EXAMPLE - * - * ===============================================================*/ -/* This are some code examples to provide a small overview of what can be - * done with this library. To try out an example uncomment the include - * and the corresponding function. */ - #define UNUSED(a) (void)a - #define MIN(a,b) ((a) < (b) ? (a) : (b)) - #define MAX(a,b) ((a) < (b) ? (b) : (a)) - #define LEN(a) (sizeof(a)/sizeof(a)[0]) - -/*#include "../style.c"*/ -/*#include "../calculator.c"*/ -/*#include "../overview.c"*/ -/*#include "../node_editor.c"*/ - -/* =============================================================== - * - * DEMO - * - * ===============================================================*/ -static IDXGISwapChain *swap_chain; -static ID3D11Device *device; -static ID3D11DeviceContext *context; -static ID3D11RenderTargetView* rt_view; - -static void -set_swap_chain_size(int width, int height) -{ - ID3D11Texture2D *back_buffer; - D3D11_RENDER_TARGET_VIEW_DESC desc; - HRESULT hr; - - if (rt_view) - ID3D11RenderTargetView_Release(rt_view); - - ID3D11DeviceContext_OMSetRenderTargets(context, 0, NULL, NULL); - - hr = IDXGISwapChain_ResizeBuffers(swap_chain, 0, width, height, DXGI_FORMAT_UNKNOWN, 0); - if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET || hr == DXGI_ERROR_DRIVER_INTERNAL_ERROR) - { - /* to recover from this, you'll need to recreate device and all the resources */ - MessageBoxW(NULL, L"DXGI device is removed or reset!", L"Error", 0); - exit(0); - } - assert(SUCCEEDED(hr)); - - memset(&desc, 0, sizeof(desc)); - desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - - hr = IDXGISwapChain_GetBuffer(swap_chain, 0, &IID_ID3D11Texture2D, &back_buffer); - assert(SUCCEEDED(hr)); - - hr = ID3D11Device_CreateRenderTargetView(device, (ID3D11Resource *)back_buffer, &desc, &rt_view); - assert(SUCCEEDED(hr)); - - ID3D11Texture2D_Release(back_buffer); -} - -static LRESULT CALLBACK -WindowProc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam) -{ - switch (msg) - { - case WM_DESTROY: - PostQuitMessage(0); - return 0; - - case WM_SIZE: - if (swap_chain) - { - int width = LOWORD(lparam); - int height = HIWORD(lparam); - set_swap_chain_size(width, height); - nk_d3d11_resize(context, width, height); - } - break; - } - - if (nk_d3d11_handle_event(wnd, msg, wparam, lparam)) - return 0; - - return DefWindowProcW(wnd, msg, wparam, lparam); -} - -int main(void) -{ - struct nk_context *ctx; - struct nk_color background; - - WNDCLASSW wc; - RECT rect = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT }; - DWORD style = WS_OVERLAPPEDWINDOW; - DWORD exstyle = WS_EX_APPWINDOW; - HWND wnd; - int running = 1; - HRESULT hr; - D3D_FEATURE_LEVEL feature_level; - DXGI_SWAP_CHAIN_DESC swap_chain_desc; - - /* Win32 */ - memset(&wc, 0, sizeof(wc)); - wc.lpfnWndProc = WindowProc; - wc.hInstance = GetModuleHandleW(0); - wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.lpszClassName = L"NuklearWindowClass"; - RegisterClassW(&wc); - - AdjustWindowRectEx(&rect, style, FALSE, exstyle); - - wnd = CreateWindowExW(exstyle, wc.lpszClassName, L"Nuklear Demo", - style | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, - rect.right - rect.left, rect.bottom - rect.top, - NULL, NULL, wc.hInstance, NULL); - - /* D3D11 setup */ - memset(&swap_chain_desc, 0, sizeof(swap_chain_desc)); - swap_chain_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - swap_chain_desc.BufferDesc.RefreshRate.Numerator = 60; - swap_chain_desc.BufferDesc.RefreshRate.Denominator = 1; - swap_chain_desc.SampleDesc.Count = 1; - swap_chain_desc.SampleDesc.Quality = 0; - swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swap_chain_desc.BufferCount = 1; - swap_chain_desc.OutputWindow = wnd; - swap_chain_desc.Windowed = TRUE; - swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; - swap_chain_desc.Flags = 0; - if (FAILED(D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, - NULL, 0, NULL, 0, D3D11_SDK_VERSION, &swap_chain_desc, - &swap_chain, &device, &feature_level, &context))) - { - /* if hardware device fails, then try WARP high-performance - software rasterizer, this is useful for RDP sessions */ - hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_WARP, - NULL, 0, NULL, 0, D3D11_SDK_VERSION, &swap_chain_desc, - &swap_chain, &device, &feature_level, &context); - assert(SUCCEEDED(hr)); - } - set_swap_chain_size(WINDOW_WIDTH, WINDOW_HEIGHT); - - /* GUI */ - ctx = nk_d3d11_init(device, WINDOW_WIDTH, WINDOW_HEIGHT, MAX_VERTEX_BUFFER, MAX_INDEX_BUFFER); - /* Load Fonts: if none of these are loaded a default font will be used */ - /* Load Cursor: if you uncomment cursor loading please hide the cursor */ - {struct nk_font_atlas *atlas; - nk_d3d11_font_stash_begin(&atlas); - /*struct nk_font *droid = nk_font_atlas_add_from_file(atlas, "../../extra_font/DroidSans.ttf", 14, 0);*/ - /*struct nk_font *robot = nk_font_atlas_add_from_file(atlas, "../../extra_font/Roboto-Regular.ttf", 14, 0);*/ - /*struct nk_font *future = nk_font_atlas_add_from_file(atlas, "../../extra_font/kenvector_future_thin.ttf", 13, 0);*/ - /*struct nk_font *clean = nk_font_atlas_add_from_file(atlas, "../../extra_font/ProggyClean.ttf", 12, 0);*/ - /*struct nk_font *tiny = nk_font_atlas_add_from_file(atlas, "../../extra_font/ProggyTiny.ttf", 10, 0);*/ - /*struct nk_font *cousine = nk_font_atlas_add_from_file(atlas, "../../extra_font/Cousine-Regular.ttf", 13, 0);*/ - nk_d3d11_font_stash_end(); - /*nk_style_load_all_cursors(ctx, atlas->cursors);*/ - /*nk_style_set_font(ctx, &droid->handle)*/;} - - /* style.c */ - /*set_style(ctx, THEME_WHITE);*/ - /*set_style(ctx, THEME_RED);*/ - /*set_style(ctx, THEME_BLUE);*/ - /*set_style(ctx, THEME_DARK);*/ - - background = nk_rgb(28,48,62); - while (running) - { - /* Input */ - MSG msg; - nk_input_begin(ctx); - while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) - { - if (msg.message == WM_QUIT) - running = 0; - TranslateMessage(&msg); - DispatchMessageW(&msg); - } - nk_input_end(ctx); - - /* GUI */ - if (nk_begin(ctx, "Demo", nk_rect(50, 50, 230, 250), - NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE| - NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE)) - { - enum {EASY, HARD}; - static int op = EASY; - static int property = 20; - - nk_layout_row_static(ctx, 30, 80, 1); - if (nk_button_label(ctx, "button")) - fprintf(stdout, "button pressed\n"); - nk_layout_row_dynamic(ctx, 30, 2); - if (nk_option_label(ctx, "easy", op == EASY)) op = EASY; - if (nk_option_label(ctx, "hard", op == HARD)) op = HARD; - nk_layout_row_dynamic(ctx, 22, 1); - nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1); - - nk_layout_row_dynamic(ctx, 20, 1); - nk_label(ctx, "background:", NK_TEXT_LEFT); - nk_layout_row_dynamic(ctx, 25, 1); - if (nk_combo_begin_color(ctx, background, nk_vec2(nk_widget_width(ctx),400))) { - nk_layout_row_dynamic(ctx, 120, 1); - background = nk_color_picker(ctx, background, NK_RGBA); - nk_layout_row_dynamic(ctx, 25, 1); - background.r = (nk_byte)nk_propertyi(ctx, "#R:", 0, background.r, 255, 1,1); - background.g = (nk_byte)nk_propertyi(ctx, "#G:", 0, background.g, 255, 1,1); - background.b = (nk_byte)nk_propertyi(ctx, "#B:", 0, background.b, 255, 1,1); - background.a = (nk_byte)nk_propertyi(ctx, "#A:", 0, background.a, 255, 1,1); - nk_combo_end(ctx); - } - } - nk_end(ctx); - if (nk_window_is_closed(ctx, "Demo")) break; - - /* -------------- EXAMPLES ---------------- */ - /*calculator(ctx);*/ - /*overview(ctx);*/ - /*node_editor(ctx);*/ - /* ----------------------------------------- */ - - {/* Draw */ - float bg[4]; - nk_color_fv(bg, background); - ID3D11DeviceContext_ClearRenderTargetView(context, rt_view, bg); - ID3D11DeviceContext_OMSetRenderTargets(context, 1, &rt_view, NULL); - nk_d3d11_render(context, NK_ANTI_ALIASING_ON); - hr = IDXGISwapChain_Present(swap_chain, 1, 0); - if (hr == DXGI_ERROR_DEVICE_RESET || hr == DXGI_ERROR_DEVICE_REMOVED) { - /* to recover from this, you'll need to recreate device and all the resources */ - MessageBoxW(NULL, L"D3D11 device is lost or removed!", L"Error", 0); - break; - } else if (hr == DXGI_STATUS_OCCLUDED) { - /* window is not visible, so vsync won't work. Let's sleep a bit to reduce CPU usage */ - Sleep(10); - } - assert(SUCCEEDED(hr));} - } - - ID3D11DeviceContext_ClearState(context); - nk_d3d11_shutdown(); - ID3D11ShaderResourceView_Release(rt_view); - ID3D11DeviceContext_Release(context); - ID3D11Device_Release(device); - IDXGISwapChain_Release(swap_chain); - UnregisterClassW(wc.lpszClassName, wc.hInstance); - return 0; -} diff --git a/deps/nuklear/demo/d3d11/nuklear_d3d11.h b/deps/nuklear/demo/d3d11/nuklear_d3d11.h deleted file mode 100644 index efddf0d2..00000000 --- a/deps/nuklear/demo/d3d11/nuklear_d3d11.h +++ /dev/null @@ -1,617 +0,0 @@ -/* - * Nuklear - v1.17 - public domain - * no warrenty implied; use at your own risk. - * authored from 2015-2016 by Micha Mettke - */ -/* - * ============================================================== - * - * API - * - * =============================================================== - */ -#ifndef NK_D3D11_H_ -#define NK_D3D11_H_ - -#define WIN32_LEAN_AND_MEAN -#include - -typedef struct ID3D11Device ID3D11Device; -typedef struct ID3D11DeviceContext ID3D11DeviceContext; - -NK_API struct nk_context *nk_d3d11_init(ID3D11Device *device, int width, int height, unsigned int max_vertex_buffer, unsigned int max_index_buffer); -NK_API void nk_d3d11_font_stash_begin(struct nk_font_atlas **atlas); -NK_API void nk_d3d11_font_stash_end(void); -NK_API int nk_d3d11_handle_event(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); -NK_API void nk_d3d11_render(ID3D11DeviceContext *context, enum nk_anti_aliasing); -NK_API void nk_d3d11_resize(ID3D11DeviceContext *context, int width, int height); -NK_API void nk_d3d11_shutdown(void); - -#endif -/* - * ============================================================== - * - * IMPLEMENTATION - * - * =============================================================== - */ -#ifdef NK_D3D11_IMPLEMENTATION - -#define WIN32_LEAN_AND_MEAN -#define COBJMACROS -#include - -#include -#include -#include -#include - -#include "nuklear_d3d11_vertex_shader.h" -#include "nuklear_d3d11_pixel_shader.h" - -struct nk_d3d11_vertex { - float position[2]; - float uv[2]; - nk_byte col[4]; -}; - -static struct -{ - struct nk_context ctx; - struct nk_font_atlas atlas; - struct nk_buffer cmds; - - struct nk_draw_null_texture null; - unsigned int max_vertex_buffer; - unsigned int max_index_buffer; - - D3D11_VIEWPORT viewport; - ID3D11Device *device; - ID3D11RasterizerState *rasterizer_state; - ID3D11VertexShader *vertex_shader; - ID3D11InputLayout *input_layout; - ID3D11Buffer *const_buffer; - ID3D11PixelShader *pixel_shader; - ID3D11BlendState *blend_state; - ID3D11Buffer *index_buffer; - ID3D11Buffer *vertex_buffer; - ID3D11ShaderResourceView *font_texture_view; - ID3D11SamplerState *sampler_state; -} d3d11; - -NK_API void -nk_d3d11_render(ID3D11DeviceContext *context, enum nk_anti_aliasing AA) -{ - const float blend_factor[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - const UINT stride = sizeof(struct nk_d3d11_vertex); - const UINT offset = 0; - - ID3D11DeviceContext_IASetInputLayout(context, d3d11.input_layout); - ID3D11DeviceContext_IASetVertexBuffers(context, 0, 1, &d3d11.vertex_buffer, &stride, &offset); - ID3D11DeviceContext_IASetIndexBuffer(context, d3d11.index_buffer, DXGI_FORMAT_R16_UINT, 0); - ID3D11DeviceContext_IASetPrimitiveTopology(context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - - ID3D11DeviceContext_VSSetShader(context, d3d11.vertex_shader, NULL, 0); - ID3D11DeviceContext_VSSetConstantBuffers(context, 0, 1, &d3d11.const_buffer); - - ID3D11DeviceContext_PSSetShader(context, d3d11.pixel_shader, NULL, 0); - ID3D11DeviceContext_PSSetSamplers(context, 0, 1, &d3d11.sampler_state); - - ID3D11DeviceContext_OMSetBlendState(context, d3d11.blend_state, blend_factor, 0xffffffff); - ID3D11DeviceContext_RSSetState(context, d3d11.rasterizer_state); - ID3D11DeviceContext_RSSetViewports(context, 1, &d3d11.viewport); - - /* Convert from command queue into draw list and draw to screen */ - {/* load draw vertices & elements directly into vertex + element buffer */ - D3D11_MAPPED_SUBRESOURCE vertices; - D3D11_MAPPED_SUBRESOURCE indices; - const struct nk_draw_command *cmd; - UINT offset = 0; - HRESULT hr; - - hr = ID3D11DeviceContext_Map(context, (ID3D11Resource *)d3d11.vertex_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &vertices); - NK_ASSERT(SUCCEEDED(hr)); - hr = ID3D11DeviceContext_Map(context, (ID3D11Resource *)d3d11.index_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &indices); - NK_ASSERT(SUCCEEDED(hr)); - - {/* fill converting configuration */ - struct nk_convert_config config; - NK_STORAGE const struct nk_draw_vertex_layout_element vertex_layout[] = { - {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_d3d11_vertex, position)}, - {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_d3d11_vertex, uv)}, - {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_d3d11_vertex, col)}, - {NK_VERTEX_LAYOUT_END} - }; - memset(&config, 0, sizeof(config)); - config.vertex_layout = vertex_layout; - config.vertex_size = sizeof(struct nk_d3d11_vertex); - config.vertex_alignment = NK_ALIGNOF(struct nk_d3d11_vertex); - config.global_alpha = 1.0f; - config.shape_AA = AA; - config.line_AA = AA; - config.circle_segment_count = 22; - config.curve_segment_count = 22; - config.arc_segment_count = 22; - config.null = d3d11.null; - - {/* setup buffers to load vertices and elements */ - struct nk_buffer vbuf, ibuf; - nk_buffer_init_fixed(&vbuf, vertices.pData, (size_t)d3d11.max_vertex_buffer); - nk_buffer_init_fixed(&ibuf, indices.pData, (size_t)d3d11.max_index_buffer); - nk_convert(&d3d11.ctx, &d3d11.cmds, &vbuf, &ibuf, &config);} - } - - ID3D11DeviceContext_Unmap(context, (ID3D11Resource *)d3d11.vertex_buffer, 0); - ID3D11DeviceContext_Unmap(context, (ID3D11Resource *)d3d11.index_buffer, 0); - - /* iterate over and execute each draw command */ - nk_draw_foreach(cmd, &d3d11.ctx, &d3d11.cmds) - { - D3D11_RECT scissor; - ID3D11ShaderResourceView *texture_view = (ID3D11ShaderResourceView *)cmd->texture.ptr; - if (!cmd->elem_count) continue; - - scissor.left = (LONG)cmd->clip_rect.x; - scissor.right = (LONG)(cmd->clip_rect.x + cmd->clip_rect.w); - scissor.top = (LONG)cmd->clip_rect.y; - scissor.bottom = (LONG)(cmd->clip_rect.y + cmd->clip_rect.h); - - ID3D11DeviceContext_PSSetShaderResources(context, 0, 1, &texture_view); - ID3D11DeviceContext_RSSetScissorRects(context, 1, &scissor); - ID3D11DeviceContext_DrawIndexed(context, (UINT)cmd->elem_count, offset, 0); - offset += cmd->elem_count; - } - nk_clear(&d3d11.ctx);} -} - -static void -nk_d3d11_get_projection_matrix(int width, int height, float *result) -{ - const float L = 0.0f; - const float R = (float)width; - const float T = 0.0f; - const float B = (float)height; - float matrix[4][4] = - { - { 2.0f / (R - L), 0.0f, 0.0f, 0.0f }, - { 0.0f, 2.0f / (T - B), 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.5f, 0.0f }, - { (R + L) / (L - R), (T + B) / (B - T), 0.5f, 1.0f }, - }; - memcpy(result, matrix, sizeof(matrix)); -} - -NK_API void -nk_d3d11_resize(ID3D11DeviceContext *context, int width, int height) -{ - D3D11_MAPPED_SUBRESOURCE mapped; - if (SUCCEEDED(ID3D11DeviceContext_Map(context, (ID3D11Resource *)d3d11.const_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped))) - { - nk_d3d11_get_projection_matrix(width, height, (float *)mapped.pData); - ID3D11DeviceContext_Unmap(context, (ID3D11Resource *)d3d11.const_buffer, 0); - - d3d11.viewport.Width = (float)width; - d3d11.viewport.Height = (float)height; - } -} - -NK_API int -nk_d3d11_handle_event(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam) -{ - switch (msg) - { - case WM_KEYDOWN: - case WM_KEYUP: - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - { - int down = !((lparam >> 31) & 1); - int ctrl = GetKeyState(VK_CONTROL) & (1 << 15); - - switch (wparam) - { - case VK_SHIFT: - case VK_LSHIFT: - case VK_RSHIFT: - nk_input_key(&d3d11.ctx, NK_KEY_SHIFT, down); - return 1; - - case VK_DELETE: - nk_input_key(&d3d11.ctx, NK_KEY_DEL, down); - return 1; - - case VK_RETURN: - nk_input_key(&d3d11.ctx, NK_KEY_ENTER, down); - return 1; - - case VK_TAB: - nk_input_key(&d3d11.ctx, NK_KEY_TAB, down); - return 1; - - case VK_LEFT: - if (ctrl) - nk_input_key(&d3d11.ctx, NK_KEY_TEXT_WORD_LEFT, down); - else - nk_input_key(&d3d11.ctx, NK_KEY_LEFT, down); - return 1; - - case VK_RIGHT: - if (ctrl) - nk_input_key(&d3d11.ctx, NK_KEY_TEXT_WORD_RIGHT, down); - else - nk_input_key(&d3d11.ctx, NK_KEY_RIGHT, down); - return 1; - - case VK_BACK: - nk_input_key(&d3d11.ctx, NK_KEY_BACKSPACE, down); - return 1; - - case VK_HOME: - nk_input_key(&d3d11.ctx, NK_KEY_TEXT_START, down); - nk_input_key(&d3d11.ctx, NK_KEY_SCROLL_START, down); - return 1; - - case VK_END: - nk_input_key(&d3d11.ctx, NK_KEY_TEXT_END, down); - nk_input_key(&d3d11.ctx, NK_KEY_SCROLL_END, down); - return 1; - - case VK_NEXT: - nk_input_key(&d3d11.ctx, NK_KEY_SCROLL_DOWN, down); - return 1; - - case VK_PRIOR: - nk_input_key(&d3d11.ctx, NK_KEY_SCROLL_UP, down); - return 1; - - case 'C': - if (ctrl) { - nk_input_key(&d3d11.ctx, NK_KEY_COPY, down); - return 1; - } - break; - - case 'V': - if (ctrl) { - nk_input_key(&d3d11.ctx, NK_KEY_PASTE, down); - return 1; - } - break; - - case 'X': - if (ctrl) { - nk_input_key(&d3d11.ctx, NK_KEY_CUT, down); - return 1; - } - break; - - case 'Z': - if (ctrl) { - nk_input_key(&d3d11.ctx, NK_KEY_TEXT_UNDO, down); - return 1; - } - break; - - case 'R': - if (ctrl) { - nk_input_key(&d3d11.ctx, NK_KEY_TEXT_REDO, down); - return 1; - } - break; - } - return 0; - } - - case WM_CHAR: - if (wparam >= 32) - { - nk_input_unicode(&d3d11.ctx, (nk_rune)wparam); - return 1; - } - break; - - case WM_LBUTTONDOWN: - nk_input_button(&d3d11.ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1); - SetCapture(wnd); - return 1; - - case WM_LBUTTONUP: - nk_input_button(&d3d11.ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0); - ReleaseCapture(); - return 1; - - case WM_RBUTTONDOWN: - nk_input_button(&d3d11.ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1); - SetCapture(wnd); - return 1; - - case WM_RBUTTONUP: - nk_input_button(&d3d11.ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0); - ReleaseCapture(); - return 1; - - case WM_MBUTTONDOWN: - nk_input_button(&d3d11.ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 1); - SetCapture(wnd); - return 1; - - case WM_MBUTTONUP: - nk_input_button(&d3d11.ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 0); - ReleaseCapture(); - return 1; - - case WM_MOUSEWHEEL: - nk_input_scroll(&d3d11.ctx, (float)(short)HIWORD(wparam) / WHEEL_DELTA); - return 1; - - case WM_MOUSEMOVE: - nk_input_motion(&d3d11.ctx, (short)LOWORD(lparam), (short)HIWORD(lparam)); - return 1; - } - - return 0; -} - -static void -nk_d3d11_clipbard_paste(nk_handle usr, struct nk_text_edit *edit) -{ - (void)usr; - if (IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL)) - { - HGLOBAL mem = GetClipboardData(CF_UNICODETEXT); - if (mem) - { - SIZE_T size = GlobalSize(mem) - 1; - if (size) - { - LPCWSTR wstr = (LPCWSTR)GlobalLock(mem); - if (wstr) - { - int utf8size = WideCharToMultiByte(CP_UTF8, 0, wstr, size / sizeof(wchar_t), NULL, 0, NULL, NULL); - if (utf8size) - { - char* utf8 = (char*)malloc(utf8size); - if (utf8) - { - WideCharToMultiByte(CP_UTF8, 0, wstr, size / sizeof(wchar_t), utf8, utf8size, NULL, NULL); - nk_textedit_paste(edit, utf8, utf8size); - free(utf8); - } - } - GlobalUnlock(mem); - } - } - } - CloseClipboard(); - } -} - -static void -nk_d3d11_clipbard_copy(nk_handle usr, const char *text, int len) -{ - (void)usr; - if (OpenClipboard(NULL)) - { - int wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0); - if (wsize) - { - HGLOBAL mem = GlobalAlloc(GMEM_MOVEABLE, (wsize + 1) * sizeof(wchar_t)); - if (mem) - { - wchar_t* wstr = (wchar_t*)GlobalLock(mem); - if (wstr) - { - MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize); - wstr[wsize] = 0; - GlobalUnlock(mem); - SetClipboardData(CF_UNICODETEXT, mem); - } - } - } - CloseClipboard(); - } -} - -NK_API struct nk_context* -nk_d3d11_init(ID3D11Device *device, int width, int height, unsigned int max_vertex_buffer, unsigned int max_index_buffer) -{ - HRESULT hr; - d3d11.max_vertex_buffer = max_vertex_buffer; - d3d11.max_index_buffer = max_index_buffer; - d3d11.device = device; - ID3D11Device_AddRef(device); - - nk_init_default(&d3d11.ctx, 0); - d3d11.ctx.clip.copy = nk_d3d11_clipbard_copy; - d3d11.ctx.clip.paste = nk_d3d11_clipbard_paste; - d3d11.ctx.clip.userdata = nk_handle_ptr(0); - - nk_buffer_init_default(&d3d11.cmds); - - {/* rasterizer state */ - D3D11_RASTERIZER_DESC desc; - memset(&desc, 0, sizeof(desc)); - desc.FillMode = D3D11_FILL_SOLID; - desc.CullMode = D3D11_CULL_NONE; - desc.FrontCounterClockwise = FALSE; - desc.DepthBias = 0; - desc.DepthBiasClamp = 0; - desc.SlopeScaledDepthBias = 0.0f; - desc.DepthClipEnable = TRUE; - desc.ScissorEnable = TRUE; - desc.MultisampleEnable = FALSE; - desc.AntialiasedLineEnable = FALSE; - hr = ID3D11Device_CreateRasterizerState(device,&desc, &d3d11.rasterizer_state); - NK_ASSERT(SUCCEEDED(hr));} - - /* vertex shader */ - {hr = ID3D11Device_CreateVertexShader(device,nk_d3d11_vertex_shader, sizeof(nk_d3d11_vertex_shader), NULL, &d3d11.vertex_shader); - NK_ASSERT(SUCCEEDED(hr));} - - /* input layout */ - {const D3D11_INPUT_ELEMENT_DESC layout[] = { - { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(struct nk_d3d11_vertex, position), D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(struct nk_d3d11_vertex, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(struct nk_d3d11_vertex, col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, - }; - hr = ID3D11Device_CreateInputLayout(device,layout, ARRAYSIZE(layout), nk_d3d11_vertex_shader, sizeof(nk_d3d11_vertex_shader), &d3d11.input_layout); - NK_ASSERT(SUCCEEDED(hr));} - - /* constant buffer */ - {float matrix[4*4]; - D3D11_BUFFER_DESC desc; - memset(&desc, 0, sizeof(desc)); - desc.ByteWidth = sizeof(matrix); - desc.Usage = D3D11_USAGE_DYNAMIC; - desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - desc.MiscFlags = 0; - - {D3D11_SUBRESOURCE_DATA data; - data.pSysMem = matrix; - data.SysMemPitch = 0; - data.SysMemSlicePitch = 0; - - nk_d3d11_get_projection_matrix(width, height, matrix); - hr = ID3D11Device_CreateBuffer(device, &desc, &data, &d3d11.const_buffer); - NK_ASSERT(SUCCEEDED(hr));}} - - /* pixel shader */ - {hr = ID3D11Device_CreatePixelShader(device, nk_d3d11_pixel_shader, sizeof(nk_d3d11_pixel_shader), NULL, &d3d11.pixel_shader); - NK_ASSERT(SUCCEEDED(hr));} - - {/* blend state */ - D3D11_BLEND_DESC desc; - memset(&desc, 0, sizeof(desc)); - desc.AlphaToCoverageEnable = FALSE; - desc.RenderTarget[0].BlendEnable = TRUE; - desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; - desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; - hr = ID3D11Device_CreateBlendState(device, &desc, &d3d11.blend_state); - NK_ASSERT(SUCCEEDED(hr));} - - /* vertex buffer */ - {D3D11_BUFFER_DESC desc; - memset(&desc, 0, sizeof(desc)); - desc.Usage = D3D11_USAGE_DYNAMIC; - desc.ByteWidth = max_vertex_buffer; - desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - desc.MiscFlags = 0; - hr = ID3D11Device_CreateBuffer(device, &desc, NULL, &d3d11.vertex_buffer); - NK_ASSERT(SUCCEEDED(hr));} - - /* index buffer */ - {D3D11_BUFFER_DESC desc; - memset(&desc, 0, sizeof(desc)); - desc.Usage = D3D11_USAGE_DYNAMIC; - desc.ByteWidth = max_index_buffer; - desc.BindFlags = D3D11_BIND_INDEX_BUFFER; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - hr = ID3D11Device_CreateBuffer(device, &desc, NULL, &d3d11.index_buffer); - NK_ASSERT(SUCCEEDED(hr));} - - /* sampler state */ - {D3D11_SAMPLER_DESC desc; - memset(&desc, 0, sizeof(desc)); - desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; - desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; - desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; - desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - desc.MipLODBias = 0.0f; - desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; - desc.MinLOD = 0.0f; - desc.MaxLOD = FLT_MAX; - hr = ID3D11Device_CreateSamplerState(device, &desc, &d3d11.sampler_state); - NK_ASSERT(SUCCEEDED(hr));} - - /* viewport */ - {d3d11.viewport.TopLeftX = 0.0f; - d3d11.viewport.TopLeftY = 0.0f; - d3d11.viewport.Width = (float)width; - d3d11.viewport.Height = (float)height; - d3d11.viewport.MinDepth = 0.0f; - d3d11.viewport.MaxDepth = 1.0f;} - return &d3d11.ctx; -} - -NK_API void -nk_d3d11_font_stash_begin(struct nk_font_atlas **atlas) -{ - nk_font_atlas_init_default(&d3d11.atlas); - nk_font_atlas_begin(&d3d11.atlas); - *atlas = &d3d11.atlas; -} - -NK_API void -nk_d3d11_font_stash_end(void) -{ - const void *image; int w, h; - image = nk_font_atlas_bake(&d3d11.atlas, &w, &h, NK_FONT_ATLAS_RGBA32); - - /* upload font to texture and create texture view */ - {ID3D11Texture2D *font_texture; - HRESULT hr; - - D3D11_TEXTURE2D_DESC desc; - memset(&desc, 0, sizeof(desc)); - desc.Width = (UINT)w; - desc.Height = (UINT)h; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc.CPUAccessFlags = 0; - - {D3D11_SUBRESOURCE_DATA data; - data.pSysMem = image; - data.SysMemPitch = (UINT)(w * 4); - data.SysMemSlicePitch = 0; - hr = ID3D11Device_CreateTexture2D(d3d11.device, &desc, &data, &font_texture); - assert(SUCCEEDED(hr));} - - {D3D11_SHADER_RESOURCE_VIEW_DESC srv; - memset(&srv, 0, sizeof(srv)); - srv.Format = desc.Format; - srv.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srv.Texture2D.MipLevels = 1; - srv.Texture2D.MostDetailedMip = 0; - hr = ID3D11Device_CreateShaderResourceView(d3d11.device, (ID3D11Resource *)font_texture, &srv, &d3d11.font_texture_view); - assert(SUCCEEDED(hr));} - ID3D11Texture2D_Release(font_texture);} - - nk_font_atlas_end(&d3d11.atlas, nk_handle_ptr(d3d11.font_texture_view), &d3d11.null); - if (d3d11.atlas.default_font) - nk_style_set_font(&d3d11.ctx, &d3d11.atlas.default_font->handle); -} - -NK_API -void nk_d3d11_shutdown(void) -{ - nk_font_atlas_clear(&d3d11.atlas); - nk_buffer_free(&d3d11.cmds); - nk_free(&d3d11.ctx); - - ID3D11SamplerState_Release(d3d11.sampler_state); - ID3D11ShaderResourceView_Release(d3d11.font_texture_view); - ID3D11Buffer_Release(d3d11.vertex_buffer); - ID3D11Buffer_Release(d3d11.index_buffer); - ID3D11BlendState_Release(d3d11.blend_state); - ID3D11PixelShader_Release(d3d11.pixel_shader); - ID3D11Buffer_Release(d3d11.const_buffer); - ID3D11VertexShader_Release(d3d11.vertex_shader); - ID3D11InputLayout_Release(d3d11.input_layout); - ID3D11RasterizerState_Release(d3d11.rasterizer_state); - ID3D11Device_Release(d3d11.device); -} - -#endif - diff --git a/deps/nuklear/demo/d3d11/nuklear_d3d11.hlsl b/deps/nuklear/demo/d3d11/nuklear_d3d11.hlsl deleted file mode 100644 index a932dcab..00000000 --- a/deps/nuklear/demo/d3d11/nuklear_d3d11.hlsl +++ /dev/null @@ -1,36 +0,0 @@ -// -cbuffer buffer0 : register(b0) -{ - float4x4 ProjectionMatrix; -}; - -sampler sampler0 : register(s0); -Texture2D texture0 : register(t0); - -struct VS_INPUT -{ - float2 pos : POSITION; - float4 col : COLOR0; - float2 uv : TEXCOORD0; -}; - -struct PS_INPUT -{ - float4 pos : SV_POSITION; - float4 col : COLOR0; - float2 uv : TEXCOORD0; -}; - -PS_INPUT vs(VS_INPUT input) -{ - PS_INPUT output; - output.pos = mul(ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f)); - output.col = input.col; - output.uv = input.uv; - return output; -} - -float4 ps(PS_INPUT input) : SV_Target -{ - return input.col * texture0.Sample(sampler0, input.uv); -} diff --git a/deps/nuklear/demo/d3d11/nuklear_d3d11_pixel_shader.h b/deps/nuklear/demo/d3d11/nuklear_d3d11_pixel_shader.h deleted file mode 100644 index 1447559e..00000000 --- a/deps/nuklear/demo/d3d11/nuklear_d3d11_pixel_shader.h +++ /dev/null @@ -1,179 +0,0 @@ -#if 0 -// -// Generated by Microsoft (R) D3D Shader Disassembler -// -// -// Input signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// SV_POSITION 0 xyzw 0 POS float -// COLOR 0 xyzw 1 NONE float xyzw -// TEXCOORD 0 xy 2 NONE float xy -// -// -// Output signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// SV_Target 0 xyzw 0 TARGET float xyzw -// -// -// Sampler/Resource to DX9 shader sampler mappings: -// -// Target Sampler Source Sampler Source Resource -// -------------- --------------- ---------------- -// s0 s0 t0 -// -// -// Level9 shader bytecode: -// - ps_2_0 - dcl t0 - dcl t1.xy - dcl_2d s0 - texld r0, t1, s0 - mul r0, r0, t0 - mov oC0, r0 - -// approximately 3 instruction slots used (1 texture, 2 arithmetic) -// -// Sampler/Resource to DX9 shader sampler mappings: -// -// Target Sampler Source Sampler Source Resource -// -------------- --------------- ---------------- -// s0 s0 t0 -// -// -// XNA shader bytecode: -// - ps_2_0 - dcl t0 - dcl t1.xy - dcl_2d s0 - texld r0, r2, s0 - mul oC0, r0, r1 - -// approximately 2 instruction slots used (1 texture, 1 arithmetic) -ps_4_0 -dcl_sampler s0, mode_default -dcl_resource_texture2d (float,float,float,float) t0 -dcl_input_ps linear v1.xyzw -dcl_input_ps linear v2.xy -dcl_output o0.xyzw -dcl_temps 1 -sample r0.xyzw, v2.xyxx, t0.xyzw, s0 -mul o0.xyzw, r0.xyzw, v1.xyzw -ret -// Approximately 0 instruction slots used -#endif - -const BYTE nk_d3d11_pixel_shader[] = -{ - 68, 88, 66, 67, 249, 46, - 26, 75, 111, 182, 161, 241, - 199, 179, 191, 89, 44, 229, - 245, 103, 1, 0, 0, 0, - 124, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 176, 0, 0, 0, 56, 1, - 0, 0, 212, 1, 0, 0, - 72, 2, 0, 0, 88, 78, - 65, 83, 116, 0, 0, 0, - 116, 0, 0, 0, 0, 2, - 255, 255, 76, 0, 0, 0, - 40, 0, 0, 0, 0, 0, - 40, 0, 0, 0, 40, 0, - 0, 0, 40, 0, 1, 0, - 36, 0, 0, 0, 40, 0, - 0, 0, 0, 0, 0, 2, - 255, 255, 31, 0, 0, 2, - 0, 0, 0, 128, 0, 0, - 15, 176, 31, 0, 0, 2, - 0, 0, 0, 128, 1, 0, - 3, 176, 31, 0, 0, 2, - 0, 0, 0, 144, 0, 8, - 15, 160, 66, 0, 0, 3, - 0, 0, 15, 128, 2, 0, - 228, 128, 0, 8, 228, 160, - 5, 0, 0, 3, 0, 8, - 15, 128, 0, 0, 228, 128, - 1, 0, 228, 128, 255, 255, - 0, 0, 65, 111, 110, 57, - 128, 0, 0, 0, 128, 0, - 0, 0, 0, 2, 255, 255, - 88, 0, 0, 0, 40, 0, - 0, 0, 0, 0, 40, 0, - 0, 0, 40, 0, 0, 0, - 40, 0, 1, 0, 36, 0, - 0, 0, 40, 0, 0, 0, - 0, 0, 0, 2, 255, 255, - 31, 0, 0, 2, 0, 0, - 0, 128, 0, 0, 15, 176, - 31, 0, 0, 2, 0, 0, - 0, 128, 1, 0, 3, 176, - 31, 0, 0, 2, 0, 0, - 0, 144, 0, 8, 15, 160, - 66, 0, 0, 3, 0, 0, - 15, 128, 1, 0, 228, 176, - 0, 8, 228, 160, 5, 0, - 0, 3, 0, 0, 15, 128, - 0, 0, 228, 128, 0, 0, - 228, 176, 1, 0, 0, 2, - 0, 8, 15, 128, 0, 0, - 228, 128, 255, 255, 0, 0, - 83, 72, 68, 82, 148, 0, - 0, 0, 64, 0, 0, 0, - 37, 0, 0, 0, 90, 0, - 0, 3, 0, 96, 16, 0, - 0, 0, 0, 0, 88, 24, - 0, 4, 0, 112, 16, 0, - 0, 0, 0, 0, 85, 85, - 0, 0, 98, 16, 0, 3, - 242, 16, 16, 0, 1, 0, - 0, 0, 98, 16, 0, 3, - 50, 16, 16, 0, 2, 0, - 0, 0, 101, 0, 0, 3, - 242, 32, 16, 0, 0, 0, - 0, 0, 104, 0, 0, 2, - 1, 0, 0, 0, 69, 0, - 0, 9, 242, 0, 16, 0, - 0, 0, 0, 0, 70, 16, - 16, 0, 2, 0, 0, 0, - 70, 126, 16, 0, 0, 0, - 0, 0, 0, 96, 16, 0, - 0, 0, 0, 0, 56, 0, - 0, 7, 242, 32, 16, 0, - 0, 0, 0, 0, 70, 14, - 16, 0, 0, 0, 0, 0, - 70, 30, 16, 0, 1, 0, - 0, 0, 62, 0, 0, 1, - 73, 83, 71, 78, 108, 0, - 0, 0, 3, 0, 0, 0, - 8, 0, 0, 0, 80, 0, - 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 3, 0, - 0, 0, 0, 0, 0, 0, - 15, 0, 0, 0, 92, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 1, 0, 0, 0, - 15, 15, 0, 0, 98, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 2, 0, 0, 0, - 3, 3, 0, 0, 83, 86, - 95, 80, 79, 83, 73, 84, - 73, 79, 78, 0, 67, 79, - 76, 79, 82, 0, 84, 69, - 88, 67, 79, 79, 82, 68, - 0, 171, 79, 83, 71, 78, - 44, 0, 0, 0, 1, 0, - 0, 0, 8, 0, 0, 0, - 32, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, - 0, 0, 15, 0, 0, 0, - 83, 86, 95, 84, 97, 114, - 103, 101, 116, 0, 171, 171 -}; diff --git a/deps/nuklear/demo/d3d11/nuklear_d3d11_vertex_shader.h b/deps/nuklear/demo/d3d11/nuklear_d3d11_vertex_shader.h deleted file mode 100644 index 770d2dd9..00000000 --- a/deps/nuklear/demo/d3d11/nuklear_d3d11_vertex_shader.h +++ /dev/null @@ -1,350 +0,0 @@ -#if 0 -// -// Generated by Microsoft (R) D3D Shader Disassembler -// -// -// Input signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// POSITION 0 xy 0 NONE float xy -// COLOR 0 xyzw 1 NONE float xyzw -// TEXCOORD 0 xy 2 NONE float xy -// -// -// Output signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// SV_POSITION 0 xyzw 0 POS float xyzw -// COLOR 0 xyzw 1 NONE float xyzw -// TEXCOORD 0 xy 2 NONE float xy -// -// -// Constant buffer to DX9 shader constant mappings: -// -// Target Reg Buffer Start Reg # of Regs Data Conversion -// ---------- ------- --------- --------- ---------------------- -// c1 cb0 0 4 ( FLT, FLT, FLT, FLT) -// -// -// Runtime generated constant mappings: -// -// Target Reg Constant Description -// ---------- -------------------------------------------------- -// c0 Vertex Shader position offset -// -// -// Level9 shader bytecode: -// - vs_2_0 - def c5, 0, 1, 0, 0 - dcl_texcoord v0 - dcl_texcoord1 v1 - dcl_texcoord2 v2 - mul r0, v0.x, c1 - mad r0, c2, v0.y, r0 - mov r1.xy, c5 - mad r0, c3, r1.x, r0 - mad r0, c4, r1.y, r0 - mul r1.xy, r0.w, c0 - add oPos.xy, r0, r1 - mov oPos.zw, r0 - mov oT0, v1 - mov oT1.xy, v2 - -// approximately 10 instruction slots used -// -// Constant buffer to DX9 shader constant mappings: -// -// Target Reg Buffer Start Reg # of Regs Data Conversion -// ---------- ------- --------- --------- ---------------------- -// c0 cb0 0 4 ( FLT, FLT, FLT, FLT) -// -// -// XNA Prepass shader bytecode: -// - vs_2_0 - def c4, 0, 1, 0, 0 - dcl_texcoord v0 - mul r1, r0.x, c0 - mad r0, c1, r0.y, r1 - mov r1.xy, c4 - mad r0, c2, r1.x, r0 - mad r0, c3, r1.y, r0 - mov oPos, r0 - -// approximately 6 instruction slots used -// -// Constant buffer to DX9 shader constant mappings: -// -// Target Reg Buffer Start Reg # of Regs Data Conversion -// ---------- ------- --------- --------- ---------------------- -// c0 cb0 0 4 ( FLT, FLT, FLT, FLT) -// -// -// XNA shader bytecode: -// - vs_2_0 - def c4, 0, 1, 0, 0 - dcl_texcoord v0 - dcl_texcoord1 v1 - dcl_texcoord2 v2 - mov oT0, r1 - mov oT1.xy, r2 - mul r1, r0.x, c0 - mad r0, c1, r0.y, r1 - mov r1.xy, c4 - mad r0, c2, r1.x, r0 - mad r0, c3, r1.y, r0 - mov oPos, r0 - -// approximately 8 instruction slots used -vs_4_0 -dcl_constantbuffer cb0[4], immediateIndexed -dcl_input v0.xy -dcl_input v1.xyzw -dcl_input v2.xy -dcl_output_siv o0.xyzw, position -dcl_output o1.xyzw -dcl_output o2.xy -dcl_temps 1 -mul r0.xyzw, v0.xxxx, cb0[0].xyzw -mad r0.xyzw, cb0[1].xyzw, v0.yyyy, r0.xyzw -mad r0.xyzw, cb0[2].xyzw, l(0.000000, 0.000000, 0.000000, 0.000000), r0.xyzw -mad o0.xyzw, cb0[3].xyzw, l(1.000000, 1.000000, 1.000000, 1.000000), r0.xyzw -mov o1.xyzw, v1.xyzw -mov o2.xy, v2.xyxx -ret -// Approximately 0 instruction slots used -#endif - -const BYTE nk_d3d11_vertex_shader[] = -{ - 68, 88, 66, 67, 215, 245, - 86, 155, 188, 117, 37, 118, - 193, 207, 209, 90, 160, 153, - 246, 188, 1, 0, 0, 0, - 72, 5, 0, 0, 6, 0, - 0, 0, 56, 0, 0, 0, - 48, 1, 0, 0, 248, 1, - 0, 0, 20, 3, 0, 0, - 100, 4, 0, 0, 212, 4, - 0, 0, 88, 78, 65, 83, - 240, 0, 0, 0, 240, 0, - 0, 0, 0, 2, 254, 255, - 192, 0, 0, 0, 48, 0, - 0, 0, 1, 0, 36, 0, - 0, 0, 48, 0, 0, 0, - 48, 0, 0, 0, 36, 0, - 0, 0, 48, 0, 0, 0, - 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 2, - 254, 255, 81, 0, 0, 5, - 4, 0, 15, 160, 0, 0, - 0, 0, 0, 0, 128, 63, - 0, 0, 0, 0, 0, 0, - 0, 0, 31, 0, 0, 2, - 5, 0, 0, 128, 0, 0, - 15, 144, 31, 0, 0, 2, - 5, 0, 1, 128, 1, 0, - 15, 144, 31, 0, 0, 2, - 5, 0, 2, 128, 2, 0, - 15, 144, 1, 0, 0, 2, - 0, 0, 15, 224, 1, 0, - 228, 128, 1, 0, 0, 2, - 1, 0, 3, 224, 2, 0, - 228, 128, 5, 0, 0, 3, - 1, 0, 15, 128, 0, 0, - 0, 128, 0, 0, 228, 160, - 4, 0, 0, 4, 0, 0, - 15, 128, 1, 0, 228, 160, - 0, 0, 85, 128, 1, 0, - 228, 128, 1, 0, 0, 2, - 1, 0, 3, 128, 4, 0, - 228, 160, 4, 0, 0, 4, - 0, 0, 15, 128, 2, 0, - 228, 160, 1, 0, 0, 128, - 0, 0, 228, 128, 4, 0, - 0, 4, 0, 0, 15, 128, - 3, 0, 228, 160, 1, 0, - 85, 128, 0, 0, 228, 128, - 1, 0, 0, 2, 0, 0, - 15, 192, 0, 0, 228, 128, - 255, 255, 0, 0, 88, 78, - 65, 80, 192, 0, 0, 0, - 192, 0, 0, 0, 0, 2, - 254, 255, 144, 0, 0, 0, - 48, 0, 0, 0, 1, 0, - 36, 0, 0, 0, 48, 0, - 0, 0, 48, 0, 0, 0, - 36, 0, 0, 0, 48, 0, - 0, 0, 0, 0, 4, 0, - 0, 0, 0, 0, 0, 0, - 0, 2, 254, 255, 81, 0, - 0, 5, 4, 0, 15, 160, - 0, 0, 0, 0, 0, 0, - 128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 31, 0, - 0, 2, 5, 0, 0, 128, - 0, 0, 15, 144, 5, 0, - 0, 3, 1, 0, 15, 128, - 0, 0, 0, 128, 0, 0, - 228, 160, 4, 0, 0, 4, - 0, 0, 15, 128, 1, 0, - 228, 160, 0, 0, 85, 128, - 1, 0, 228, 128, 1, 0, - 0, 2, 1, 0, 3, 128, - 4, 0, 228, 160, 4, 0, - 0, 4, 0, 0, 15, 128, - 2, 0, 228, 160, 1, 0, - 0, 128, 0, 0, 228, 128, - 4, 0, 0, 4, 0, 0, - 15, 128, 3, 0, 228, 160, - 1, 0, 85, 128, 0, 0, - 228, 128, 1, 0, 0, 2, - 0, 0, 15, 192, 0, 0, - 228, 128, 255, 255, 0, 0, - 65, 111, 110, 57, 20, 1, - 0, 0, 20, 1, 0, 0, - 0, 2, 254, 255, 224, 0, - 0, 0, 52, 0, 0, 0, - 1, 0, 36, 0, 0, 0, - 48, 0, 0, 0, 48, 0, - 0, 0, 36, 0, 1, 0, - 48, 0, 0, 0, 0, 0, - 4, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 2, 254, 255, 81, 0, - 0, 5, 5, 0, 15, 160, - 0, 0, 0, 0, 0, 0, - 128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 31, 0, - 0, 2, 5, 0, 0, 128, - 0, 0, 15, 144, 31, 0, - 0, 2, 5, 0, 1, 128, - 1, 0, 15, 144, 31, 0, - 0, 2, 5, 0, 2, 128, - 2, 0, 15, 144, 5, 0, - 0, 3, 0, 0, 15, 128, - 0, 0, 0, 144, 1, 0, - 228, 160, 4, 0, 0, 4, - 0, 0, 15, 128, 2, 0, - 228, 160, 0, 0, 85, 144, - 0, 0, 228, 128, 1, 0, - 0, 2, 1, 0, 3, 128, - 5, 0, 228, 160, 4, 0, - 0, 4, 0, 0, 15, 128, - 3, 0, 228, 160, 1, 0, - 0, 128, 0, 0, 228, 128, - 4, 0, 0, 4, 0, 0, - 15, 128, 4, 0, 228, 160, - 1, 0, 85, 128, 0, 0, - 228, 128, 5, 0, 0, 3, - 1, 0, 3, 128, 0, 0, - 255, 128, 0, 0, 228, 160, - 2, 0, 0, 3, 0, 0, - 3, 192, 0, 0, 228, 128, - 1, 0, 228, 128, 1, 0, - 0, 2, 0, 0, 12, 192, - 0, 0, 228, 128, 1, 0, - 0, 2, 0, 0, 15, 224, - 1, 0, 228, 144, 1, 0, - 0, 2, 1, 0, 3, 224, - 2, 0, 228, 144, 255, 255, - 0, 0, 83, 72, 68, 82, - 72, 1, 0, 0, 64, 0, - 1, 0, 82, 0, 0, 0, - 89, 0, 0, 4, 70, 142, - 32, 0, 0, 0, 0, 0, - 4, 0, 0, 0, 95, 0, - 0, 3, 50, 16, 16, 0, - 0, 0, 0, 0, 95, 0, - 0, 3, 242, 16, 16, 0, - 1, 0, 0, 0, 95, 0, - 0, 3, 50, 16, 16, 0, - 2, 0, 0, 0, 103, 0, - 0, 4, 242, 32, 16, 0, - 0, 0, 0, 0, 1, 0, - 0, 0, 101, 0, 0, 3, - 242, 32, 16, 0, 1, 0, - 0, 0, 101, 0, 0, 3, - 50, 32, 16, 0, 2, 0, - 0, 0, 104, 0, 0, 2, - 1, 0, 0, 0, 56, 0, - 0, 8, 242, 0, 16, 0, - 0, 0, 0, 0, 6, 16, - 16, 0, 0, 0, 0, 0, - 70, 142, 32, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 50, 0, 0, 10, 242, 0, - 16, 0, 0, 0, 0, 0, - 70, 142, 32, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 86, 21, 16, 0, 0, 0, - 0, 0, 70, 14, 16, 0, - 0, 0, 0, 0, 50, 0, - 0, 13, 242, 0, 16, 0, - 0, 0, 0, 0, 70, 142, - 32, 0, 0, 0, 0, 0, - 2, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 70, 14, 16, 0, 0, 0, - 0, 0, 50, 0, 0, 13, - 242, 32, 16, 0, 0, 0, - 0, 0, 70, 142, 32, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 128, 63, 0, 0, - 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 70, 14, - 16, 0, 0, 0, 0, 0, - 54, 0, 0, 5, 242, 32, - 16, 0, 1, 0, 0, 0, - 70, 30, 16, 0, 1, 0, - 0, 0, 54, 0, 0, 5, - 50, 32, 16, 0, 2, 0, - 0, 0, 70, 16, 16, 0, - 2, 0, 0, 0, 62, 0, - 0, 1, 73, 83, 71, 78, - 104, 0, 0, 0, 3, 0, - 0, 0, 8, 0, 0, 0, - 80, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, - 0, 0, 3, 3, 0, 0, - 89, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 1, 0, - 0, 0, 15, 15, 0, 0, - 95, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 2, 0, - 0, 0, 3, 3, 0, 0, - 80, 79, 83, 73, 84, 73, - 79, 78, 0, 67, 79, 76, - 79, 82, 0, 84, 69, 88, - 67, 79, 79, 82, 68, 0, - 79, 83, 71, 78, 108, 0, - 0, 0, 3, 0, 0, 0, - 8, 0, 0, 0, 80, 0, - 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 3, 0, - 0, 0, 0, 0, 0, 0, - 15, 0, 0, 0, 92, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 1, 0, 0, 0, - 15, 0, 0, 0, 98, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 2, 0, 0, 0, - 3, 12, 0, 0, 83, 86, - 95, 80, 79, 83, 73, 84, - 73, 79, 78, 0, 67, 79, - 76, 79, 82, 0, 84, 69, - 88, 67, 79, 79, 82, 68, - 0, 171 -}; diff --git a/deps/nuklear/demo/gdi/build.bat b/deps/nuklear/demo/gdi/build.bat deleted file mode 100644 index 38843171..00000000 --- a/deps/nuklear/demo/gdi/build.bat +++ /dev/null @@ -1,6 +0,0 @@ -@echo off - -rem This will use VS2015 for compiler -call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86 - -cl /nologo /W3 /O2 /fp:fast /Gm- /Fedemo.exe main.c user32.lib gdi32.lib /link /incremental:no diff --git a/deps/nuklear/demo/gdi/main.c b/deps/nuklear/demo/gdi/main.c deleted file mode 100644 index e82cd169..00000000 --- a/deps/nuklear/demo/gdi/main.c +++ /dev/null @@ -1,161 +0,0 @@ -/* nuklear - v1.17 - public domain */ -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#include - -#define WINDOW_WIDTH 800 -#define WINDOW_HEIGHT 600 - -#define NK_INCLUDE_FIXED_TYPES -#define NK_INCLUDE_STANDARD_IO -#define NK_INCLUDE_STANDARD_VARARGS -#define NK_INCLUDE_DEFAULT_ALLOCATOR -#define NK_IMPLEMENTATION -#define NK_GDI_IMPLEMENTATION -#include "../../nuklear.h" -#include "nuklear_gdi.h" - -/* =============================================================== - * - * EXAMPLE - * - * ===============================================================*/ -/* This are some code examples to provide a small overview of what can be - * done with this library. To try out an example uncomment the include - * and the corresponding function. */ -#define UNUSED(a) (void)a -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) < (b) ? (b) : (a)) -#define LEN(a) (sizeof(a)/sizeof(a)[0]) - -/*#include "../style.c"*/ -/*#include "../calculator.c"*/ -/*#include "../overview.c"*/ -/*#include "../node_editor.c"*/ - -/* =============================================================== - * - * DEMO - * - * ===============================================================*/ -static LRESULT CALLBACK -WindowProc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam) -{ - switch (msg) - { - case WM_DESTROY: - PostQuitMessage(0); - return 0; - } - - if (nk_gdi_handle_event(wnd, msg, wparam, lparam)) - return 0; - - return DefWindowProcW(wnd, msg, wparam, lparam); -} - -int main(void) -{ - GdiFont* font; - struct nk_context *ctx; - - WNDCLASSW wc; - ATOM atom; - RECT rect = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT }; - DWORD style = WS_OVERLAPPEDWINDOW; - DWORD exstyle = WS_EX_APPWINDOW; - HWND wnd; - HDC dc; - int running = 1; - int needs_refresh = 1; - - /* Win32 */ - memset(&wc, 0, sizeof(wc)); - wc.lpfnWndProc = WindowProc; - wc.hInstance = GetModuleHandleW(0); - wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.lpszClassName = L"NuklearWindowClass"; - atom = RegisterClassW(&wc); - - AdjustWindowRectEx(&rect, style, FALSE, exstyle); - wnd = CreateWindowExW(exstyle, wc.lpszClassName, L"Nuklear Demo", - style | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, - rect.right - rect.left, rect.bottom - rect.top, - NULL, NULL, wc.hInstance, NULL); - dc = GetDC(wnd); - - /* GUI */ - font = nk_gdifont_create("Arial", 14); - ctx = nk_gdi_init(font, dc, WINDOW_WIDTH, WINDOW_HEIGHT); - - /* style.c */ - /*set_style(ctx, THEME_WHITE);*/ - /*set_style(ctx, THEME_RED);*/ - /*set_style(ctx, THEME_BLUE);*/ - /*set_style(ctx, THEME_DARK);*/ - - while (running) - { - /* Input */ - MSG msg; - nk_input_begin(ctx); - if (needs_refresh == 0) { - if (GetMessageW(&msg, NULL, 0, 0) <= 0) - running = 0; - else { - TranslateMessage(&msg); - DispatchMessageW(&msg); - } - needs_refresh = 1; - } else needs_refresh = 0; - - while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { - if (msg.message == WM_QUIT) - running = 0; - TranslateMessage(&msg); - DispatchMessageW(&msg); - needs_refresh = 1; - } - nk_input_end(ctx); - - /* GUI */ - if (nk_begin(ctx, "Demo", nk_rect(50, 50, 200, 200), - NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE| - NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE)) - { - enum {EASY, HARD}; - static int op = EASY; - static int property = 20; - - nk_layout_row_static(ctx, 30, 80, 1); - if (nk_button_label(ctx, "button")) - fprintf(stdout, "button pressed\n"); - nk_layout_row_dynamic(ctx, 30, 2); - if (nk_option_label(ctx, "easy", op == EASY)) op = EASY; - if (nk_option_label(ctx, "hard", op == HARD)) op = HARD; - nk_layout_row_dynamic(ctx, 22, 1); - nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1); - } - nk_end(ctx); - if (nk_window_is_closed(ctx, "Demo")) break; - - /* -------------- EXAMPLES ---------------- */ - /*calculator(ctx);*/ - /*overview(ctx);*/ - /*node_editor(ctx);*/ - /* ----------------------------------------- */ - - /* Draw */ - nk_gdi_render(nk_rgb(30,30,30)); - } - - nk_gdifont_del(font); - ReleaseDC(wnd, dc); - UnregisterClassW(wc.lpszClassName, wc.hInstance); - return 0; -} - diff --git a/deps/nuklear/demo/gdi/nuklear_gdi.h b/deps/nuklear/demo/gdi/nuklear_gdi.h deleted file mode 100644 index 6d3a84a0..00000000 --- a/deps/nuklear/demo/gdi/nuklear_gdi.h +++ /dev/null @@ -1,761 +0,0 @@ -/* - * Nuklear - v1.17 - public domain - * no warrenty implied; use at your own risk. - * authored from 2015-2016 by Micha Mettke - */ -/* - * ============================================================== - * - * API - * - * =============================================================== - */ -#ifndef NK_GDI_H_ -#define NK_GDI_H_ - -#define WIN32_LEAN_AND_MEAN -#include - -typedef struct GdiFont GdiFont; -NK_API struct nk_context* nk_gdi_init(GdiFont *font, HDC window_dc, unsigned int width, unsigned int height); -NK_API int nk_gdi_handle_event(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); -NK_API void nk_gdi_render(struct nk_color clear); -NK_API void nk_gdi_shutdown(void); - -/* font */ -NK_API GdiFont* nk_gdifont_create(const char *name, int size); -NK_API void nk_gdifont_del(GdiFont *font); -NK_API void nk_gdi_set_font(GdiFont *font); - -#endif - -/* - * ============================================================== - * - * IMPLEMENTATION - * - * =============================================================== - */ -#ifdef NK_GDI_IMPLEMENTATION - -#include -#include - -struct GdiFont { - struct nk_user_font nk; - int height; - HFONT handle; - HDC dc; -}; - -static struct { - HBITMAP bitmap; - HDC window_dc; - HDC memory_dc; - unsigned int width; - unsigned int height; - struct nk_context ctx; -} gdi; - -static COLORREF -convert_color(struct nk_color c) -{ - return c.r | (c.g << 8) | (c.b << 16); -} - -static void -nk_gdi_scissor(HDC dc, float x, float y, float w, float h) -{ - SelectClipRgn(dc, NULL); - IntersectClipRect(dc, (int)x, (int)y, (int)(x + w + 1), (int)(y + h + 1)); -} - -static void -nk_gdi_stroke_line(HDC dc, short x0, short y0, short x1, - short y1, unsigned int line_thickness, struct nk_color col) -{ - COLORREF color = convert_color(col); - - HPEN pen = NULL; - if (line_thickness == 1) { - SetDCPenColor(dc, color); - } else { - pen = CreatePen(PS_SOLID, line_thickness, color); - SelectObject(dc, pen); - } - - MoveToEx(dc, x0, y0, NULL); - LineTo(dc, x1, y1); - - if (pen) { - SelectObject(dc, GetStockObject(DC_PEN)); - DeleteObject(pen); - } -} - -static void -nk_gdi_stroke_rect(HDC dc, short x, short y, unsigned short w, - unsigned short h, unsigned short r, unsigned short line_thickness, struct nk_color col) -{ - COLORREF color = convert_color(col); - - HPEN pen = NULL; - if (line_thickness == 1) { - SetDCPenColor(dc, color); - } else { - pen = CreatePen(PS_SOLID, line_thickness, color); - SelectObject(dc, pen); - } - - SetDCBrushColor(dc, OPAQUE); - if (r == 0) { - Rectangle(dc, x, y, x + w, y + h); - } else { - RoundRect(dc, x, y, x + w, y + h, r, r); - } - - if (pen) { - SelectObject(dc, GetStockObject(DC_PEN)); - DeleteObject(pen); - } -} - -static void -nk_gdi_fill_rect(HDC dc, short x, short y, unsigned short w, - unsigned short h, unsigned short r, struct nk_color col) -{ - COLORREF color = convert_color(col); - - if (r == 0) { - RECT rect = { x, y, x + w, y + h }; - SetBkColor(dc, color); - ExtTextOutW(dc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); - } else { - SetDCPenColor(dc, color); - SetDCBrushColor(dc, color); - RoundRect(dc, x, y, x + w, y + h, r, r); - } -} - -static void -nk_gdi_fill_triangle(HDC dc, short x0, short y0, short x1, - short y1, short x2, short y2, struct nk_color col) -{ - COLORREF color = convert_color(col); - POINT points[] = { - { x0, y0 }, - { x1, y1 }, - { x2, y2 }, - }; - - SetDCPenColor(dc, color); - SetDCBrushColor(dc, color); - Polygon(dc, points, 3); -} - -static void -nk_gdi_stroke_triangle(HDC dc, short x0, short y0, short x1, - short y1, short x2, short y2, unsigned short line_thickness, struct nk_color col) -{ - COLORREF color = convert_color(col); - POINT points[] = { - { x0, y0 }, - { x1, y1 }, - { x2, y2 }, - { x0, y0 }, - }; - - HPEN pen = NULL; - if (line_thickness == 1) { - SetDCPenColor(dc, color); - } else { - pen = CreatePen(PS_SOLID, line_thickness, color); - SelectObject(dc, pen); - } - - Polyline(dc, points, 4); - - if (pen) { - SelectObject(dc, GetStockObject(DC_PEN)); - DeleteObject(pen); - } -} - -static void -nk_gdi_fill_polygon(HDC dc, const struct nk_vec2i *pnts, int count, struct nk_color col) -{ - int i = 0; - #define MAX_POINTS 64 - POINT points[MAX_POINTS]; - COLORREF color = convert_color(col); - SetDCBrushColor(dc, color); - SetDCPenColor(dc, color); - for (i = 0; i < count && i < MAX_POINTS; ++i) { - points[i].x = pnts[i].x; - points[i].y = pnts[i].y; - } - Polygon(dc, points, i); - #undef MAX_POINTS -} - -static void -nk_gdi_stroke_polygon(HDC dc, const struct nk_vec2i *pnts, int count, - unsigned short line_thickness, struct nk_color col) -{ - COLORREF color = convert_color(col); - HPEN pen = NULL; - if (line_thickness == 1) { - SetDCPenColor(dc, color); - } else { - pen = CreatePen(PS_SOLID, line_thickness, color); - SelectObject(dc, pen); - } - - if (count > 0) { - int i; - MoveToEx(dc, pnts[0].x, pnts[0].y, NULL); - for (i = 1; i < count; ++i) - LineTo(dc, pnts[i].x, pnts[i].y); - LineTo(dc, pnts[0].x, pnts[0].y); - } - - if (pen) { - SelectObject(dc, GetStockObject(DC_PEN)); - DeleteObject(pen); - } -} - -static void -nk_gdi_stroke_polyline(HDC dc, const struct nk_vec2i *pnts, - int count, unsigned short line_thickness, struct nk_color col) -{ - COLORREF color = convert_color(col); - HPEN pen = NULL; - if (line_thickness == 1) { - SetDCPenColor(dc, color); - } else { - pen = CreatePen(PS_SOLID, line_thickness, color); - SelectObject(dc, pen); - } - - if (count > 0) { - int i; - MoveToEx(dc, pnts[0].x, pnts[0].y, NULL); - for (i = 1; i < count; ++i) - LineTo(dc, pnts[i].x, pnts[i].y); - } - - if (pen) { - SelectObject(dc, GetStockObject(DC_PEN)); - DeleteObject(pen); - } -} - -static void -nk_gdi_fill_circle(HDC dc, short x, short y, unsigned short w, - unsigned short h, struct nk_color col) -{ - COLORREF color = convert_color(col); - SetDCBrushColor(dc, color); - SetDCPenColor(dc, color); - Ellipse(dc, x, y, x + w, y + h); -} - -static void -nk_gdi_stroke_circle(HDC dc, short x, short y, unsigned short w, - unsigned short h, unsigned short line_thickness, struct nk_color col) -{ - COLORREF color = convert_color(col); - HPEN pen = NULL; - if (line_thickness == 1) { - SetDCPenColor(dc, color); - } else { - pen = CreatePen(PS_SOLID, line_thickness, color); - SelectObject(dc, pen); - } - - SetDCBrushColor(dc, OPAQUE); - Ellipse(dc, x, y, x + w, y + h); - - if (pen) { - SelectObject(dc, GetStockObject(DC_PEN)); - DeleteObject(pen); - } -} - -static void -nk_gdi_stroke_curve(HDC dc, struct nk_vec2i p1, - struct nk_vec2i p2, struct nk_vec2i p3, struct nk_vec2i p4, - unsigned short line_thickness, struct nk_color col) -{ - COLORREF color = convert_color(col); - POINT p[] = { - { p1.x, p1.y }, - { p2.x, p2.y }, - { p3.x, p3.y }, - { p4.x, p4.y }, - }; - - HPEN pen = NULL; - if (line_thickness == 1) { - SetDCPenColor(dc, color); - } else { - pen = CreatePen(PS_SOLID, line_thickness, color); - SelectObject(dc, pen); - } - - SetDCBrushColor(dc, OPAQUE); - PolyBezier(dc, p, 4); - - if (pen) { - SelectObject(dc, GetStockObject(DC_PEN)); - DeleteObject(pen); - } -} - -static void -nk_gdi_draw_text(HDC dc, short x, short y, unsigned short w, unsigned short h, - const char *text, int len, GdiFont *font, struct nk_color cbg, struct nk_color cfg) -{ - int wsize; - WCHAR* wstr; - - if(!text || !font || !len) return; - - wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0); - wstr = (WCHAR*)_alloca(wsize * sizeof(wchar_t)); - MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize); - - SetBkColor(dc, convert_color(cbg)); - SetTextColor(dc, convert_color(cfg)); - - SelectObject(dc, font->handle); - ExtTextOutW(dc, x, y, ETO_OPAQUE, NULL, wstr, wsize, NULL); -} - -static void -nk_gdi_clear(HDC dc, struct nk_color col) -{ - COLORREF color = convert_color(col); - RECT rect = { 0, 0, gdi.width, gdi.height }; - SetBkColor(dc, color); - - ExtTextOutW(dc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); -} - -static void -nk_gdi_blit(HDC dc) -{ - BitBlt(dc, 0, 0, gdi.width, gdi.height, gdi.memory_dc, 0, 0, SRCCOPY); -} - -GdiFont* -nk_gdifont_create(const char *name, int size) -{ - TEXTMETRICW metric; - GdiFont *font = (GdiFont*)calloc(1, sizeof(GdiFont)); - if (!font) - return NULL; - font->dc = CreateCompatibleDC(0); - font->handle = CreateFont(size, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_DONTCARE, name); - SelectObject(font->dc, font->handle); - GetTextMetricsW(font->dc, &metric); - font->height = metric.tmHeight; - return font; -} - -static float -nk_gdifont_get_text_width(nk_handle handle, float height, const char *text, int len) -{ - GdiFont *font = (GdiFont*)handle.ptr; - SIZE size; - int wsize; - WCHAR* wstr; - if (!font || !text) - return 0; - - wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0); - wstr = (WCHAR*)_alloca(wsize * sizeof(wchar_t)); - MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize); - if (GetTextExtentPoint32W(font->dc, wstr, wsize, &size)) - return (float)size.cx; - return -1.0f; -} - -void -nk_gdifont_del(GdiFont *font) -{ - if(!font) return; - DeleteObject(font->handle); - DeleteDC(font->dc); - free(font); -} - -static void -nk_gdi_clipbard_paste(nk_handle usr, struct nk_text_edit *edit) -{ - (void)usr; - if (IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL)) - { - HGLOBAL mem = GetClipboardData(CF_UNICODETEXT); - if (mem) - { - SIZE_T size = GlobalSize(mem) - 1; - if (size) - { - LPCWSTR wstr = (LPCWSTR)GlobalLock(mem); - if (wstr) - { - int utf8size = WideCharToMultiByte(CP_UTF8, 0, wstr, (int)(size / sizeof(wchar_t)), NULL, 0, NULL, NULL); - if (utf8size) - { - char* utf8 = (char*)malloc(utf8size); - if (utf8) - { - WideCharToMultiByte(CP_UTF8, 0, wstr, (int)(size / sizeof(wchar_t)), utf8, utf8size, NULL, NULL); - nk_textedit_paste(edit, utf8, utf8size); - free(utf8); - } - } - GlobalUnlock(mem); - } - } - } - CloseClipboard(); - } -} - -static void -nk_gdi_clipbard_copy(nk_handle usr, const char *text, int len) -{ - if (OpenClipboard(NULL)) - { - int wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0); - if (wsize) - { - HGLOBAL mem = (HGLOBAL)GlobalAlloc(GMEM_MOVEABLE, (wsize + 1) * sizeof(wchar_t)); - if (mem) - { - wchar_t* wstr = (wchar_t*)GlobalLock(mem); - if (wstr) - { - MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize); - wstr[wsize] = 0; - GlobalUnlock(mem); - - SetClipboardData(CF_UNICODETEXT, mem); - } - } - } - CloseClipboard(); - } -} - -NK_API struct nk_context* -nk_gdi_init(GdiFont *gdifont, HDC window_dc, unsigned int width, unsigned int height) -{ - struct nk_user_font *font = &gdifont->nk; - font->userdata = nk_handle_ptr(gdifont); - font->height = (float)gdifont->height; - font->width = nk_gdifont_get_text_width; - - gdi.bitmap = CreateCompatibleBitmap(window_dc, width, height); - gdi.window_dc = window_dc; - gdi.memory_dc = CreateCompatibleDC(window_dc); - gdi.width = width; - gdi.height = height; - SelectObject(gdi.memory_dc, gdi.bitmap); - - nk_init_default(&gdi.ctx, font); - gdi.ctx.clip.copy = nk_gdi_clipbard_copy; - gdi.ctx.clip.paste = nk_gdi_clipbard_paste; - return &gdi.ctx; -} - -NK_API void -nk_gdi_set_font(GdiFont *gdifont) -{ - struct nk_user_font *font = &gdifont->nk; - font->userdata = nk_handle_ptr(gdifont); - font->height = (float)gdifont->height; - font->width = nk_gdifont_get_text_width; - nk_style_set_font(&gdi.ctx, font); -} - -NK_API int -nk_gdi_handle_event(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam) -{ - switch (msg) - { - case WM_SIZE: - { - unsigned width = LOWORD(lparam); - unsigned height = LOWORD(lparam); - if (width != gdi.width || height != gdi.height) - { - DeleteObject(gdi.bitmap); - gdi.bitmap = CreateCompatibleBitmap(gdi.window_dc, width, height); - gdi.width = width; - gdi.height = height; - SelectObject(gdi.memory_dc, gdi.bitmap); - } - break; - } - - case WM_PAINT: - { - PAINTSTRUCT paint; - HDC dc = BeginPaint(wnd, &paint); - nk_gdi_blit(dc); - EndPaint(wnd, &paint); - return 1; - } - - case WM_KEYDOWN: - case WM_KEYUP: - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - { - int down = !((lparam >> 31) & 1); - int ctrl = GetKeyState(VK_CONTROL) & (1 << 15); - - switch (wparam) - { - case VK_SHIFT: - case VK_LSHIFT: - case VK_RSHIFT: - nk_input_key(&gdi.ctx, NK_KEY_SHIFT, down); - return 1; - - case VK_DELETE: - nk_input_key(&gdi.ctx, NK_KEY_DEL, down); - return 1; - - case VK_RETURN: - nk_input_key(&gdi.ctx, NK_KEY_ENTER, down); - return 1; - - case VK_TAB: - nk_input_key(&gdi.ctx, NK_KEY_TAB, down); - return 1; - - case VK_LEFT: - if (ctrl) - nk_input_key(&gdi.ctx, NK_KEY_TEXT_WORD_LEFT, down); - else - nk_input_key(&gdi.ctx, NK_KEY_LEFT, down); - return 1; - - case VK_RIGHT: - if (ctrl) - nk_input_key(&gdi.ctx, NK_KEY_TEXT_WORD_RIGHT, down); - else - nk_input_key(&gdi.ctx, NK_KEY_RIGHT, down); - return 1; - - case VK_BACK: - nk_input_key(&gdi.ctx, NK_KEY_BACKSPACE, down); - return 1; - - case VK_HOME: - nk_input_key(&gdi.ctx, NK_KEY_TEXT_START, down); - nk_input_key(&gdi.ctx, NK_KEY_SCROLL_START, down); - return 1; - - case VK_END: - nk_input_key(&gdi.ctx, NK_KEY_TEXT_END, down); - nk_input_key(&gdi.ctx, NK_KEY_SCROLL_END, down); - return 1; - - case VK_NEXT: - nk_input_key(&gdi.ctx, NK_KEY_SCROLL_DOWN, down); - return 1; - - case VK_PRIOR: - nk_input_key(&gdi.ctx, NK_KEY_SCROLL_UP, down); - return 1; - - case 'C': - if (ctrl) { - nk_input_key(&gdi.ctx, NK_KEY_COPY, down); - return 1; - } - break; - - case 'V': - if (ctrl) { - nk_input_key(&gdi.ctx, NK_KEY_PASTE, down); - return 1; - } - break; - - case 'X': - if (ctrl) { - nk_input_key(&gdi.ctx, NK_KEY_CUT, down); - return 1; - } - break; - - case 'Z': - if (ctrl) { - nk_input_key(&gdi.ctx, NK_KEY_TEXT_UNDO, down); - return 1; - } - break; - - case 'R': - if (ctrl) { - nk_input_key(&gdi.ctx, NK_KEY_TEXT_REDO, down); - return 1; - } - break; - } - return 0; - } - - case WM_CHAR: - if (wparam >= 32) - { - nk_input_unicode(&gdi.ctx, (nk_rune)wparam); - return 1; - } - break; - - case WM_LBUTTONDOWN: - nk_input_button(&gdi.ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1); - SetCapture(wnd); - return 1; - - case WM_LBUTTONUP: - nk_input_button(&gdi.ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0); - ReleaseCapture(); - return 1; - - case WM_RBUTTONDOWN: - nk_input_button(&gdi.ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1); - SetCapture(wnd); - return 1; - - case WM_RBUTTONUP: - nk_input_button(&gdi.ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0); - ReleaseCapture(); - return 1; - - case WM_MBUTTONDOWN: - nk_input_button(&gdi.ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 1); - SetCapture(wnd); - return 1; - - case WM_MBUTTONUP: - nk_input_button(&gdi.ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 0); - ReleaseCapture(); - return 1; - - case WM_MOUSEWHEEL: - nk_input_scroll(&gdi.ctx, (float)(short)HIWORD(wparam) / WHEEL_DELTA); - return 1; - - case WM_MOUSEMOVE: - nk_input_motion(&gdi.ctx, (short)LOWORD(lparam), (short)HIWORD(lparam)); - return 1; - } - - return 0; -} - -NK_API void -nk_gdi_shutdown(void) -{ - DeleteObject(gdi.memory_dc); - DeleteObject(gdi.bitmap); - nk_free(&gdi.ctx); -} - -NK_API void -nk_gdi_render(struct nk_color clear) -{ - const struct nk_command *cmd; - - HDC memory_dc = gdi.memory_dc; - SelectObject(memory_dc, GetStockObject(DC_PEN)); - SelectObject(memory_dc, GetStockObject(DC_BRUSH)); - nk_gdi_clear(memory_dc, clear); - - nk_foreach(cmd, &gdi.ctx) - { - switch (cmd->type) { - case NK_COMMAND_NOP: break; - case NK_COMMAND_SCISSOR: { - const struct nk_command_scissor *s =(const struct nk_command_scissor*)cmd; - nk_gdi_scissor(memory_dc, s->x, s->y, s->w, s->h); - } break; - case NK_COMMAND_LINE: { - const struct nk_command_line *l = (const struct nk_command_line *)cmd; - nk_gdi_stroke_line(memory_dc, l->begin.x, l->begin.y, l->end.x, - l->end.y, l->line_thickness, l->color); - } break; - case NK_COMMAND_RECT: { - const struct nk_command_rect *r = (const struct nk_command_rect *)cmd; - nk_gdi_stroke_rect(memory_dc, r->x, r->y, r->w, r->h, - (unsigned short)r->rounding, r->line_thickness, r->color); - } break; - case NK_COMMAND_RECT_FILLED: { - const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled *)cmd; - nk_gdi_fill_rect(memory_dc, r->x, r->y, r->w, r->h, - (unsigned short)r->rounding, r->color); - } break; - case NK_COMMAND_CIRCLE: { - const struct nk_command_circle *c = (const struct nk_command_circle *)cmd; - nk_gdi_stroke_circle(memory_dc, c->x, c->y, c->w, c->h, c->line_thickness, c->color); - } break; - case NK_COMMAND_CIRCLE_FILLED: { - const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd; - nk_gdi_fill_circle(memory_dc, c->x, c->y, c->w, c->h, c->color); - } break; - case NK_COMMAND_TRIANGLE: { - const struct nk_command_triangle*t = (const struct nk_command_triangle*)cmd; - nk_gdi_stroke_triangle(memory_dc, t->a.x, t->a.y, t->b.x, t->b.y, - t->c.x, t->c.y, t->line_thickness, t->color); - } break; - case NK_COMMAND_TRIANGLE_FILLED: { - const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled *)cmd; - nk_gdi_fill_triangle(memory_dc, t->a.x, t->a.y, t->b.x, t->b.y, - t->c.x, t->c.y, t->color); - } break; - case NK_COMMAND_POLYGON: { - const struct nk_command_polygon *p =(const struct nk_command_polygon*)cmd; - nk_gdi_stroke_polygon(memory_dc, p->points, p->point_count, p->line_thickness,p->color); - } break; - case NK_COMMAND_POLYGON_FILLED: { - const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled *)cmd; - nk_gdi_fill_polygon(memory_dc, p->points, p->point_count, p->color); - } break; - case NK_COMMAND_POLYLINE: { - const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd; - nk_gdi_stroke_polyline(memory_dc, p->points, p->point_count, p->line_thickness, p->color); - } break; - case NK_COMMAND_TEXT: { - const struct nk_command_text *t = (const struct nk_command_text*)cmd; - nk_gdi_draw_text(memory_dc, t->x, t->y, t->w, t->h, - (const char*)t->string, t->length, - (GdiFont*)t->font->userdata.ptr, - t->background, t->foreground); - } break; - case NK_COMMAND_CURVE: { - const struct nk_command_curve *q = (const struct nk_command_curve *)cmd; - nk_gdi_stroke_curve(memory_dc, q->begin, q->ctrl[0], q->ctrl[1], - q->end, q->line_thickness, q->color); - } break; - case NK_COMMAND_RECT_MULTI_COLOR: - case NK_COMMAND_IMAGE: - case NK_COMMAND_ARC: - case NK_COMMAND_ARC_FILLED: - default: break; - } - } - nk_gdi_blit(gdi.window_dc); - nk_clear(&gdi.ctx); -} - -#endif - diff --git a/deps/nuklear/demo/gdip/build.bat b/deps/nuklear/demo/gdip/build.bat deleted file mode 100644 index 28f51a37..00000000 --- a/deps/nuklear/demo/gdip/build.bat +++ /dev/null @@ -1,5 +0,0 @@ -@echo off - -call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86 - -cl /nologo /W3 /O2 /fp:fast /Gm- /Fedemo.exe main.c user32.lib gdiplus.lib /link /incremental:no diff --git a/deps/nuklear/demo/gdip/main.c b/deps/nuklear/demo/gdip/main.c deleted file mode 100644 index 7d623e75..00000000 --- a/deps/nuklear/demo/gdip/main.c +++ /dev/null @@ -1,155 +0,0 @@ -/* nuklear - v1.17 - public domain */ -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#include - -#define WINDOW_WIDTH 800 -#define WINDOW_HEIGHT 600 - -#define NK_INCLUDE_FIXED_TYPES -#define NK_INCLUDE_STANDARD_IO -#define NK_INCLUDE_STANDARD_VARARGS -#define NK_INCLUDE_DEFAULT_ALLOCATOR -#define NK_IMPLEMENTATION -#define NK_GDIP_IMPLEMENTATION -#include "../../nuklear.h" -#include "nuklear_gdip.h" - -/* =============================================================== - * - * EXAMPLE - * - * ===============================================================*/ -/* These are some code examples to provide a small overview of what can be - * done with this library. To try out an example uncomment the include - * and the corresponding function. */ - #define UNUSED(a) (void)a - #define MIN(a,b) ((a) < (b) ? (a) : (b)) - #define MAX(a,b) ((a) < (b) ? (b) : (a)) - #define LEN(a) (sizeof(a)/sizeof(a)[0]) - -/*#include "../style.c"*/ -/*#include "../calculator.c"*/ -/*#include "../overview.c"*/ -/*#include "../node_editor.c"*/ - -/* =============================================================== - * - * DEMO - * - * ===============================================================*/ -static LRESULT CALLBACK -WindowProc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam) -{ - switch (msg) { - case WM_DESTROY: - PostQuitMessage(0); - return 0; - } - if (nk_gdip_handle_event(wnd, msg, wparam, lparam)) - return 0; - return DefWindowProcW(wnd, msg, wparam, lparam); -} - -int main(void) -{ - GdipFont* font; - struct nk_context *ctx; - - WNDCLASSW wc; - RECT rect = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT }; - DWORD style = WS_OVERLAPPEDWINDOW; - DWORD exstyle = WS_EX_APPWINDOW; - HWND wnd; - int running = 1; - int needs_refresh = 1; - - /* Win32 */ - memset(&wc, 0, sizeof(wc)); - wc.lpfnWndProc = WindowProc; - wc.hInstance = GetModuleHandleW(0); - wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.lpszClassName = L"NuklearWindowClass"; - RegisterClassW(&wc); - - AdjustWindowRectEx(&rect, style, FALSE, exstyle); - - wnd = CreateWindowExW(exstyle, wc.lpszClassName, L"Nuklear Demo", - style | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, - rect.right - rect.left, rect.bottom - rect.top, - NULL, NULL, wc.hInstance, NULL); - - /* GUI */ - ctx = nk_gdip_init(wnd, WINDOW_WIDTH, WINDOW_HEIGHT); - font = nk_gdipfont_create("Arial", 12); - nk_gdip_set_font(font); - - /* style.c */ - /*set_style(ctx, THEME_WHITE);*/ - /*set_style(ctx, THEME_RED);*/ - /*set_style(ctx, THEME_BLUE);*/ - /*set_style(ctx, THEME_DARK);*/ - - while (running) - { - /* Input */ - MSG msg; - nk_input_begin(ctx); - if (needs_refresh == 0) { - if (GetMessageW(&msg, NULL, 0, 0) <= 0) - running = 0; - else { - TranslateMessage(&msg); - DispatchMessageW(&msg); - } - needs_refresh = 1; - } else needs_refresh = 0; - while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { - if (msg.message == WM_QUIT) - running = 0; - TranslateMessage(&msg); - DispatchMessageW(&msg); - needs_refresh = 1; - } - nk_input_end(ctx); - - /* GUI */ - if (nk_begin(ctx, "Demo", nk_rect(50, 50, 200, 200), - NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE| - NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE)) - { - enum {EASY, HARD}; - static int op = EASY; - static int property = 20; - - nk_layout_row_static(ctx, 30, 80, 1); - if (nk_button_label(ctx, "button")) - fprintf(stdout, "button pressed\n"); - nk_layout_row_dynamic(ctx, 30, 2); - if (nk_option_label(ctx, "easy", op == EASY)) op = EASY; - if (nk_option_label(ctx, "hard", op == HARD)) op = HARD; - nk_layout_row_dynamic(ctx, 22, 1); - nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1); - } - nk_end(ctx); - if (nk_window_is_closed(ctx, "Demo")) break; - - /* -------------- EXAMPLES ---------------- */ - /*calculator(ctx);*/ - /*overview(ctx);*/ - /*node_editor(ctx);*/ - /* ----------------------------------------- */ - - /* Draw */ - nk_gdip_render(NK_ANTI_ALIASING_ON, nk_rgb(30,30,30)); - } - - nk_gdipfont_del(font); - nk_gdip_shutdown(); - UnregisterClassW(wc.lpszClassName, wc.hInstance); - return 0; -} diff --git a/deps/nuklear/demo/gdip/nuklear_gdip.h b/deps/nuklear/demo/gdip/nuklear_gdip.h deleted file mode 100644 index edefaa42..00000000 --- a/deps/nuklear/demo/gdip/nuklear_gdip.h +++ /dev/null @@ -1,1006 +0,0 @@ -/* - * Nuklear - v1.17 - public domain - * no warrenty implied; use at your own risk. - * authored from 2015-2016 by Micha Mettke - */ -/* - * ============================================================== - * - * API - * - * =============================================================== - */ -#ifndef NK_GDIP_H_ -#define NK_GDIP_H_ - -#define WIN32_LEAN_AND_MEAN -#include - -/* font */ -typedef struct GdipFont GdipFont; -NK_API GdipFont* nk_gdipfont_create(const char *name, int size); -NK_API void nk_gdipfont_del(GdipFont *font); - -NK_API struct nk_context* nk_gdip_init(HWND hwnd, unsigned int width, unsigned int height); -NK_API void nk_gdip_set_font(GdipFont *font); -NK_API int nk_gdip_handle_event(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); -NK_API void nk_gdip_render(enum nk_anti_aliasing AA, struct nk_color clear); -NK_API void nk_gdip_shutdown(void); - -#endif -/* - * ============================================================== - * - * IMPLEMENTATION - * - * =============================================================== - */ -#ifdef NK_GDIP_IMPLEMENTATION - -#include -#include - -/* manually declare everything GDI+ needs, because - GDI+ headers are not usable from C */ -#define WINGDIPAPI __stdcall -#define GDIPCONST const - -typedef struct GpGraphics GpGraphics; -typedef struct GpImage GpImage; -typedef struct GpPen GpPen; -typedef struct GpBrush GpBrush; -typedef struct GpStringFormat GpStringFormat; -typedef struct GpFont GpFont; -typedef struct GpFontFamily GpFontFamily; -typedef struct GpFontCollection GpFontCollection; - -typedef GpImage GpBitmap; -typedef GpBrush GpSolidFill; - -typedef int Status; -typedef Status GpStatus; - -typedef float REAL; -typedef DWORD ARGB; -typedef POINT GpPoint; - -typedef enum { - TextRenderingHintSystemDefault = 0, - TextRenderingHintSingleBitPerPixelGridFit = 1, - TextRenderingHintSingleBitPerPixel = 2, - TextRenderingHintAntiAliasGridFit = 3, - TextRenderingHintAntiAlias = 4, - TextRenderingHintClearTypeGridFit = 5 -} TextRenderingHint; - -typedef enum { - StringFormatFlagsDirectionRightToLeft = 0x00000001, - StringFormatFlagsDirectionVertical = 0x00000002, - StringFormatFlagsNoFitBlackBox = 0x00000004, - StringFormatFlagsDisplayFormatControl = 0x00000020, - StringFormatFlagsNoFontFallback = 0x00000400, - StringFormatFlagsMeasureTrailingSpaces = 0x00000800, - StringFormatFlagsNoWrap = 0x00001000, - StringFormatFlagsLineLimit = 0x00002000, - StringFormatFlagsNoClip = 0x00004000 -} StringFormatFlags; - -typedef enum -{ - QualityModeInvalid = -1, - QualityModeDefault = 0, - QualityModeLow = 1, - QualityModeHigh = 2 -} QualityMode; - -typedef enum -{ - SmoothingModeInvalid = QualityModeInvalid, - SmoothingModeDefault = QualityModeDefault, - SmoothingModeHighSpeed = QualityModeLow, - SmoothingModeHighQuality = QualityModeHigh, - SmoothingModeNone, - SmoothingModeAntiAlias, - SmoothingModeAntiAlias8x4 = SmoothingModeAntiAlias, - SmoothingModeAntiAlias8x8 -} SmoothingMode; - -typedef enum -{ - FontStyleRegular = 0, - FontStyleBold = 1, - FontStyleItalic = 2, - FontStyleBoldItalic = 3, - FontStyleUnderline = 4, - FontStyleStrikeout = 8 -} FontStyle; - -typedef enum { - FillModeAlternate, - FillModeWinding -} FillMode; - -typedef enum { - CombineModeReplace, - CombineModeIntersect, - CombineModeUnion, - CombineModeXor, - CombineModeExclude, - CombineModeComplement -} CombineMode; - -typedef enum { - UnitWorld, - UnitDisplay, - UnitPixel, - UnitPoint, - UnitInch, - UnitDocument, - UnitMillimeter -} Unit; - -typedef struct { - FLOAT X; - FLOAT Y; - FLOAT Width; - FLOAT Height; -} RectF; - -typedef enum { - DebugEventLevelFatal, - DebugEventLevelWarning -} DebugEventLevel; - -typedef VOID (WINAPI *DebugEventProc)(DebugEventLevel level, CHAR *message); - -typedef struct { - UINT32 GdiplusVersion; - DebugEventProc DebugEventCallback; - BOOL SuppressBackgroundThread; - BOOL SuppressExternalCodecs; -} GdiplusStartupInput; - -typedef Status (WINAPI *NotificationHookProc)(OUT ULONG_PTR *token); -typedef VOID (WINAPI *NotificationUnhookProc)(ULONG_PTR token); - -typedef struct { - NotificationHookProc NotificationHook; - NotificationUnhookProc NotificationUnhook; -} GdiplusStartupOutput; - -/* startup & shutdown */ - -Status WINAPI GdiplusStartup( - OUT ULONG_PTR *token, - const GdiplusStartupInput *input, - OUT GdiplusStartupOutput *output); - -VOID WINAPI GdiplusShutdown(ULONG_PTR token); - -/* image */ - -GpStatus WINGDIPAPI -GdipCreateBitmapFromGraphics(INT width, - INT height, - GpGraphics* target, - GpBitmap** bitmap); - -GpStatus WINGDIPAPI -GdipDisposeImage(GpImage *image); - -GpStatus WINGDIPAPI -GdipGetImageGraphicsContext(GpImage *image, GpGraphics **graphics); - -/* pen */ - -GpStatus WINGDIPAPI -GdipCreatePen1(ARGB color, REAL width, Unit unit, GpPen **pen); - -GpStatus WINGDIPAPI -GdipDeletePen(GpPen *pen); - -GpStatus WINGDIPAPI -GdipSetPenWidth(GpPen *pen, REAL width); - -GpStatus WINGDIPAPI -GdipSetPenColor(GpPen *pen, ARGB argb); - -/* brush */ - -GpStatus WINGDIPAPI -GdipCreateSolidFill(ARGB color, GpSolidFill **brush); - -GpStatus WINGDIPAPI -GdipDeleteBrush(GpBrush *brush); - -GpStatus WINGDIPAPI -GdipSetSolidFillColor(GpSolidFill *brush, ARGB color); - -/* font */ - -GpStatus WINGDIPAPI -GdipCreateFont( - GDIPCONST GpFontFamily *fontFamily, - REAL emSize, - INT style, - Unit unit, - GpFont **font -); - -GpStatus WINGDIPAPI -GdipDeleteFont(GpFont* font); - -GpStatus WINGDIPAPI -GdipGetFontSize(GpFont *font, REAL *size); - -GpStatus WINGDIPAPI -GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name, - GpFontCollection *fontCollection, - GpFontFamily **fontFamily); - -GpStatus WINGDIPAPI -GdipDeleteFontFamily(GpFontFamily *fontFamily); - -GpStatus WINGDIPAPI -GdipStringFormatGetGenericTypographic(GpStringFormat **format); - -GpStatus WINGDIPAPI -GdipSetStringFormatFlags(GpStringFormat *format, INT flags); - -GpStatus WINGDIPAPI -GdipDeleteStringFormat(GpStringFormat *format); - -/* graphics */ - - -GpStatus WINGDIPAPI -GdipCreateFromHWND(HWND hwnd, GpGraphics **graphics); - -GpStatus WINGDIPAPI -GdipCreateFromHDC(HDC hdc, GpGraphics **graphics); - -GpStatus WINGDIPAPI -GdipDeleteGraphics(GpGraphics *graphics); - -GpStatus WINGDIPAPI -GdipSetSmoothingMode(GpGraphics *graphics, SmoothingMode smoothingMode); - -GpStatus WINGDIPAPI -GdipSetClipRectI(GpGraphics *graphics, INT x, INT y, - INT width, INT height, CombineMode combineMode); - -GpStatus WINGDIPAPI -GdipDrawLineI(GpGraphics *graphics, GpPen *pen, INT x1, INT y1, - INT x2, INT y2); - -GpStatus WINGDIPAPI -GdipDrawArcI(GpGraphics *graphics, GpPen *pen, INT x, INT y, - INT width, INT height, REAL startAngle, REAL sweepAngle); - -GpStatus WINGDIPAPI -GdipFillPieI(GpGraphics *graphics, GpBrush *brush, INT x, INT y, - INT width, INT height, REAL startAngle, REAL sweepAngle); - -GpStatus WINGDIPAPI -GdipDrawRectangleI(GpGraphics *graphics, GpPen *pen, INT x, INT y, - INT width, INT height); - -GpStatus WINGDIPAPI -GdipFillRectangleI(GpGraphics *graphics, GpBrush *brush, INT x, INT y, - INT width, INT height); - -GpStatus WINGDIPAPI -GdipFillPolygonI(GpGraphics *graphics, GpBrush *brush, - GDIPCONST GpPoint *points, INT count, FillMode fillMode); - -GpStatus WINGDIPAPI -GdipDrawPolygonI(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPoint *points, - INT count); - -GpStatus WINGDIPAPI -GdipFillEllipseI(GpGraphics *graphics, GpBrush *brush, INT x, INT y, - INT width, INT height); - -GpStatus WINGDIPAPI -GdipDrawEllipseI(GpGraphics *graphics, GpPen *pen, INT x, INT y, - INT width, INT height); - -GpStatus WINGDIPAPI -GdipDrawBezierI(GpGraphics *graphics, GpPen *pen, INT x1, INT y1, - INT x2, INT y2, INT x3, INT y3, INT x4, INT y4); - -GpStatus WINGDIPAPI -GdipDrawString( - GpGraphics *graphics, - GDIPCONST WCHAR *string, - INT length, - GDIPCONST GpFont *font, - GDIPCONST RectF *layoutRect, - GDIPCONST GpStringFormat *stringFormat, - GDIPCONST GpBrush *brush -); - -GpStatus WINGDIPAPI -GdipGraphicsClear(GpGraphics *graphics, ARGB color); - -GpStatus WINGDIPAPI -GdipDrawImageI(GpGraphics *graphics, GpImage *image, INT x, INT y); - -GpStatus WINGDIPAPI -GdipMeasureString( - GpGraphics *graphics, - GDIPCONST WCHAR *string, - INT length, - GDIPCONST GpFont *font, - GDIPCONST RectF *layoutRect, - GDIPCONST GpStringFormat *stringFormat, - RectF *boundingBox, - INT *codepointsFitted, - INT *linesFilled -); - -GpStatus WINGDIPAPI -GdipSetTextRenderingHint(GpGraphics *graphics, TextRenderingHint mode); - -struct GdipFont -{ - struct nk_user_font nk; - GpFont* handle; -}; - -static struct { - ULONG_PTR token; - - GpGraphics *window; - GpGraphics *memory; - GpImage *bitmap; - GpPen *pen; - GpSolidFill *brush; - GpStringFormat *format; - - struct nk_context ctx; -} gdip; - -static ARGB convert_color(struct nk_color c) -{ - return (c.a << 24) | (c.r << 16) | (c.g << 8) | c.b; -} - -static void -nk_gdip_scissor(float x, float y, float w, float h) -{ - GdipSetClipRectI(gdip.memory, (INT)x, (INT)y, (INT)(w + 1), (INT)(h + 1), CombineModeReplace); -} - -static void -nk_gdip_stroke_line(short x0, short y0, short x1, - short y1, unsigned int line_thickness, struct nk_color col) -{ - GdipSetPenWidth(gdip.pen, (REAL)line_thickness); - GdipSetPenColor(gdip.pen, convert_color(col)); - GdipDrawLineI(gdip.memory, gdip.pen, x0, y0, x1, y1); -} - -static void -nk_gdip_stroke_rect(short x, short y, unsigned short w, - unsigned short h, unsigned short r, unsigned short line_thickness, struct nk_color col) -{ - GdipSetPenWidth(gdip.pen, (REAL)line_thickness); - GdipSetPenColor(gdip.pen, convert_color(col)); - if (r == 0) { - GdipDrawRectangleI(gdip.memory, gdip.pen, x, y, w, h); - } else { - INT d = 2 * r; - GdipDrawArcI(gdip.memory, gdip.pen, x, y, d, d, 180, 90); - GdipDrawLineI(gdip.memory, gdip.pen, x + r, y, x + w - r, y); - GdipDrawArcI(gdip.memory, gdip.pen, x + w - d, y, d, d, 270, 90); - GdipDrawLineI(gdip.memory, gdip.pen, x + w, y + r, x + w, y + h - r); - GdipDrawArcI(gdip.memory, gdip.pen, x + w - d, y + h - d, d, d, 0, 90); - GdipDrawLineI(gdip.memory, gdip.pen, x, y + r, x, y + h - r); - GdipDrawArcI(gdip.memory, gdip.pen, x, y + h - d, d, d, 90, 90); - GdipDrawLineI(gdip.memory, gdip.pen, x + r, y + h, x + w - r, y + h); - } -} - -static void -nk_gdip_fill_rect(short x, short y, unsigned short w, - unsigned short h, unsigned short r, struct nk_color col) -{ - GdipSetSolidFillColor(gdip.brush, convert_color(col)); - if (r == 0) { - GdipFillRectangleI(gdip.memory, gdip.brush, x, y, w, h); - } else { - INT d = 2 * r; - GdipFillRectangleI(gdip.memory, gdip.brush, x + r, y, w - d, h); - GdipFillRectangleI(gdip.memory, gdip.brush, x, y + r, w, h - d); - GdipFillPieI(gdip.memory, gdip.brush, x, y, d, d, 180, 90); - GdipFillPieI(gdip.memory, gdip.brush, x + w - d, y, d, d, 270, 90); - GdipFillPieI(gdip.memory, gdip.brush, x + w - d, y + h - d, d, d, 0, 90); - GdipFillPieI(gdip.memory, gdip.brush, x, y + h - d, d, d, 90, 90); - } -} - -static void -nk_gdip_fill_triangle(short x0, short y0, short x1, - short y1, short x2, short y2, struct nk_color col) -{ - POINT points[] = { - { x0, y0 }, - { x1, y1 }, - { x2, y2 }, - }; - - GdipSetSolidFillColor(gdip.brush, convert_color(col)); - GdipFillPolygonI(gdip.memory, gdip.brush, points, 3, FillModeAlternate); -} - -static void -nk_gdip_stroke_triangle(short x0, short y0, short x1, - short y1, short x2, short y2, unsigned short line_thickness, struct nk_color col) -{ - POINT points[] = { - { x0, y0 }, - { x1, y1 }, - { x2, y2 }, - { x0, y0 }, - }; - GdipSetPenWidth(gdip.pen, (REAL)line_thickness); - GdipSetPenColor(gdip.pen, convert_color(col)); - GdipDrawPolygonI(gdip.memory, gdip.pen, points, 4); -} - -static void -nk_gdip_fill_polygon(const struct nk_vec2i *pnts, int count, struct nk_color col) -{ - int i = 0; - #define MAX_POINTS 64 - POINT points[MAX_POINTS]; - GdipSetSolidFillColor(gdip.brush, convert_color(col)); - for (i = 0; i < count && i < MAX_POINTS; ++i) { - points[i].x = pnts[i].x; - points[i].y = pnts[i].y; - } - GdipFillPolygonI(gdip.memory, gdip.brush, points, i, FillModeAlternate); - #undef MAX_POINTS -} - -static void -nk_gdip_stroke_polygon(const struct nk_vec2i *pnts, int count, - unsigned short line_thickness, struct nk_color col) -{ - GdipSetPenWidth(gdip.pen, (REAL)line_thickness); - GdipSetPenColor(gdip.pen, convert_color(col)); - if (count > 0) { - int i; - for (i = 1; i < count; ++i) - GdipDrawLineI(gdip.memory, gdip.pen, pnts[i-1].x, pnts[i-1].y, pnts[i].x, pnts[i].y); - GdipDrawLineI(gdip.memory, gdip.pen, pnts[count-1].x, pnts[count-1].y, pnts[0].x, pnts[0].y); - } -} - -static void -nk_gdip_stroke_polyline(const struct nk_vec2i *pnts, - int count, unsigned short line_thickness, struct nk_color col) -{ - GdipSetPenWidth(gdip.pen, (REAL)line_thickness); - GdipSetPenColor(gdip.pen, convert_color(col)); - if (count > 0) { - int i; - for (i = 1; i < count; ++i) - GdipDrawLineI(gdip.memory, gdip.pen, pnts[i-1].x, pnts[i-1].y, pnts[i].x, pnts[i].y); - } -} - -static void -nk_gdip_fill_circle(short x, short y, unsigned short w, - unsigned short h, struct nk_color col) -{ - GdipSetSolidFillColor(gdip.brush, convert_color(col)); - GdipFillEllipseI(gdip.memory, gdip.brush, x, y, w, h); -} - -static void -nk_gdip_stroke_circle(short x, short y, unsigned short w, - unsigned short h, unsigned short line_thickness, struct nk_color col) -{ - GdipSetPenWidth(gdip.pen, (REAL)line_thickness); - GdipSetPenColor(gdip.pen, convert_color(col)); - GdipDrawEllipseI(gdip.memory, gdip.pen, x, y, w, h); -} - -static void -nk_gdip_stroke_curve(struct nk_vec2i p1, - struct nk_vec2i p2, struct nk_vec2i p3, struct nk_vec2i p4, - unsigned short line_thickness, struct nk_color col) -{ - GdipSetPenWidth(gdip.pen, (REAL)line_thickness); - GdipSetPenColor(gdip.pen, convert_color(col)); - GdipDrawBezierI(gdip.memory, gdip.pen, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y); -} - -static void -nk_gdip_draw_text(short x, short y, unsigned short w, unsigned short h, - const char *text, int len, GdipFont *font, struct nk_color cbg, struct nk_color cfg) -{ - int wsize; - WCHAR* wstr; - RectF layout = { (FLOAT)x, (FLOAT)y, (FLOAT)w, (FLOAT)h }; - - if(!text || !font || !len) return; - - wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0); - wstr = (WCHAR*)_alloca(wsize * sizeof(wchar_t)); - MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize); - - GdipSetSolidFillColor(gdip.brush, convert_color(cbg)); - GdipFillRectangleI(gdip.memory, gdip.brush, x, y, w, h); - GdipSetSolidFillColor(gdip.brush, convert_color(cfg)); - GdipDrawString(gdip.memory, wstr, wsize, font->handle, &layout, gdip.format, gdip.brush); -} - -static void -nk_gdip_clear(struct nk_color col) -{ - GdipGraphicsClear(gdip.memory, convert_color(col)); -} - -static void -nk_gdip_blit(GpGraphics *graphics) -{ - GdipDrawImageI(graphics, gdip.bitmap, 0, 0); -} - -GdipFont* -nk_gdipfont_create(const char *name, int size) -{ - GdipFont *font = (GdipFont*)calloc(1, sizeof(GdipFont)); - GpFontFamily *family; - - int wsize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0); - WCHAR* wname = (WCHAR*)_alloca((wsize + 1) * sizeof(wchar_t)); - MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, wsize); - wname[wsize] = 0; - - GdipCreateFontFamilyFromName(wname, NULL, &family); - GdipCreateFont(family, (REAL)size, FontStyleRegular, UnitPixel, &font->handle); - GdipDeleteFontFamily(family); - - return font; -} - -static float -nk_gdipfont_get_text_width(nk_handle handle, float height, const char *text, int len) -{ - GdipFont *font = (GdipFont *)handle.ptr; - RectF layout = { 0.0f, 0.0f, 65536.0f, 65536.0f }; - RectF bbox; - int wsize; - WCHAR* wstr; - if (!font || !text) - return 0; - - (void)height; - wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0); - wstr = (WCHAR*)_alloca(wsize * sizeof(wchar_t)); - MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize); - - GdipMeasureString(gdip.memory, wstr, wsize, font->handle, &layout, gdip.format, &bbox, NULL, NULL); - return bbox.Width; -} - -void -nk_gdipfont_del(GdipFont *font) -{ - if(!font) return; - GdipDeleteFont(font->handle); - free(font); -} - -static void -nk_gdip_clipbard_paste(nk_handle usr, struct nk_text_edit *edit) -{ - HGLOBAL mem; - SIZE_T size; - LPCWSTR wstr; - int utf8size; - char* utf8; - (void)usr; - - if (!IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL)) - return; - - mem = (HGLOBAL)GetClipboardData(CF_UNICODETEXT); - if (!mem) { - CloseClipboard(); - return; - } - - size = GlobalSize(mem) - 1; - if (!size) { - CloseClipboard(); - return; - } - - wstr = (LPCWSTR)GlobalLock(mem); - if (!wstr) { - CloseClipboard(); - return; - } - - utf8size = WideCharToMultiByte(CP_UTF8, 0, wstr, (int)(size / sizeof(wchar_t)), NULL, 0, NULL, NULL); - if (!utf8size) { - GlobalUnlock(mem); - CloseClipboard(); - return; - } - - utf8 = (char*)malloc(utf8size); - if (!utf8) { - GlobalUnlock(mem); - CloseClipboard(); - return; - } - - WideCharToMultiByte(CP_UTF8, 0, wstr, (int)(size / sizeof(wchar_t)), utf8, utf8size, NULL, NULL); - nk_textedit_paste(edit, utf8, utf8size); - free(utf8); - GlobalUnlock(mem); - CloseClipboard(); -} - -static void -nk_gdip_clipbard_copy(nk_handle usr, const char *text, int len) -{ - HGLOBAL mem; - wchar_t* wstr; - int wsize; - (void)usr; - - if (!OpenClipboard(NULL)) - return; - - wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0); - if (!wsize) { - CloseClipboard(); - return; - } - - mem = (HGLOBAL)GlobalAlloc(GMEM_MOVEABLE, (wsize + 1) * sizeof(wchar_t)); - if (!mem) { - CloseClipboard(); - return; - } - - wstr = (wchar_t*)GlobalLock(mem); - if (!wstr) { - GlobalFree(mem); - CloseClipboard(); - return; - } - - MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize); - wstr[wsize] = 0; - GlobalUnlock(mem); - if (!SetClipboardData(CF_UNICODETEXT, mem)) - GlobalFree(mem); - CloseClipboard(); -} - -NK_API struct nk_context* -nk_gdip_init(HWND hwnd, unsigned int width, unsigned int height) -{ - GdiplusStartupInput startup = { 1, NULL, FALSE, TRUE }; - GdiplusStartup(&gdip.token, &startup, NULL); - - GdipCreateFromHWND(hwnd, &gdip.window); - GdipCreateBitmapFromGraphics(width, height, gdip.window, &gdip.bitmap); - GdipGetImageGraphicsContext(gdip.bitmap, &gdip.memory); - GdipCreatePen1(0, 1.0f, UnitPixel, &gdip.pen); - GdipCreateSolidFill(0, &gdip.brush); - GdipStringFormatGetGenericTypographic(&gdip.format); - GdipSetStringFormatFlags(gdip.format, StringFormatFlagsNoFitBlackBox | - StringFormatFlagsMeasureTrailingSpaces | StringFormatFlagsNoWrap | - StringFormatFlagsNoClip); - - nk_init_default(&gdip.ctx, NULL); - gdip.ctx.clip.copy = nk_gdip_clipbard_copy; - gdip.ctx.clip.paste = nk_gdip_clipbard_paste; - return &gdip.ctx; -} - -NK_API void -nk_gdip_set_font(GdipFont *gdipfont) -{ - struct nk_user_font *font = &gdipfont->nk; - font->userdata = nk_handle_ptr(gdipfont); - GdipGetFontSize(gdipfont->handle, &font->height); - font->width = nk_gdipfont_get_text_width; - nk_style_set_font(&gdip.ctx, font); -} - -NK_API int -nk_gdip_handle_event(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam) -{ - switch (msg) - { - case WM_SIZE: - if (gdip.window) - { - unsigned int width = LOWORD(lparam); - unsigned int height = HIWORD(lparam); - GdipDeleteGraphics(gdip.window); - GdipDeleteGraphics(gdip.memory); - GdipDisposeImage(gdip.bitmap); - GdipCreateFromHWND(wnd, &gdip.window); - GdipCreateBitmapFromGraphics(width, height, gdip.window, &gdip.bitmap); - GdipGetImageGraphicsContext(gdip.bitmap, &gdip.memory); - } - break; - - case WM_PAINT: - { - PAINTSTRUCT paint; - HDC dc = BeginPaint(wnd, &paint); - GpGraphics *graphics; - GdipCreateFromHDC(dc, &graphics); - nk_gdip_blit(graphics); - GdipDeleteGraphics(graphics); - EndPaint(wnd, &paint); - return 1; - } - - case WM_KEYDOWN: - case WM_KEYUP: - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - { - int down = !((lparam >> 31) & 1); - int ctrl = GetKeyState(VK_CONTROL) & (1 << 15); - - switch (wparam) - { - case VK_SHIFT: - case VK_LSHIFT: - case VK_RSHIFT: - nk_input_key(&gdip.ctx, NK_KEY_SHIFT, down); - return 1; - - case VK_DELETE: - nk_input_key(&gdip.ctx, NK_KEY_DEL, down); - return 1; - - case VK_RETURN: - nk_input_key(&gdip.ctx, NK_KEY_ENTER, down); - return 1; - - case VK_TAB: - nk_input_key(&gdip.ctx, NK_KEY_TAB, down); - return 1; - - case VK_LEFT: - if (ctrl) - nk_input_key(&gdip.ctx, NK_KEY_TEXT_WORD_LEFT, down); - else - nk_input_key(&gdip.ctx, NK_KEY_LEFT, down); - return 1; - - case VK_RIGHT: - if (ctrl) - nk_input_key(&gdip.ctx, NK_KEY_TEXT_WORD_RIGHT, down); - else - nk_input_key(&gdip.ctx, NK_KEY_RIGHT, down); - return 1; - - case VK_BACK: - nk_input_key(&gdip.ctx, NK_KEY_BACKSPACE, down); - return 1; - - case VK_HOME: - nk_input_key(&gdip.ctx, NK_KEY_TEXT_START, down); - nk_input_key(&gdip.ctx, NK_KEY_SCROLL_START, down); - return 1; - - case VK_END: - nk_input_key(&gdip.ctx, NK_KEY_TEXT_END, down); - nk_input_key(&gdip.ctx, NK_KEY_SCROLL_END, down); - return 1; - - case VK_NEXT: - nk_input_key(&gdip.ctx, NK_KEY_SCROLL_DOWN, down); - return 1; - - case VK_PRIOR: - nk_input_key(&gdip.ctx, NK_KEY_SCROLL_UP, down); - return 1; - - case 'C': - if (ctrl) { - nk_input_key(&gdip.ctx, NK_KEY_COPY, down); - return 1; - } - break; - - case 'V': - if (ctrl) { - nk_input_key(&gdip.ctx, NK_KEY_PASTE, down); - return 1; - } - break; - - case 'X': - if (ctrl) { - nk_input_key(&gdip.ctx, NK_KEY_CUT, down); - return 1; - } - break; - - case 'Z': - if (ctrl) { - nk_input_key(&gdip.ctx, NK_KEY_TEXT_UNDO, down); - return 1; - } - break; - - case 'R': - if (ctrl) { - nk_input_key(&gdip.ctx, NK_KEY_TEXT_REDO, down); - return 1; - } - break; - } - return 0; - } - - case WM_CHAR: - if (wparam >= 32) - { - nk_input_unicode(&gdip.ctx, (nk_rune)wparam); - return 1; - } - break; - - case WM_LBUTTONDOWN: - nk_input_button(&gdip.ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1); - SetCapture(wnd); - return 1; - - case WM_LBUTTONUP: - nk_input_button(&gdip.ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0); - ReleaseCapture(); - return 1; - - case WM_RBUTTONDOWN: - nk_input_button(&gdip.ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1); - SetCapture(wnd); - return 1; - - case WM_RBUTTONUP: - nk_input_button(&gdip.ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0); - ReleaseCapture(); - return 1; - - case WM_MBUTTONDOWN: - nk_input_button(&gdip.ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 1); - SetCapture(wnd); - return 1; - - case WM_MBUTTONUP: - nk_input_button(&gdip.ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 0); - ReleaseCapture(); - return 1; - - case WM_MOUSEWHEEL: - nk_input_scroll(&gdip.ctx, (float)(short)HIWORD(wparam) / WHEEL_DELTA); - return 1; - - case WM_MOUSEMOVE: - nk_input_motion(&gdip.ctx, (short)LOWORD(lparam), (short)HIWORD(lparam)); - return 1; - } - - return 0; -} - -NK_API void -nk_gdip_shutdown(void) -{ - GdipDeleteGraphics(gdip.window); - GdipDeleteGraphics(gdip.memory); - GdipDisposeImage(gdip.bitmap); - GdipDeletePen(gdip.pen); - GdipDeleteBrush(gdip.brush); - GdipDeleteStringFormat(gdip.format); - GdiplusShutdown(gdip.token); - - nk_free(&gdip.ctx); -} - -NK_API void -nk_gdip_render(enum nk_anti_aliasing AA, struct nk_color clear) -{ - const struct nk_command *cmd; - - GdipSetTextRenderingHint(gdip.memory, AA != NK_ANTI_ALIASING_OFF ? - TextRenderingHintClearTypeGridFit : TextRenderingHintSingleBitPerPixelGridFit); - GdipSetSmoothingMode(gdip.memory, AA != NK_ANTI_ALIASING_OFF ? - SmoothingModeHighQuality : SmoothingModeNone); - nk_gdip_clear(clear); - - nk_foreach(cmd, &gdip.ctx) - { - switch (cmd->type) { - case NK_COMMAND_NOP: break; - case NK_COMMAND_SCISSOR: { - const struct nk_command_scissor *s =(const struct nk_command_scissor*)cmd; - nk_gdip_scissor(s->x, s->y, s->w, s->h); - } break; - case NK_COMMAND_LINE: { - const struct nk_command_line *l = (const struct nk_command_line *)cmd; - nk_gdip_stroke_line(l->begin.x, l->begin.y, l->end.x, - l->end.y, l->line_thickness, l->color); - } break; - case NK_COMMAND_RECT: { - const struct nk_command_rect *r = (const struct nk_command_rect *)cmd; - nk_gdip_stroke_rect(r->x, r->y, r->w, r->h, - (unsigned short)r->rounding, r->line_thickness, r->color); - } break; - case NK_COMMAND_RECT_FILLED: { - const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled *)cmd; - nk_gdip_fill_rect(r->x, r->y, r->w, r->h, - (unsigned short)r->rounding, r->color); - } break; - case NK_COMMAND_CIRCLE: { - const struct nk_command_circle *c = (const struct nk_command_circle *)cmd; - nk_gdip_stroke_circle(c->x, c->y, c->w, c->h, c->line_thickness, c->color); - } break; - case NK_COMMAND_CIRCLE_FILLED: { - const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd; - nk_gdip_fill_circle(c->x, c->y, c->w, c->h, c->color); - } break; - case NK_COMMAND_TRIANGLE: { - const struct nk_command_triangle*t = (const struct nk_command_triangle*)cmd; - nk_gdip_stroke_triangle(t->a.x, t->a.y, t->b.x, t->b.y, - t->c.x, t->c.y, t->line_thickness, t->color); - } break; - case NK_COMMAND_TRIANGLE_FILLED: { - const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled *)cmd; - nk_gdip_fill_triangle(t->a.x, t->a.y, t->b.x, t->b.y, - t->c.x, t->c.y, t->color); - } break; - case NK_COMMAND_POLYGON: { - const struct nk_command_polygon *p =(const struct nk_command_polygon*)cmd; - nk_gdip_stroke_polygon(p->points, p->point_count, p->line_thickness,p->color); - } break; - case NK_COMMAND_POLYGON_FILLED: { - const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled *)cmd; - nk_gdip_fill_polygon(p->points, p->point_count, p->color); - } break; - case NK_COMMAND_POLYLINE: { - const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd; - nk_gdip_stroke_polyline(p->points, p->point_count, p->line_thickness, p->color); - } break; - case NK_COMMAND_TEXT: { - const struct nk_command_text *t = (const struct nk_command_text*)cmd; - nk_gdip_draw_text(t->x, t->y, t->w, t->h, - (const char*)t->string, t->length, - (GdipFont*)t->font->userdata.ptr, - t->background, t->foreground); - } break; - case NK_COMMAND_CURVE: { - const struct nk_command_curve *q = (const struct nk_command_curve *)cmd; - nk_gdip_stroke_curve(q->begin, q->ctrl[0], q->ctrl[1], - q->end, q->line_thickness, q->color); - } break; - case NK_COMMAND_RECT_MULTI_COLOR: - case NK_COMMAND_IMAGE: - case NK_COMMAND_ARC: - case NK_COMMAND_ARC_FILLED: - default: break; - } - } - nk_gdip_blit(gdip.window); - nk_clear(&gdip.ctx); -} - -#endif - diff --git a/deps/nuklear/demo/glfw_opengl2/main.c b/deps/nuklear/demo/glfw_opengl2/main.c deleted file mode 100644 index 1c0f284f..00000000 --- a/deps/nuklear/demo/glfw_opengl2/main.c +++ /dev/null @@ -1,165 +0,0 @@ -/* nuklear - v1.17 - public domain */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define NK_INCLUDE_FIXED_TYPES -#define NK_INCLUDE_STANDARD_IO -#define NK_INCLUDE_STANDARD_VARARGS -#define NK_INCLUDE_DEFAULT_ALLOCATOR -#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT -#define NK_INCLUDE_FONT_BAKING -#define NK_INCLUDE_DEFAULT_FONT -#define NK_IMPLEMENTATION -#define NK_GLFW_GL2_IMPLEMENTATION -#include "../../nuklear.h" -#include "nuklear_glfw_gl2.h" - -#define WINDOW_WIDTH 1200 -#define WINDOW_HEIGHT 800 - -#define MAX_VERTEX_BUFFER 512 * 1024 -#define MAX_ELEMENT_BUFFER 128 * 1024 - -#define UNUSED(a) (void)a -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) < (b) ? (b) : (a)) -#define LEN(a) (sizeof(a)/sizeof(a)[0]) - -/* =============================================================== - * - * EXAMPLE - * - * ===============================================================*/ -/* This are some code examples to provide a small overview of what can be - * done with this library. To try out an example uncomment the include - * and the corresponding function. */ -/*#include "../style.c"*/ -/*#include "../calculator.c"*/ -/*#include "../overview.c"*/ -/*#include "../node_editor.c"*/ - -/* =============================================================== - * - * DEMO - * - * ===============================================================*/ -static void error_callback(int e, const char *d) -{printf("Error %d: %s\n", e, d);} - -int main(void) -{ - /* Platform */ - static GLFWwindow *win; - int width = 0, height = 0; - struct nk_context *ctx; - struct nk_color background; - - /* GLFW */ - glfwSetErrorCallback(error_callback); - if (!glfwInit()) { - fprintf(stdout, "[GFLW] failed to init!\n"); - exit(1); - } - win = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Demo", NULL, NULL); - glfwMakeContextCurrent(win); - glfwGetWindowSize(win, &width, &height); - - /* GUI */ - ctx = nk_glfw3_init(win, NK_GLFW3_INSTALL_CALLBACKS); - /* Load Fonts: if none of these are loaded a default font will be used */ - /* Load Cursor: if you uncomment cursor loading please hide the cursor */ - {struct nk_font_atlas *atlas; - nk_glfw3_font_stash_begin(&atlas); - /*struct nk_font *droid = nk_font_atlas_add_from_file(atlas, "../../../extra_font/DroidSans.ttf", 14, 0);*/ - /*struct nk_font *roboto = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Roboto-Regular.ttf", 14, 0);*/ - /*struct nk_font *future = nk_font_atlas_add_from_file(atlas, "../../../extra_font/kenvector_future_thin.ttf", 13, 0);*/ - /*struct nk_font *clean = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyClean.ttf", 12, 0);*/ - /*struct nk_font *tiny = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyTiny.ttf", 10, 0);*/ - /*struct nk_font *cousine = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Cousine-Regular.ttf", 13, 0);*/ - nk_glfw3_font_stash_end(); - /*nk_style_load_all_cursors(ctx, atlas->cursors);*/ - /*nk_style_set_font(ctx, &droid->handle);*/} - - /* style.c */ - /*set_style(ctx, THEME_WHITE);*/ - /*set_style(ctx, THEME_RED);*/ - /*set_style(ctx, THEME_BLUE);*/ - /*set_style(ctx, THEME_DARK);*/ - - background = nk_rgb(28,48,62); - while (!glfwWindowShouldClose(win)) - { - /* Input */ - glfwPollEvents(); - nk_glfw3_new_frame(); - - /* GUI */ - if (nk_begin(ctx, "Demo", nk_rect(50, 50, 230, 250), - NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE| - NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE)) - { - enum {EASY, HARD}; - static int op = EASY; - static int property = 20; - nk_layout_row_static(ctx, 30, 80, 1); - if (nk_button_label(ctx, "button")) - fprintf(stdout, "button pressed\n"); - - nk_layout_row_dynamic(ctx, 30, 2); - if (nk_option_label(ctx, "easy", op == EASY)) op = EASY; - if (nk_option_label(ctx, "hard", op == HARD)) op = HARD; - - nk_layout_row_dynamic(ctx, 25, 1); - nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1); - - nk_layout_row_dynamic(ctx, 20, 1); - nk_label(ctx, "background:", NK_TEXT_LEFT); - nk_layout_row_dynamic(ctx, 25, 1); - if (nk_combo_begin_color(ctx, background, nk_vec2(nk_widget_width(ctx),400))) { - nk_layout_row_dynamic(ctx, 120, 1); - background = nk_color_picker(ctx, background, NK_RGBA); - nk_layout_row_dynamic(ctx, 25, 1); - background.r = (nk_byte)nk_propertyi(ctx, "#R:", 0, background.r, 255, 1,1); - background.g = (nk_byte)nk_propertyi(ctx, "#G:", 0, background.g, 255, 1,1); - background.b = (nk_byte)nk_propertyi(ctx, "#B:", 0, background.b, 255, 1,1); - background.a = (nk_byte)nk_propertyi(ctx, "#A:", 0, background.a, 255, 1,1); - nk_combo_end(ctx); - } - } - nk_end(ctx); - - /* -------------- EXAMPLES ---------------- */ - /*calculator(ctx);*/ - /*overview(ctx);*/ - /*node_editor(ctx);*/ - /* ----------------------------------------- */ - - /* Draw */ - {float bg[4]; - nk_color_fv(bg, background); - glfwGetWindowSize(win, &width, &height); - glViewport(0, 0, width, height); - glClear(GL_COLOR_BUFFER_BIT); - glClearColor(bg[0], bg[1], bg[2], bg[3]); - /* IMPORTANT: `nk_glfw_render` modifies some global OpenGL state - * with blending, scissor, face culling and depth test and defaults everything - * back into a default state. Make sure to either save and restore or - * reset your own state after drawing rendering the UI. */ - nk_glfw3_render(NK_ANTI_ALIASING_ON, MAX_VERTEX_BUFFER, MAX_ELEMENT_BUFFER); - glfwSwapBuffers(win);} - } - nk_glfw3_shutdown(); - glfwTerminate(); - return 0; -} - diff --git a/deps/nuklear/demo/glfw_opengl2/nuklear_glfw_gl2.h b/deps/nuklear/demo/glfw_opengl2/nuklear_glfw_gl2.h deleted file mode 100644 index a2a615c6..00000000 --- a/deps/nuklear/demo/glfw_opengl2/nuklear_glfw_gl2.h +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Nuklear - v1.17 - public domain - * no warrenty implied; use at your own risk. - * authored from 2015-2016 by Micha Mettke - */ -/* - * ============================================================== - * - * API - * - * =============================================================== - */ -#ifndef NK_GLFW_GL2_H_ -#define NK_GLFW_GL2_H_ - -#include - -enum nk_glfw_init_state{ - NK_GLFW3_DEFAULT = 0, - NK_GLFW3_INSTALL_CALLBACKS -}; -NK_API struct nk_context* nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state); -NK_API void nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas); -NK_API void nk_glfw3_font_stash_end(void); - -NK_API void nk_glfw3_new_frame(void); -NK_API void nk_glfw3_render(enum nk_anti_aliasing , int max_vertex_buffer, int max_element_buffer); -NK_API void nk_glfw3_shutdown(void); - -NK_API void nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint); -NK_API void nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff); - -#endif - -/* - * ============================================================== - * - * IMPLEMENTATION - * - * =============================================================== - */ -#ifdef NK_GLFW_GL2_IMPLEMENTATION - -#ifndef NK_GLFW_TEXT_MAX -#define NK_GLFW_TEXT_MAX 256 -#endif - -struct nk_glfw_device { - struct nk_buffer cmds; - struct nk_draw_null_texture null; - GLuint font_tex; -}; - -struct nk_glfw_vertex { - float position[2]; - float uv[2]; - nk_byte col[4]; -}; - -static struct nk_glfw { - GLFWwindow *win; - int width, height; - int display_width, display_height; - struct nk_glfw_device ogl; - struct nk_context ctx; - struct nk_font_atlas atlas; - struct nk_vec2 fb_scale; - unsigned int text[NK_GLFW_TEXT_MAX]; - int text_len; - float scroll; -} glfw; - -NK_INTERN void -nk_glfw3_device_upload_atlas(const void *image, int width, int height) -{ - struct nk_glfw_device *dev = &glfw.ogl; - glGenTextures(1, &dev->font_tex); - glBindTexture(GL_TEXTURE_2D, dev->font_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, image); -} - -NK_API void -nk_glfw3_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_buffer) -{ - /* setup global state */ - struct nk_glfw_device *dev = &glfw.ogl; - glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT|GL_TRANSFORM_BIT); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnable(GL_BLEND); - glEnable(GL_TEXTURE_2D); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - /* setup viewport/project */ - glViewport(0,0,(GLsizei)glfw.display_width,(GLsizei)glfw.display_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, glfw.width, glfw.height, 0.0f, -1.0f, 1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - { - GLsizei vs = sizeof(struct nk_glfw_vertex); - size_t vp = offsetof(struct nk_glfw_vertex, position); - size_t vt = offsetof(struct nk_glfw_vertex, uv); - size_t vc = offsetof(struct nk_glfw_vertex, col); - - /* convert from command queue into draw list and draw to screen */ - const struct nk_draw_command *cmd; - const nk_draw_index *offset = NULL; - struct nk_buffer vbuf, ebuf; - - /* fill convert configuration */ - struct nk_convert_config config; - static const struct nk_draw_vertex_layout_element vertex_layout[] = { - {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, position)}, - {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, uv)}, - {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_glfw_vertex, col)}, - {NK_VERTEX_LAYOUT_END} - }; - NK_MEMSET(&config, 0, sizeof(config)); - config.vertex_layout = vertex_layout; - config.vertex_size = sizeof(struct nk_glfw_vertex); - config.vertex_alignment = NK_ALIGNOF(struct nk_glfw_vertex); - config.null = dev->null; - config.circle_segment_count = 22; - config.curve_segment_count = 22; - config.arc_segment_count = 22; - config.global_alpha = 1.0f; - config.shape_AA = AA; - config.line_AA = AA; - - /* convert shapes into vertexes */ - nk_buffer_init_default(&vbuf); - nk_buffer_init_default(&ebuf); - nk_convert(&glfw.ctx, &dev->cmds, &vbuf, &ebuf, &config); - - /* setup vertex buffer pointer */ - {const void *vertices = nk_buffer_memory_const(&vbuf); - glVertexPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vp)); - glTexCoordPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vt)); - glColorPointer(4, GL_UNSIGNED_BYTE, vs, (const void*)((const nk_byte*)vertices + vc));} - - /* iterate over and execute each draw command */ - offset = (const nk_draw_index*)nk_buffer_memory_const(&ebuf); - nk_draw_foreach(cmd, &glfw.ctx, &dev->cmds) - { - if (!cmd->elem_count) continue; - glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id); - glScissor( - (GLint)(cmd->clip_rect.x * glfw.fb_scale.x), - (GLint)((glfw.height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * glfw.fb_scale.y), - (GLint)(cmd->clip_rect.w * glfw.fb_scale.x), - (GLint)(cmd->clip_rect.h * glfw.fb_scale.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset); - offset += cmd->elem_count; - } - nk_clear(&glfw.ctx); - nk_buffer_free(&vbuf); - nk_buffer_free(&ebuf); - } - - /* default OpenGL state */ - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - - glBindTexture(GL_TEXTURE_2D, 0); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); -} - -NK_API void -nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint) -{ - (void)win; - if (glfw.text_len < NK_GLFW_TEXT_MAX) - glfw.text[glfw.text_len++] = codepoint; -} - -NK_API void -nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff) -{ - (void)win; (void)xoff; - glfw.scroll += (float)yoff; -} - -NK_INTERN void -nk_glfw3_clipbard_paste(nk_handle usr, struct nk_text_edit *edit) -{ - const char *text = glfwGetClipboardString(glfw.win); - if (text) nk_textedit_paste(edit, text, nk_strlen(text)); - (void)usr; -} - -NK_INTERN void -nk_glfw3_clipbard_copy(nk_handle usr, const char *text, int len) -{ - char *str = 0; - (void)usr; - if (!len) return; - str = (char*)malloc((size_t)len+1); - if (!str) return; - memcpy(str, text, (size_t)len); - str[len] = '\0'; - glfwSetClipboardString(glfw.win, str); - free(str); -} - -NK_API struct nk_context* -nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state init_state) -{ - glfw.win = win; - if (init_state == NK_GLFW3_INSTALL_CALLBACKS) { - glfwSetScrollCallback(win, nk_gflw3_scroll_callback); - glfwSetCharCallback(win, nk_glfw3_char_callback); - } - - nk_init_default(&glfw.ctx, 0); - glfw.ctx.clip.copy = nk_glfw3_clipbard_copy; - glfw.ctx.clip.paste = nk_glfw3_clipbard_paste; - glfw.ctx.clip.userdata = nk_handle_ptr(0); - nk_buffer_init_default(&glfw.ogl.cmds); - return &glfw.ctx; -} - -NK_API void -nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas) -{ - nk_font_atlas_init_default(&glfw.atlas); - nk_font_atlas_begin(&glfw.atlas); - *atlas = &glfw.atlas; -} - -NK_API void -nk_glfw3_font_stash_end(void) -{ - const void *image; int w, h; - image = nk_font_atlas_bake(&glfw.atlas, &w, &h, NK_FONT_ATLAS_RGBA32); - nk_glfw3_device_upload_atlas(image, w, h); - nk_font_atlas_end(&glfw.atlas, nk_handle_id((int)glfw.ogl.font_tex), &glfw.ogl.null); - if (glfw.atlas.default_font) - nk_style_set_font(&glfw.ctx, &glfw.atlas.default_font->handle); -} - -NK_API void -nk_glfw3_new_frame(void) -{ - int i; - double x, y; - struct nk_context *ctx = &glfw.ctx; - struct GLFWwindow *win = glfw.win; - - glfwGetWindowSize(win, &glfw.width, &glfw.height); - glfwGetFramebufferSize(win, &glfw.display_width, &glfw.display_height); - glfw.fb_scale.x = (float)glfw.display_width/(float)glfw.width; - glfw.fb_scale.y = (float)glfw.display_height/(float)glfw.height; - - nk_input_begin(ctx); - for (i = 0; i < glfw.text_len; ++i) - nk_input_unicode(ctx, glfw.text[i]); - - /* optional grabbing behavior */ - if (ctx->input.mouse.grab) - glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); - else if (ctx->input.mouse.ungrab) - glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_NORMAL); - - nk_input_key(ctx, NK_KEY_DEL, glfwGetKey(win, GLFW_KEY_DELETE) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_ENTER, glfwGetKey(win, GLFW_KEY_ENTER) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_TAB, glfwGetKey(win, GLFW_KEY_TAB) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_BACKSPACE, glfwGetKey(win, GLFW_KEY_BACKSPACE) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_UP, glfwGetKey(win, GLFW_KEY_UP) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_DOWN, glfwGetKey(win, GLFW_KEY_DOWN) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_TEXT_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_TEXT_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_SCROLL_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_SCROLL_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_SCROLL_DOWN, glfwGetKey(win, GLFW_KEY_PAGE_DOWN) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_SCROLL_UP, glfwGetKey(win, GLFW_KEY_PAGE_UP) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_SHIFT, glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS|| - glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS); - - if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS || - glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS) { - nk_input_key(ctx, NK_KEY_COPY, glfwGetKey(win, GLFW_KEY_C) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_PASTE, glfwGetKey(win, GLFW_KEY_V) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_X) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_TEXT_UNDO, glfwGetKey(win, GLFW_KEY_Z) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_TEXT_REDO, glfwGetKey(win, GLFW_KEY_R) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_TEXT_LINE_START, glfwGetKey(win, GLFW_KEY_B) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_TEXT_LINE_END, glfwGetKey(win, GLFW_KEY_E) == GLFW_PRESS); - } else { - nk_input_key(ctx, NK_KEY_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_COPY, 0); - nk_input_key(ctx, NK_KEY_PASTE, 0); - nk_input_key(ctx, NK_KEY_CUT, 0); - nk_input_key(ctx, NK_KEY_SHIFT, 0); - } - - glfwGetCursorPos(win, &x, &y); - nk_input_motion(ctx, (int)x, (int)y); - if (ctx->input.mouse.grabbed) { - glfwSetCursorPos(glfw.win, ctx->input.mouse.prev.x, ctx->input.mouse.prev.y); - ctx->input.mouse.pos.x = ctx->input.mouse.prev.x; - ctx->input.mouse.pos.y = ctx->input.mouse.prev.y; - } - - nk_input_button(ctx, NK_BUTTON_LEFT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS); - nk_input_button(ctx, NK_BUTTON_MIDDLE, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS); - nk_input_button(ctx, NK_BUTTON_RIGHT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS); - nk_input_scroll(ctx, glfw.scroll); - nk_input_end(&glfw.ctx); - glfw.text_len = 0; - glfw.scroll = 0; -} - -NK_API -void nk_glfw3_shutdown(void) -{ - struct nk_glfw_device *dev = &glfw.ogl; - nk_font_atlas_clear(&glfw.atlas); - nk_free(&glfw.ctx); - glDeleteTextures(1, &dev->font_tex); - nk_buffer_free(&dev->cmds); - memset(&glfw, 0, sizeof(glfw)); -} - -#endif diff --git a/deps/nuklear/demo/glfw_opengl3/main.c b/deps/nuklear/demo/glfw_opengl3/main.c deleted file mode 100644 index d74ee562..00000000 --- a/deps/nuklear/demo/glfw_opengl3/main.c +++ /dev/null @@ -1,180 +0,0 @@ -/* nuklear - v1.17 - public domain */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define NK_INCLUDE_FIXED_TYPES -#define NK_INCLUDE_STANDARD_IO -#define NK_INCLUDE_STANDARD_VARARGS -#define NK_INCLUDE_DEFAULT_ALLOCATOR -#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT -#define NK_INCLUDE_FONT_BAKING -#define NK_INCLUDE_DEFAULT_FONT -#define NK_IMPLEMENTATION -#define NK_GLFW_GL3_IMPLEMENTATION -#include "../../nuklear.h" -#include "nuklear_glfw_gl3.h" - -#define WINDOW_WIDTH 1200 -#define WINDOW_HEIGHT 800 - -#define MAX_VERTEX_BUFFER 512 * 1024 -#define MAX_ELEMENT_BUFFER 128 * 1024 - -#define UNUSED(a) (void)a -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) < (b) ? (b) : (a)) -#define LEN(a) (sizeof(a)/sizeof(a)[0]) - -/* =============================================================== - * - * EXAMPLE - * - * ===============================================================*/ -/* This are some code examples to provide a small overview of what can be - * done with this library. To try out an example uncomment the include - * and the corresponding function. */ -/*#include "../style.c"*/ -/*#include "../calculator.c"*/ -/*#include "../overview.c"*/ -/*#include "../node_editor.c"*/ - -/* =============================================================== - * - * DEMO - * - * ===============================================================*/ -static void error_callback(int e, const char *d) -{printf("Error %d: %s\n", e, d);} - -int main(void) -{ - /* Platform */ - static GLFWwindow *win; - int width = 0, height = 0; - struct nk_context *ctx; - struct nk_color background; - - /* GLFW */ - glfwSetErrorCallback(error_callback); - if (!glfwInit()) { - fprintf(stdout, "[GFLW] failed to init!\n"); - exit(1); - } - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); -#ifdef __APPLE__ - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); -#endif - win = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Demo", NULL, NULL); - glfwMakeContextCurrent(win); - glfwGetWindowSize(win, &width, &height); - - /* OpenGL */ - glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); - glewExperimental = 1; - if (glewInit() != GLEW_OK) { - fprintf(stderr, "Failed to setup GLEW\n"); - exit(1); - } - - ctx = nk_glfw3_init(win, NK_GLFW3_INSTALL_CALLBACKS); - /* Load Fonts: if none of these are loaded a default font will be used */ - /* Load Cursor: if you uncomment cursor loading please hide the cursor */ - {struct nk_font_atlas *atlas; - nk_glfw3_font_stash_begin(&atlas); - /*struct nk_font *droid = nk_font_atlas_add_from_file(atlas, "../../../extra_font/DroidSans.ttf", 14, 0);*/ - /*struct nk_font *roboto = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Roboto-Regular.ttf", 14, 0);*/ - /*struct nk_font *future = nk_font_atlas_add_from_file(atlas, "../../../extra_font/kenvector_future_thin.ttf", 13, 0);*/ - /*struct nk_font *clean = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyClean.ttf", 12, 0);*/ - /*struct nk_font *tiny = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyTiny.ttf", 10, 0);*/ - /*struct nk_font *cousine = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Cousine-Regular.ttf", 13, 0);*/ - nk_glfw3_font_stash_end(); - /*nk_style_load_all_cursors(ctx, atlas->cursors);*/ - /*nk_style_set_font(ctx, &droid->handle);*/} - - /* style.c */ - /*set_style(ctx, THEME_WHITE);*/ - /*set_style(ctx, THEME_RED);*/ - /*set_style(ctx, THEME_BLUE);*/ - /*set_style(ctx, THEME_DARK);*/ - - background = nk_rgb(28,48,62); - while (!glfwWindowShouldClose(win)) - { - /* Input */ - glfwPollEvents(); - nk_glfw3_new_frame(); - - /* GUI */ - if (nk_begin(ctx, "Demo", nk_rect(50, 50, 230, 250), - NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE| - NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE)) - { - enum {EASY, HARD}; - static int op = EASY; - static int property = 20; - nk_layout_row_static(ctx, 30, 80, 1); - if (nk_button_label(ctx, "button")) - fprintf(stdout, "button pressed\n"); - - nk_layout_row_dynamic(ctx, 30, 2); - if (nk_option_label(ctx, "easy", op == EASY)) op = EASY; - if (nk_option_label(ctx, "hard", op == HARD)) op = HARD; - - nk_layout_row_dynamic(ctx, 25, 1); - nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1); - - nk_layout_row_dynamic(ctx, 20, 1); - nk_label(ctx, "background:", NK_TEXT_LEFT); - nk_layout_row_dynamic(ctx, 25, 1); - if (nk_combo_begin_color(ctx, background, nk_vec2(nk_widget_width(ctx),400))) { - nk_layout_row_dynamic(ctx, 120, 1); - background = nk_color_picker(ctx, background, NK_RGBA); - nk_layout_row_dynamic(ctx, 25, 1); - background.r = (nk_byte)nk_propertyi(ctx, "#R:", 0, background.r, 255, 1,1); - background.g = (nk_byte)nk_propertyi(ctx, "#G:", 0, background.g, 255, 1,1); - background.b = (nk_byte)nk_propertyi(ctx, "#B:", 0, background.b, 255, 1,1); - background.a = (nk_byte)nk_propertyi(ctx, "#A:", 0, background.a, 255, 1,1); - nk_combo_end(ctx); - } - } - nk_end(ctx); - - /* -------------- EXAMPLES ---------------- */ - /*calculator(ctx);*/ - /*overview(ctx);*/ - /*node_editor(ctx);*/ - /* ----------------------------------------- */ - - /* Draw */ - {float bg[4]; - nk_color_fv(bg, background); - glfwGetWindowSize(win, &width, &height); - glViewport(0, 0, width, height); - glClear(GL_COLOR_BUFFER_BIT); - glClearColor(bg[0], bg[1], bg[2], bg[3]); - /* IMPORTANT: `nk_glfw_render` modifies some global OpenGL state - * with blending, scissor, face culling, depth test and viewport and - * defaults everything back into a default state. - * Make sure to either a.) save and restore or b.) reset your own state after - * rendering the UI. */ - nk_glfw3_render(NK_ANTI_ALIASING_ON, MAX_VERTEX_BUFFER, MAX_ELEMENT_BUFFER); - glfwSwapBuffers(win);} - } - nk_glfw3_shutdown(); - glfwTerminate(); - return 0; -} - diff --git a/deps/nuklear/demo/glfw_opengl3/nuklear_glfw_gl3.h b/deps/nuklear/demo/glfw_opengl3/nuklear_glfw_gl3.h deleted file mode 100644 index d0eea353..00000000 --- a/deps/nuklear/demo/glfw_opengl3/nuklear_glfw_gl3.h +++ /dev/null @@ -1,456 +0,0 @@ -/* - * Nuklear - v1.17 - public domain - * no warrenty implied; use at your own risk. - * authored from 2015-2016 by Micha Mettke - */ -/* - * ============================================================== - * - * API - * - * =============================================================== - */ -#ifndef NK_GLFW_GL3_H_ -#define NK_GLFW_GL3_H_ - -#include - -enum nk_glfw_init_state{ - NK_GLFW3_DEFAULT=0, - NK_GLFW3_INSTALL_CALLBACKS -}; - -NK_API struct nk_context* nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state); -NK_API void nk_glfw3_shutdown(void); -NK_API void nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas); -NK_API void nk_glfw3_font_stash_end(void); -NK_API void nk_glfw3_new_frame(void); -NK_API void nk_glfw3_render(enum nk_anti_aliasing, int max_vertex_buffer, int max_element_buffer); - -NK_API void nk_glfw3_device_destroy(void); -NK_API void nk_glfw3_device_create(void); - -NK_API void nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint); -NK_API void nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff); - -#endif -/* - * ============================================================== - * - * IMPLEMENTATION - * - * =============================================================== - */ -#ifdef NK_GLFW_GL3_IMPLEMENTATION - -#ifndef NK_GLFW_TEXT_MAX -#define NK_GLFW_TEXT_MAX 256 -#endif - -struct nk_glfw_device { - struct nk_buffer cmds; - struct nk_draw_null_texture null; - GLuint vbo, vao, ebo; - GLuint prog; - GLuint vert_shdr; - GLuint frag_shdr; - GLint attrib_pos; - GLint attrib_uv; - GLint attrib_col; - GLint uniform_tex; - GLint uniform_proj; - GLuint font_tex; -}; - -struct nk_glfw_vertex { - float position[2]; - float uv[2]; - nk_byte col[4]; -}; - -static struct nk_glfw { - GLFWwindow *win; - int width, height; - int display_width, display_height; - struct nk_glfw_device ogl; - struct nk_context ctx; - struct nk_font_atlas atlas; - struct nk_vec2 fb_scale; - unsigned int text[NK_GLFW_TEXT_MAX]; - int text_len; - float scroll; -} glfw; - -#ifdef __APPLE__ - #define NK_SHADER_VERSION "#version 150\n" -#else - #define NK_SHADER_VERSION "#version 300 es\n" -#endif - -NK_API void -nk_glfw3_device_create(void) -{ - GLint status; - static const GLchar *vertex_shader = - NK_SHADER_VERSION - "uniform mat4 ProjMtx;\n" - "in vec2 Position;\n" - "in vec2 TexCoord;\n" - "in vec4 Color;\n" - "out vec2 Frag_UV;\n" - "out vec4 Frag_Color;\n" - "void main() {\n" - " Frag_UV = TexCoord;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy, 0, 1);\n" - "}\n"; - static const GLchar *fragment_shader = - NK_SHADER_VERSION - "precision mediump float;\n" - "uniform sampler2D Texture;\n" - "in vec2 Frag_UV;\n" - "in vec4 Frag_Color;\n" - "out vec4 Out_Color;\n" - "void main(){\n" - " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" - "}\n"; - - struct nk_glfw_device *dev = &glfw.ogl; - nk_buffer_init_default(&dev->cmds); - dev->prog = glCreateProgram(); - dev->vert_shdr = glCreateShader(GL_VERTEX_SHADER); - dev->frag_shdr = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(dev->vert_shdr, 1, &vertex_shader, 0); - glShaderSource(dev->frag_shdr, 1, &fragment_shader, 0); - glCompileShader(dev->vert_shdr); - glCompileShader(dev->frag_shdr); - glGetShaderiv(dev->vert_shdr, GL_COMPILE_STATUS, &status); - assert(status == GL_TRUE); - glGetShaderiv(dev->frag_shdr, GL_COMPILE_STATUS, &status); - assert(status == GL_TRUE); - glAttachShader(dev->prog, dev->vert_shdr); - glAttachShader(dev->prog, dev->frag_shdr); - glLinkProgram(dev->prog); - glGetProgramiv(dev->prog, GL_LINK_STATUS, &status); - assert(status == GL_TRUE); - - dev->uniform_tex = glGetUniformLocation(dev->prog, "Texture"); - dev->uniform_proj = glGetUniformLocation(dev->prog, "ProjMtx"); - dev->attrib_pos = glGetAttribLocation(dev->prog, "Position"); - dev->attrib_uv = glGetAttribLocation(dev->prog, "TexCoord"); - dev->attrib_col = glGetAttribLocation(dev->prog, "Color"); - - { - /* buffer setup */ - GLsizei vs = sizeof(struct nk_glfw_vertex); - size_t vp = offsetof(struct nk_glfw_vertex, position); - size_t vt = offsetof(struct nk_glfw_vertex, uv); - size_t vc = offsetof(struct nk_glfw_vertex, col); - - glGenBuffers(1, &dev->vbo); - glGenBuffers(1, &dev->ebo); - glGenVertexArrays(1, &dev->vao); - - glBindVertexArray(dev->vao); - glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); - - glEnableVertexAttribArray((GLuint)dev->attrib_pos); - glEnableVertexAttribArray((GLuint)dev->attrib_uv); - glEnableVertexAttribArray((GLuint)dev->attrib_col); - - glVertexAttribPointer((GLuint)dev->attrib_pos, 2, GL_FLOAT, GL_FALSE, vs, (void*)vp); - glVertexAttribPointer((GLuint)dev->attrib_uv, 2, GL_FLOAT, GL_FALSE, vs, (void*)vt); - glVertexAttribPointer((GLuint)dev->attrib_col, 4, GL_UNSIGNED_BYTE, GL_TRUE, vs, (void*)vc); - } - - glBindTexture(GL_TEXTURE_2D, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindVertexArray(0); -} - -NK_INTERN void -nk_glfw3_device_upload_atlas(const void *image, int width, int height) -{ - struct nk_glfw_device *dev = &glfw.ogl; - glGenTextures(1, &dev->font_tex); - glBindTexture(GL_TEXTURE_2D, dev->font_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, image); -} - -NK_API void -nk_glfw3_device_destroy(void) -{ - struct nk_glfw_device *dev = &glfw.ogl; - glDetachShader(dev->prog, dev->vert_shdr); - glDetachShader(dev->prog, dev->frag_shdr); - glDeleteShader(dev->vert_shdr); - glDeleteShader(dev->frag_shdr); - glDeleteProgram(dev->prog); - glDeleteTextures(1, &dev->font_tex); - glDeleteBuffers(1, &dev->vbo); - glDeleteBuffers(1, &dev->ebo); - nk_buffer_free(&dev->cmds); -} - -NK_API void -nk_glfw3_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_buffer) -{ - struct nk_glfw_device *dev = &glfw.ogl; - GLfloat ortho[4][4] = { - {2.0f, 0.0f, 0.0f, 0.0f}, - {0.0f,-2.0f, 0.0f, 0.0f}, - {0.0f, 0.0f,-1.0f, 0.0f}, - {-1.0f,1.0f, 0.0f, 1.0f}, - }; - ortho[0][0] /= (GLfloat)glfw.width; - ortho[1][1] /= (GLfloat)glfw.height; - - /* setup global state */ - glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glActiveTexture(GL_TEXTURE0); - - /* setup program */ - glUseProgram(dev->prog); - glUniform1i(dev->uniform_tex, 0); - glUniformMatrix4fv(dev->uniform_proj, 1, GL_FALSE, &ortho[0][0]); - glViewport(0,0,(GLsizei)glfw.display_width,(GLsizei)glfw.display_height); - { - /* convert from command queue into draw list and draw to screen */ - const struct nk_draw_command *cmd; - void *vertices, *elements; - const nk_draw_index *offset = NULL; - - /* allocate vertex and element buffer */ - glBindVertexArray(dev->vao); - glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); - - glBufferData(GL_ARRAY_BUFFER, max_vertex_buffer, NULL, GL_STREAM_DRAW); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, max_element_buffer, NULL, GL_STREAM_DRAW); - - /* load draw vertices & elements directly into vertex + element buffer */ - vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - elements = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); - { - /* fill convert configuration */ - struct nk_convert_config config; - static const struct nk_draw_vertex_layout_element vertex_layout[] = { - {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, position)}, - {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, uv)}, - {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_glfw_vertex, col)}, - {NK_VERTEX_LAYOUT_END} - }; - NK_MEMSET(&config, 0, sizeof(config)); - config.vertex_layout = vertex_layout; - config.vertex_size = sizeof(struct nk_glfw_vertex); - config.vertex_alignment = NK_ALIGNOF(struct nk_glfw_vertex); - config.null = dev->null; - config.circle_segment_count = 22; - config.curve_segment_count = 22; - config.arc_segment_count = 22; - config.global_alpha = 1.0f; - config.shape_AA = AA; - config.line_AA = AA; - - /* setup buffers to load vertices and elements */ - {struct nk_buffer vbuf, ebuf; - nk_buffer_init_fixed(&vbuf, vertices, (size_t)max_vertex_buffer); - nk_buffer_init_fixed(&ebuf, elements, (size_t)max_element_buffer); - nk_convert(&glfw.ctx, &dev->cmds, &vbuf, &ebuf, &config);} - } - glUnmapBuffer(GL_ARRAY_BUFFER); - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - - /* iterate over and execute each draw command */ - nk_draw_foreach(cmd, &glfw.ctx, &dev->cmds) - { - if (!cmd->elem_count) continue; - glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id); - glScissor( - (GLint)(cmd->clip_rect.x * glfw.fb_scale.x), - (GLint)((glfw.height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * glfw.fb_scale.y), - (GLint)(cmd->clip_rect.w * glfw.fb_scale.x), - (GLint)(cmd->clip_rect.h * glfw.fb_scale.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset); - offset += cmd->elem_count; - } - nk_clear(&glfw.ctx); - } - - /* default OpenGL state */ - glUseProgram(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindVertexArray(0); - glDisable(GL_BLEND); - glDisable(GL_SCISSOR_TEST); -} - -NK_API void -nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint) -{ - (void)win; - if (glfw.text_len < NK_GLFW_TEXT_MAX) - glfw.text[glfw.text_len++] = codepoint; -} - -NK_API void -nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff) -{ - (void)win; (void)xoff; - glfw.scroll += (float)yoff; -} - -NK_INTERN void -nk_glfw3_clipbard_paste(nk_handle usr, struct nk_text_edit *edit) -{ - const char *text = glfwGetClipboardString(glfw.win); - if (text) nk_textedit_paste(edit, text, nk_strlen(text)); - (void)usr; -} - -NK_INTERN void -nk_glfw3_clipbard_copy(nk_handle usr, const char *text, int len) -{ - char *str = 0; - (void)usr; - if (!len) return; - str = (char*)malloc((size_t)len+1); - if (!str) return; - memcpy(str, text, (size_t)len); - str[len] = '\0'; - glfwSetClipboardString(glfw.win, str); - free(str); -} - -NK_API struct nk_context* -nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state init_state) -{ - glfw.win = win; - if (init_state == NK_GLFW3_INSTALL_CALLBACKS) { - glfwSetScrollCallback(win, nk_gflw3_scroll_callback); - glfwSetCharCallback(win, nk_glfw3_char_callback); - } - - nk_init_default(&glfw.ctx, 0); - glfw.ctx.clip.copy = nk_glfw3_clipbard_copy; - glfw.ctx.clip.paste = nk_glfw3_clipbard_paste; - glfw.ctx.clip.userdata = nk_handle_ptr(0); - nk_glfw3_device_create(); - return &glfw.ctx; -} - -NK_API void -nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas) -{ - nk_font_atlas_init_default(&glfw.atlas); - nk_font_atlas_begin(&glfw.atlas); - *atlas = &glfw.atlas; -} - -NK_API void -nk_glfw3_font_stash_end(void) -{ - const void *image; int w, h; - image = nk_font_atlas_bake(&glfw.atlas, &w, &h, NK_FONT_ATLAS_RGBA32); - nk_glfw3_device_upload_atlas(image, w, h); - nk_font_atlas_end(&glfw.atlas, nk_handle_id((int)glfw.ogl.font_tex), &glfw.ogl.null); - if (glfw.atlas.default_font) - nk_style_set_font(&glfw.ctx, &glfw.atlas.default_font->handle); -} - -NK_API void -nk_glfw3_new_frame(void) -{ - int i; - double x, y; - struct nk_context *ctx = &glfw.ctx; - struct GLFWwindow *win = glfw.win; - - glfwGetWindowSize(win, &glfw.width, &glfw.height); - glfwGetFramebufferSize(win, &glfw.display_width, &glfw.display_height); - glfw.fb_scale.x = (float)glfw.display_width/(float)glfw.width; - glfw.fb_scale.y = (float)glfw.display_height/(float)glfw.height; - - nk_input_begin(ctx); - for (i = 0; i < glfw.text_len; ++i) - nk_input_unicode(ctx, glfw.text[i]); - - /* optional grabbing behavior */ - if (ctx->input.mouse.grab) - glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); - else if (ctx->input.mouse.ungrab) - glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_NORMAL); - - nk_input_key(ctx, NK_KEY_DEL, glfwGetKey(win, GLFW_KEY_DELETE) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_ENTER, glfwGetKey(win, GLFW_KEY_ENTER) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_TAB, glfwGetKey(win, GLFW_KEY_TAB) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_BACKSPACE, glfwGetKey(win, GLFW_KEY_BACKSPACE) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_UP, glfwGetKey(win, GLFW_KEY_UP) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_DOWN, glfwGetKey(win, GLFW_KEY_DOWN) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_TEXT_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_TEXT_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_SCROLL_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_SCROLL_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_SCROLL_DOWN, glfwGetKey(win, GLFW_KEY_PAGE_DOWN) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_SCROLL_UP, glfwGetKey(win, GLFW_KEY_PAGE_UP) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_SHIFT, glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS|| - glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS); - - if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS || - glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS) { - nk_input_key(ctx, NK_KEY_COPY, glfwGetKey(win, GLFW_KEY_C) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_PASTE, glfwGetKey(win, GLFW_KEY_V) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_X) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_TEXT_UNDO, glfwGetKey(win, GLFW_KEY_Z) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_TEXT_REDO, glfwGetKey(win, GLFW_KEY_R) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_TEXT_LINE_START, glfwGetKey(win, GLFW_KEY_B) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_TEXT_LINE_END, glfwGetKey(win, GLFW_KEY_E) == GLFW_PRESS); - } else { - nk_input_key(ctx, NK_KEY_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_COPY, 0); - nk_input_key(ctx, NK_KEY_PASTE, 0); - nk_input_key(ctx, NK_KEY_CUT, 0); - nk_input_key(ctx, NK_KEY_SHIFT, 0); - } - - glfwGetCursorPos(win, &x, &y); - nk_input_motion(ctx, (int)x, (int)y); - if (ctx->input.mouse.grabbed) { - glfwSetCursorPos(glfw.win, ctx->input.mouse.prev.x, ctx->input.mouse.prev.y); - ctx->input.mouse.pos.x = ctx->input.mouse.prev.x; - ctx->input.mouse.pos.y = ctx->input.mouse.prev.y; - } - - nk_input_button(ctx, NK_BUTTON_LEFT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS); - nk_input_button(ctx, NK_BUTTON_MIDDLE, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS); - nk_input_button(ctx, NK_BUTTON_RIGHT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS); - nk_input_scroll(ctx, glfw.scroll); - nk_input_end(&glfw.ctx); - glfw.text_len = 0; - glfw.scroll = 0; -} - -NK_API -void nk_glfw3_shutdown(void) -{ - nk_font_atlas_clear(&glfw.atlas); - nk_free(&glfw.ctx); - nk_glfw3_device_destroy(); - memset(&glfw, 0, sizeof(glfw)); -} - -#endif diff --git a/deps/nuklear/demo/node_editor.c b/deps/nuklear/demo/node_editor.c deleted file mode 100644 index 6949f590..00000000 --- a/deps/nuklear/demo/node_editor.c +++ /dev/null @@ -1,343 +0,0 @@ -/* nuklear - v1.00 - public domain */ -/* This is a simple node editor just to show a simple implementation and that - * it is possible to achieve it with this library. While all nodes inside this - * example use a simple color modifier as content you could change them - * to have your custom content depending on the node time. - * Biggest difference to most usual implementation is that this example does - * not have connectors on the right position of the property that it links. - * This is mainly done out of laziness and could be implemented as well but - * requires calculating the position of all rows and add connectors. - * In addition adding and removing nodes is quite limited at the - * moment since it is based on a simple fixed array. If this is to be converted - * into something more serious it is probably best to extend it.*/ -struct node { - int ID; - char name[32]; - struct nk_rect bounds; - float value; - struct nk_color color; - int input_count; - int output_count; - struct node *next; - struct node *prev; -}; - -struct node_link { - int input_id; - int input_slot; - int output_id; - int output_slot; - struct nk_vec2 in; - struct nk_vec2 out; -}; - -struct node_linking { - int active; - struct node *node; - int input_id; - int input_slot; -}; - -struct node_editor { - int initialized; - struct node node_buf[32]; - struct node_link links[64]; - struct node *begin; - struct node *end; - int node_count; - int link_count; - struct nk_rect bounds; - struct node *selected; - int show_grid; - struct nk_vec2 scrolling; - struct node_linking linking; -}; -static struct node_editor nodeEditor; - -static void -node_editor_push(struct node_editor *editor, struct node *node) -{ - if (!editor->begin) { - node->next = NULL; - node->prev = NULL; - editor->begin = node; - editor->end = node; - } else { - node->prev = editor->end; - if (editor->end) - editor->end->next = node; - node->next = NULL; - editor->end = node; - } -} - -static void -node_editor_pop(struct node_editor *editor, struct node *node) -{ - if (node->next) - node->next->prev = node->prev; - if (node->prev) - node->prev->next = node->next; - if (editor->end == node) - editor->end = node->prev; - if (editor->begin == node) - editor->begin = node->next; - node->next = NULL; - node->prev = NULL; -} - -static struct node* -node_editor_find(struct node_editor *editor, int ID) -{ - struct node *iter = editor->begin; - while (iter) { - if (iter->ID == ID) - return iter; - iter = iter->next; - } - return NULL; -} - -static void -node_editor_add(struct node_editor *editor, const char *name, struct nk_rect bounds, - struct nk_color col, int in_count, int out_count) -{ - static int IDs = 0; - struct node *node; - assert((nk_size)editor->node_count < LEN(editor->node_buf)); - node = &editor->node_buf[editor->node_count++]; - node->ID = IDs++; - node->value = 0; - node->color = nk_rgb(255, 0, 0); - node->input_count = in_count; - node->output_count = out_count; - node->color = col; - node->bounds = bounds; - strcpy(node->name, name); - node_editor_push(editor, node); -} - -static void -node_editor_link(struct node_editor *editor, int in_id, int in_slot, - int out_id, int out_slot) -{ - struct node_link *link; - assert((nk_size)editor->link_count < LEN(editor->links)); - link = &editor->links[editor->link_count++]; - link->input_id = in_id; - link->input_slot = in_slot; - link->output_id = out_id; - link->output_slot = out_slot; -} - -static void -node_editor_init(struct node_editor *editor) -{ - memset(editor, 0, sizeof(*editor)); - editor->begin = NULL; - editor->end = NULL; - node_editor_add(editor, "Source", nk_rect(40, 10, 180, 220), nk_rgb(255, 0, 0), 0, 1); - node_editor_add(editor, "Source", nk_rect(40, 260, 180, 220), nk_rgb(0, 255, 0), 0, 1); - node_editor_add(editor, "Combine", nk_rect(400, 100, 180, 220), nk_rgb(0,0,255), 2, 2); - node_editor_link(editor, 0, 0, 2, 0); - node_editor_link(editor, 1, 0, 2, 1); - editor->show_grid = nk_true; -} - -static int -node_editor(struct nk_context *ctx) -{ - int n = 0; - struct nk_rect total_space; - const struct nk_input *in = &ctx->input; - struct nk_command_buffer *canvas; - struct node *updated = 0; - struct node_editor *nodedit = &nodeEditor; - - if (!nodeEditor.initialized) { - node_editor_init(&nodeEditor); - nodeEditor.initialized = 1; - } - - if (nk_begin(ctx, "NodeEdit", nk_rect(0, 0, 800, 600), - NK_WINDOW_BORDER|NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_MOVABLE|NK_WINDOW_CLOSABLE)) - { - /* allocate complete window space */ - canvas = nk_window_get_canvas(ctx); - total_space = nk_window_get_content_region(ctx); - nk_layout_space_begin(ctx, NK_STATIC, total_space.h, nodedit->node_count); - { - struct node *it = nodedit->begin; - struct nk_rect size = nk_layout_space_bounds(ctx); - - if (nodedit->show_grid) { - /* display grid */ - float x, y; - const float grid_size = 32.0f; - const struct nk_color grid_color = nk_rgb(50, 50, 50); - for (x = (float)fmod(size.x - nodedit->scrolling.x, grid_size); x < size.w; x += grid_size) - nk_stroke_line(canvas, x+size.x, size.y, x+size.x, size.y+size.h, 1.0f, grid_color); - for (y = (float)fmod(size.y - nodedit->scrolling.y, grid_size); y < size.h; y += grid_size) - nk_stroke_line(canvas, size.x, y+size.y, size.x+size.w, y+size.y, 1.0f, grid_color); - } - - /* execute each node as a movable group */ - struct nk_panel *node; - while (it) { - /* calculate scrolled node window position and size */ - nk_layout_space_push(ctx, nk_rect(it->bounds.x - nodedit->scrolling.x, - it->bounds.y - nodedit->scrolling.y, it->bounds.w, it->bounds.h)); - - /* execute node window */ - if (nk_group_begin(ctx, it->name, NK_WINDOW_MOVABLE|NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER|NK_WINDOW_TITLE)) - { - /* always have last selected node on top */ - - node = nk_window_get_panel(ctx); - if (nk_input_mouse_clicked(in, NK_BUTTON_LEFT, node->bounds) && - (!(it->prev && nk_input_mouse_clicked(in, NK_BUTTON_LEFT, - nk_layout_space_rect_to_screen(ctx, node->bounds)))) && - nodedit->end != it) - { - updated = it; - } - - /* ================= NODE CONTENT =====================*/ - nk_layout_row_dynamic(ctx, 25, 1); - nk_button_color(ctx, it->color); - it->color.r = (nk_byte)nk_propertyi(ctx, "#R:", 0, it->color.r, 255, 1,1); - it->color.g = (nk_byte)nk_propertyi(ctx, "#G:", 0, it->color.g, 255, 1,1); - it->color.b = (nk_byte)nk_propertyi(ctx, "#B:", 0, it->color.b, 255, 1,1); - it->color.a = (nk_byte)nk_propertyi(ctx, "#A:", 0, it->color.a, 255, 1,1); - /* ====================================================*/ - nk_group_end(ctx); - } - { - /* node connector and linking */ - float space; - struct nk_rect bounds; - bounds = nk_layout_space_rect_to_local(ctx, node->bounds); - bounds.x += nodedit->scrolling.x; - bounds.y += nodedit->scrolling.y; - it->bounds = bounds; - - /* output connector */ - space = node->bounds.h / (float)((it->output_count) + 1); - for (n = 0; n < it->output_count; ++n) { - struct nk_rect circle; - circle.x = node->bounds.x + node->bounds.w-4; - circle.y = node->bounds.y + space * (float)(n+1); - circle.w = 8; circle.h = 8; - nk_fill_circle(canvas, circle, nk_rgb(100, 100, 100)); - - /* start linking process */ - if (nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, circle, nk_true)) { - nodedit->linking.active = nk_true; - nodedit->linking.node = it; - nodedit->linking.input_id = it->ID; - nodedit->linking.input_slot = n; - } - - /* draw curve from linked node slot to mouse position */ - if (nodedit->linking.active && nodedit->linking.node == it && - nodedit->linking.input_slot == n) { - struct nk_vec2 l0 = nk_vec2(circle.x + 3, circle.y + 3); - struct nk_vec2 l1 = in->mouse.pos; - nk_stroke_curve(canvas, l0.x, l0.y, l0.x + 50.0f, l0.y, - l1.x - 50.0f, l1.y, l1.x, l1.y, 1.0f, nk_rgb(100, 100, 100)); - } - } - - /* input connector */ - space = node->bounds.h / (float)((it->input_count) + 1); - for (n = 0; n < it->input_count; ++n) { - struct nk_rect circle; - circle.x = node->bounds.x-4; - circle.y = node->bounds.y + space * (float)(n+1); - circle.w = 8; circle.h = 8; - nk_fill_circle(canvas, circle, nk_rgb(100, 100, 100)); - if (nk_input_is_mouse_released(in, NK_BUTTON_LEFT) && - nk_input_is_mouse_hovering_rect(in, circle) && - nodedit->linking.active && nodedit->linking.node != it) { - nodedit->linking.active = nk_false; - node_editor_link(nodedit, nodedit->linking.input_id, - nodedit->linking.input_slot, it->ID, n); - } - } - } - it = it->next; - } - - /* reset linking connection */ - if (nodedit->linking.active && nk_input_is_mouse_released(in, NK_BUTTON_LEFT)) { - nodedit->linking.active = nk_false; - nodedit->linking.node = NULL; - fprintf(stdout, "linking failed\n"); - } - - /* draw each link */ - for (n = 0; n < nodedit->link_count; ++n) { - struct node_link *link = &nodedit->links[n]; - struct node *ni = node_editor_find(nodedit, link->input_id); - struct node *no = node_editor_find(nodedit, link->output_id); - float spacei = node->bounds.h / (float)((ni->output_count) + 1); - float spaceo = node->bounds.h / (float)((no->input_count) + 1); - struct nk_vec2 l0 = nk_layout_space_to_screen(ctx, - nk_vec2(ni->bounds.x + ni->bounds.w, 3.0f + ni->bounds.y + spacei * (float)(link->input_slot+1))); - struct nk_vec2 l1 = nk_layout_space_to_screen(ctx, - nk_vec2(no->bounds.x, 3.0f + no->bounds.y + spaceo * (float)(link->output_slot+1))); - - l0.x -= nodedit->scrolling.x; - l0.y -= nodedit->scrolling.y; - l1.x -= nodedit->scrolling.x; - l1.y -= nodedit->scrolling.y; - nk_stroke_curve(canvas, l0.x, l0.y, l0.x + 50.0f, l0.y, - l1.x - 50.0f, l1.y, l1.x, l1.y, 1.0f, nk_rgb(100, 100, 100)); - } - - if (updated) { - /* reshuffle nodes to have least recently selected node on top */ - node_editor_pop(nodedit, updated); - node_editor_push(nodedit, updated); - } - - /* node selection */ - if (nk_input_mouse_clicked(in, NK_BUTTON_LEFT, nk_layout_space_bounds(ctx))) { - it = nodedit->begin; - nodedit->selected = NULL; - nodedit->bounds = nk_rect(in->mouse.pos.x, in->mouse.pos.y, 100, 200); - while (it) { - struct nk_rect b = nk_layout_space_rect_to_screen(ctx, it->bounds); - b.x -= nodedit->scrolling.x; - b.y -= nodedit->scrolling.y; - if (nk_input_is_mouse_hovering_rect(in, b)) - nodedit->selected = it; - it = it->next; - } - } - - /* contextual menu */ - if (nk_contextual_begin(ctx, 0, nk_vec2(100, 220), nk_window_get_bounds(ctx))) { - const char *grid_option[] = {"Show Grid", "Hide Grid"}; - nk_layout_row_dynamic(ctx, 25, 1); - if (nk_contextual_item_label(ctx, "New", NK_TEXT_CENTERED)) - node_editor_add(nodedit, "New", nk_rect(400, 260, 180, 220), - nk_rgb(255, 255, 255), 1, 2); - if (nk_contextual_item_label(ctx, grid_option[nodedit->show_grid],NK_TEXT_CENTERED)) - nodedit->show_grid = !nodedit->show_grid; - nk_contextual_end(ctx); - } - } - nk_layout_space_end(ctx); - - /* window content scrolling */ - if (nk_input_is_mouse_hovering_rect(in, nk_window_get_bounds(ctx)) && - nk_input_is_mouse_down(in, NK_BUTTON_MIDDLE)) { - nodedit->scrolling.x += in->mouse.delta.x; - nodedit->scrolling.y += in->mouse.delta.y; - } - } - nk_end(ctx); - return !nk_window_is_closed(ctx, "NodeEdit"); -} - diff --git a/deps/nuklear/demo/overview.c b/deps/nuklear/demo/overview.c deleted file mode 100644 index 7f2c4853..00000000 --- a/deps/nuklear/demo/overview.c +++ /dev/null @@ -1,1188 +0,0 @@ - -static int -overview(struct nk_context *ctx) -{ - /* window flags */ - static int show_menu = nk_true; - static int titlebar = nk_true; - static int border = nk_true; - static int resize = nk_true; - static int movable = nk_true; - static int no_scrollbar = nk_false; - static nk_flags window_flags = 0; - static int minimizable = nk_true; - - /* popups */ - static enum nk_style_header_align header_align = NK_HEADER_RIGHT; - static int show_app_about = nk_false; - - /* window flags */ - window_flags = 0; - ctx->style.window.header.align = header_align; - if (border) window_flags |= NK_WINDOW_BORDER; - if (resize) window_flags |= NK_WINDOW_SCALABLE; - if (movable) window_flags |= NK_WINDOW_MOVABLE; - if (no_scrollbar) window_flags |= NK_WINDOW_NO_SCROLLBAR; - if (minimizable) window_flags |= NK_WINDOW_MINIMIZABLE; - - if (nk_begin(ctx, "Overview", nk_rect(10, 10, 400, 600), window_flags)) - { - if (show_menu) - { - /* menubar */ - enum menu_states {MENU_DEFAULT, MENU_WINDOWS}; - static nk_size mprog = 60; - static int mslider = 10; - static int mcheck = nk_true; - - nk_menubar_begin(ctx); - nk_layout_row_begin(ctx, NK_STATIC, 25, 4); - nk_layout_row_push(ctx, 45); - if (nk_menu_begin_label(ctx, "MENU", NK_TEXT_LEFT, nk_vec2(120, 200))) - { - static size_t prog = 40; - static int slider = 10; - static int check = nk_true; - nk_layout_row_dynamic(ctx, 25, 1); - if (nk_menu_item_label(ctx, "Hide", NK_TEXT_LEFT)) - show_menu = nk_false; - if (nk_menu_item_label(ctx, "About", NK_TEXT_LEFT)) - show_app_about = nk_true; - nk_progress(ctx, &prog, 100, NK_MODIFIABLE); - nk_slider_int(ctx, 0, &slider, 16, 1); - nk_checkbox_label(ctx, "check", &check); - nk_menu_end(ctx); - } - nk_layout_row_push(ctx, 70); - nk_progress(ctx, &mprog, 100, NK_MODIFIABLE); - nk_slider_int(ctx, 0, &mslider, 16, 1); - nk_checkbox_label(ctx, "check", &mcheck); - nk_menubar_end(ctx); - } - - if (show_app_about) - { - /* about popup */ - static struct nk_rect s = {20, 100, 300, 190}; - if (nk_popup_begin(ctx, NK_POPUP_STATIC, "About", NK_WINDOW_CLOSABLE, s)) - { - nk_layout_row_dynamic(ctx, 20, 1); - nk_label(ctx, "Nuklear", NK_TEXT_LEFT); - nk_label(ctx, "By Micha Mettke", NK_TEXT_LEFT); - nk_label(ctx, "nuklear is licensed under the public domain License.", NK_TEXT_LEFT); - nk_popup_end(ctx); - } else show_app_about = nk_false; - } - - /* window flags */ - if (nk_tree_push(ctx, NK_TREE_TAB, "Window", NK_MINIMIZED)) { - nk_layout_row_dynamic(ctx, 30, 2); - nk_checkbox_label(ctx, "Titlebar", &titlebar); - nk_checkbox_label(ctx, "Menu", &show_menu); - nk_checkbox_label(ctx, "Border", &border); - nk_checkbox_label(ctx, "Resizable", &resize); - nk_checkbox_label(ctx, "Movable", &movable); - nk_checkbox_label(ctx, "No Scrollbar", &no_scrollbar); - nk_checkbox_label(ctx, "Minimizable", &minimizable); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Widgets", NK_MINIMIZED)) - { - enum options {A,B,C}; - static int checkbox; - static int option; - if (nk_tree_push(ctx, NK_TREE_NODE, "Text", NK_MINIMIZED)) - { - /* Text Widgets */ - nk_layout_row_dynamic(ctx, 20, 1); - nk_label(ctx, "Label aligned left", NK_TEXT_LEFT); - nk_label(ctx, "Label aligned centered", NK_TEXT_CENTERED); - nk_label(ctx, "Label aligned right", NK_TEXT_RIGHT); - nk_label_colored(ctx, "Blue text", NK_TEXT_LEFT, nk_rgb(0,0,255)); - nk_label_colored(ctx, "Yellow text", NK_TEXT_LEFT, nk_rgb(255,255,0)); - nk_text(ctx, "Text without /0", 15, NK_TEXT_RIGHT); - - nk_layout_row_static(ctx, 100, 200, 1); - nk_label_wrap(ctx, "This is a very long line to hopefully get this text to be wrapped into multiple lines to show line wrapping"); - nk_layout_row_dynamic(ctx, 100, 1); - nk_label_wrap(ctx, "This is another long text to show dynamic window changes on multiline text"); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Button", NK_MINIMIZED)) - { - /* Buttons Widgets */ - nk_layout_row_static(ctx, 30, 100, 3); - if (nk_button_label(ctx, "Button")) - fprintf(stdout, "Button pressed!\n"); - nk_button_set_behavior(ctx, NK_BUTTON_REPEATER); - if (nk_button_label(ctx, "Repeater")) - fprintf(stdout, "Repeater is being pressed!\n"); - nk_button_set_behavior(ctx, NK_BUTTON_DEFAULT); - nk_button_color(ctx, nk_rgb(0,0,255)); - - nk_layout_row_static(ctx, 25, 25, 8); - nk_button_symbol(ctx, NK_SYMBOL_CIRCLE_SOLID); - nk_button_symbol(ctx, NK_SYMBOL_CIRCLE_OUTLINE); - nk_button_symbol(ctx, NK_SYMBOL_RECT_SOLID); - nk_button_symbol(ctx, NK_SYMBOL_RECT_OUTLINE); - nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_UP); - nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_DOWN); - nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_LEFT); - nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_RIGHT); - - nk_layout_row_static(ctx, 30, 100, 2); - nk_button_symbol_label(ctx, NK_SYMBOL_TRIANGLE_LEFT, "prev", NK_TEXT_RIGHT); - nk_button_symbol_label(ctx, NK_SYMBOL_TRIANGLE_RIGHT, "next", NK_TEXT_LEFT); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Basic", NK_MINIMIZED)) - { - /* Basic widgets */ - static int int_slider = 5; - static float float_slider = 2.5f; - static size_t prog_value = 40; - static float property_float = 2; - static int property_int = 10; - static int property_neg = 10; - - static float range_float_min = 0; - static float range_float_max = 100; - static float range_float_value = 50; - static int range_int_min = 0; - static int range_int_value = 2048; - static int range_int_max = 4096; - static const float ratio[] = {120, 150}; - - nk_layout_row_static(ctx, 30, 100, 1); - nk_checkbox_label(ctx, "Checkbox", &checkbox); - - nk_layout_row_static(ctx, 30, 80, 3); - option = nk_option_label(ctx, "optionA", option == A) ? A : option; - option = nk_option_label(ctx, "optionB", option == B) ? B : option; - option = nk_option_label(ctx, "optionC", option == C) ? C : option; - - - nk_layout_row(ctx, NK_STATIC, 30, 2, ratio); - nk_labelf(ctx, NK_TEXT_LEFT, "Slider int"); - nk_slider_int(ctx, 0, &int_slider, 10, 1); - - nk_label(ctx, "Slider float", NK_TEXT_LEFT); - nk_slider_float(ctx, 0, &float_slider, 5.0, 0.5f); - nk_labelf(ctx, NK_TEXT_LEFT, "Progressbar" , prog_value); - nk_progress(ctx, &prog_value, 100, NK_MODIFIABLE); - - nk_layout_row(ctx, NK_STATIC, 25, 2, ratio); - nk_label(ctx, "Property float:", NK_TEXT_LEFT); - nk_property_float(ctx, "Float:", 0, &property_float, 64.0f, 0.1f, 0.2f); - nk_label(ctx, "Property int:", NK_TEXT_LEFT); - nk_property_int(ctx, "Int:", 0, &property_int, 100.0f, 1, 1); - nk_label(ctx, "Property neg:", NK_TEXT_LEFT); - nk_property_int(ctx, "Neg:", -10, &property_neg, 10, 1, 1); - - nk_layout_row_dynamic(ctx, 25, 1); - nk_label(ctx, "Range:", NK_TEXT_LEFT); - nk_layout_row_dynamic(ctx, 25, 3); - nk_property_float(ctx, "#min:", 0, &range_float_min, range_float_max, 1.0f, 0.2f); - nk_property_float(ctx, "#float:", range_float_min, &range_float_value, range_float_max, 1.0f, 0.2f); - nk_property_float(ctx, "#max:", range_float_min, &range_float_max, 100, 1.0f, 0.2f); - - nk_property_int(ctx, "#min:", INT_MIN, &range_int_min, range_int_max, 1, 10); - nk_property_int(ctx, "#neg:", range_int_min, &range_int_value, range_int_max, 1, 10); - nk_property_int(ctx, "#max:", range_int_min, &range_int_max, INT_MAX, 1, 10); - - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Selectable", NK_MINIMIZED)) - { - if (nk_tree_push(ctx, NK_TREE_NODE, "List", NK_MINIMIZED)) - { - static int selected[4] = {nk_false, nk_false, nk_true, nk_false}; - nk_layout_row_static(ctx, 18, 100, 1); - nk_selectable_label(ctx, "Selectable", NK_TEXT_LEFT, &selected[0]); - nk_selectable_label(ctx, "Selectable", NK_TEXT_LEFT, &selected[1]); - nk_label(ctx, "Not Selectable", NK_TEXT_LEFT); - nk_selectable_label(ctx, "Selectable", NK_TEXT_LEFT, &selected[2]); - nk_selectable_label(ctx, "Selectable", NK_TEXT_LEFT, &selected[3]); - nk_tree_pop(ctx); - } - if (nk_tree_push(ctx, NK_TREE_NODE, "Grid", NK_MINIMIZED)) - { - int i; - static int selected[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1}; - nk_layout_row_static(ctx, 50, 50, 4); - for (i = 0; i < 16; ++i) { - if (nk_selectable_label(ctx, "Z", NK_TEXT_CENTERED, &selected[i])) { - int x = (i % 4), y = i / 4; - if (x > 0) selected[i - 1] ^= 1; - if (x < 3) selected[i + 1] ^= 1; - if (y > 0) selected[i - 4] ^= 1; - if (y < 3) selected[i + 4] ^= 1; - } - } - nk_tree_pop(ctx); - } - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Combo", NK_MINIMIZED)) - { - /* Combobox Widgets - * In this library comboboxes are not limited to being a popup - * list of selectable text. Instead it is a abstract concept of - * having something that is *selected* or displayed, a popup window - * which opens if something needs to be modified and the content - * of the popup which causes the *selected* or displayed value to - * change or if wanted close the combobox. - * - * While strange at first handling comboboxes in a abstract way - * solves the problem of overloaded window content. For example - * changing a color value requires 4 value modifier (slider, property,...) - * for RGBA then you need a label and ways to display the current color. - * If you want to go fancy you even add rgb and hsv ratio boxes. - * While fine for one color if you have a lot of them it because - * tedious to look at and quite wasteful in space. You could add - * a popup which modifies the color but this does not solve the - * fact that it still requires a lot of cluttered space to do. - * - * In these kind of instance abstract comboboxes are quite handy. All - * value modifiers are hidden inside the combobox popup and only - * the color is shown if not open. This combines the clarity of the - * popup with the ease of use of just using the space for modifiers. - * - * Other instances are for example time and especially date picker, - * which only show the currently activated time/data and hide the - * selection logic inside the combobox popup. - */ - static float chart_selection = 8.0f; - static int current_weapon = 0; - static int check_values[5]; - static float position[3]; - static struct nk_color combo_color = {130, 50, 50, 255}; - static struct nk_color combo_color2 = {130, 180, 50, 255}; - static size_t prog_a = 20, prog_b = 40, prog_c = 10, prog_d = 90; - static const char *weapons[] = {"Fist","Pistol","Shotgun","Plasma","BFG"}; - - char buffer[64]; - size_t sum = 0; - - /* default combobox */ - nk_layout_row_static(ctx, 25, 200, 1); - current_weapon = nk_combo(ctx, weapons, LEN(weapons), current_weapon, 25, nk_vec2(200,200)); - - /* slider color combobox */ - if (nk_combo_begin_color(ctx, combo_color, nk_vec2(200,200))) { - float ratios[] = {0.15f, 0.85f}; - nk_layout_row(ctx, NK_DYNAMIC, 30, 2, ratios); - nk_label(ctx, "R:", NK_TEXT_LEFT); - combo_color.r = (nk_byte)nk_slide_int(ctx, 0, combo_color.r, 255, 5); - nk_label(ctx, "G:", NK_TEXT_LEFT); - combo_color.g = (nk_byte)nk_slide_int(ctx, 0, combo_color.g, 255, 5); - nk_label(ctx, "B:", NK_TEXT_LEFT); - combo_color.b = (nk_byte)nk_slide_int(ctx, 0, combo_color.b, 255, 5); - nk_label(ctx, "A:", NK_TEXT_LEFT); - combo_color.a = (nk_byte)nk_slide_int(ctx, 0, combo_color.a , 255, 5); - nk_combo_end(ctx); - } - - /* complex color combobox */ - if (nk_combo_begin_color(ctx, combo_color2, nk_vec2(200,400))) { - enum color_mode {COL_RGB, COL_HSV}; - static int col_mode = COL_RGB; - #ifndef DEMO_DO_NOT_USE_COLOR_PICKER - nk_layout_row_dynamic(ctx, 120, 1); - combo_color2 = nk_color_picker(ctx, combo_color2, NK_RGBA); - #endif - - nk_layout_row_dynamic(ctx, 25, 2); - col_mode = nk_option_label(ctx, "RGB", col_mode == COL_RGB) ? COL_RGB : col_mode; - col_mode = nk_option_label(ctx, "HSV", col_mode == COL_HSV) ? COL_HSV : col_mode; - - nk_layout_row_dynamic(ctx, 25, 1); - if (col_mode == COL_RGB) { - combo_color2.r = (nk_byte)nk_propertyi(ctx, "#R:", 0, combo_color2.r, 255, 1,1); - combo_color2.g = (nk_byte)nk_propertyi(ctx, "#G:", 0, combo_color2.g, 255, 1,1); - combo_color2.b = (nk_byte)nk_propertyi(ctx, "#B:", 0, combo_color2.b, 255, 1,1); - combo_color2.a = (nk_byte)nk_propertyi(ctx, "#A:", 0, combo_color2.a, 255, 1,1); - } else { - nk_byte tmp[4]; - nk_color_hsva_bv(tmp, combo_color2); - tmp[0] = (nk_byte)nk_propertyi(ctx, "#H:", 0, tmp[0], 255, 1,1); - tmp[1] = (nk_byte)nk_propertyi(ctx, "#S:", 0, tmp[1], 255, 1,1); - tmp[2] = (nk_byte)nk_propertyi(ctx, "#V:", 0, tmp[2], 255, 1,1); - tmp[3] = (nk_byte)nk_propertyi(ctx, "#A:", 0, tmp[3], 255, 1,1); - combo_color2 = nk_hsva_bv(tmp); - } - nk_combo_end(ctx); - } - - /* progressbar combobox */ - sum = prog_a + prog_b + prog_c + prog_d; - sprintf(buffer, "%lu", sum); - if (nk_combo_begin_label(ctx, buffer, nk_vec2(200,200))) { - nk_layout_row_dynamic(ctx, 30, 1); - nk_progress(ctx, &prog_a, 100, NK_MODIFIABLE); - nk_progress(ctx, &prog_b, 100, NK_MODIFIABLE); - nk_progress(ctx, &prog_c, 100, NK_MODIFIABLE); - nk_progress(ctx, &prog_d, 100, NK_MODIFIABLE); - nk_combo_end(ctx); - } - - /* checkbox combobox */ - sum = (size_t)(check_values[0] + check_values[1] + check_values[2] + check_values[3] + check_values[4]); - sprintf(buffer, "%lu", sum); - if (nk_combo_begin_label(ctx, buffer, nk_vec2(200,200))) { - nk_layout_row_dynamic(ctx, 30, 1); - nk_checkbox_label(ctx, weapons[0], &check_values[0]); - nk_checkbox_label(ctx, weapons[1], &check_values[1]); - nk_checkbox_label(ctx, weapons[2], &check_values[2]); - nk_checkbox_label(ctx, weapons[3], &check_values[3]); - nk_combo_end(ctx); - } - - /* complex text combobox */ - sprintf(buffer, "%.2f, %.2f, %.2f", position[0], position[1],position[2]); - if (nk_combo_begin_label(ctx, buffer, nk_vec2(200,200))) { - nk_layout_row_dynamic(ctx, 25, 1); - nk_property_float(ctx, "#X:", -1024.0f, &position[0], 1024.0f, 1,0.5f); - nk_property_float(ctx, "#Y:", -1024.0f, &position[1], 1024.0f, 1,0.5f); - nk_property_float(ctx, "#Z:", -1024.0f, &position[2], 1024.0f, 1,0.5f); - nk_combo_end(ctx); - } - - /* chart combobox */ - sprintf(buffer, "%.1f", chart_selection); - if (nk_combo_begin_label(ctx, buffer, nk_vec2(200,250))) { - size_t i = 0; - static const float values[]={26.0f,13.0f,30.0f,15.0f,25.0f,10.0f,20.0f,40.0f, 12.0f, 8.0f, 22.0f, 28.0f, 5.0f}; - nk_layout_row_dynamic(ctx, 150, 1); - nk_chart_begin(ctx, NK_CHART_COLUMN, LEN(values), 0, 50); - for (i = 0; i < LEN(values); ++i) { - nk_flags res = nk_chart_push(ctx, values[i]); - if (res & NK_CHART_CLICKED) { - chart_selection = values[i]; - nk_combo_close(ctx); - } - } - nk_chart_end(ctx); - nk_combo_end(ctx); - } - - { - static int time_selected = 0; - static int date_selected = 0; - static struct tm sel_time; - static struct tm sel_date; - if (!time_selected || !date_selected) { - /* keep time and date updated if nothing is selected */ - time_t cur_time = time(0); - struct tm *n = localtime(&cur_time); - if (!time_selected) - memcpy(&sel_time, n, sizeof(struct tm)); - if (!date_selected) - memcpy(&sel_date, n, sizeof(struct tm)); - } - - /* time combobox */ - sprintf(buffer, "%02d:%02d:%02d", sel_time.tm_hour, sel_time.tm_min, sel_time.tm_sec); - if (nk_combo_begin_label(ctx, buffer, nk_vec2(200,250))) { - time_selected = 1; - nk_layout_row_dynamic(ctx, 25, 1); - sel_time.tm_sec = nk_propertyi(ctx, "#S:", 0, sel_time.tm_sec, 60, 1, 1); - sel_time.tm_min = nk_propertyi(ctx, "#M:", 0, sel_time.tm_min, 60, 1, 1); - sel_time.tm_hour = nk_propertyi(ctx, "#H:", 0, sel_time.tm_hour, 23, 1, 1); - nk_combo_end(ctx); - } - - /* date combobox */ - sprintf(buffer, "%02d-%02d-%02d", sel_date.tm_mday, sel_date.tm_mon+1, sel_date.tm_year+1900); - if (nk_combo_begin_label(ctx, buffer, nk_vec2(350,400))) - { - int i = 0; - const char *month[] = {"January", "February", "March", "Apil", "May", "June", "July", "August", "September", "Ocotober", "November", "December"}; - const char *week_days[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"}; - const int month_days[] = {31,28,31,30,31,30,31,31,30,31,30,31}; - int year = sel_date.tm_year+1900; - int leap_year = (!(year % 4) && ((year % 100))) || !(year % 400); - int days = (sel_date.tm_mon == 1) ? - month_days[sel_date.tm_mon] + leap_year: - month_days[sel_date.tm_mon]; - - /* header with month and year */ - date_selected = 1; - nk_layout_row_begin(ctx, NK_DYNAMIC, 20, 3); - nk_layout_row_push(ctx, 0.05f); - if (nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_LEFT)) { - if (sel_date.tm_mon == 0) { - sel_date.tm_mon = 11; - sel_date.tm_year = MAX(0, sel_date.tm_year-1); - } else sel_date.tm_mon--; - } - nk_layout_row_push(ctx, 0.9f); - sprintf(buffer, "%s %d", month[sel_date.tm_mon], year); - nk_label(ctx, buffer, NK_TEXT_CENTERED); - nk_layout_row_push(ctx, 0.05f); - if (nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_RIGHT)) { - if (sel_date.tm_mon == 11) { - sel_date.tm_mon = 0; - sel_date.tm_year++; - } else sel_date.tm_mon++; - } - nk_layout_row_end(ctx); - - /* good old week day formula (double because precision) */ - {int year_n = (sel_date.tm_mon < 2) ? year-1: year; - int y = year_n % 100; - int c = year_n / 100; - int y4 = (int)((float)y / 4); - int c4 = (int)((float)c / 4); - int m = (int)(2.6 * (double)(((sel_date.tm_mon + 10) % 12) + 1) - 0.2); - int week_day = (((1 + m + y + y4 + c4 - 2 * c) % 7) + 7) % 7; - - /* weekdays */ - nk_layout_row_dynamic(ctx, 35, 7); - for (i = 0; i < (int)LEN(week_days); ++i) - nk_label(ctx, week_days[i], NK_TEXT_CENTERED); - - /* days */ - if (week_day > 0) nk_spacing(ctx, week_day); - for (i = 1; i <= days; ++i) { - sprintf(buffer, "%d", i); - if (nk_button_label(ctx, buffer)) { - sel_date.tm_mday = i; - nk_combo_close(ctx); - } - }} - nk_combo_end(ctx); - } - } - - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Input", NK_MINIMIZED)) - { - static const float ratio[] = {120, 150}; - static char field_buffer[64]; - static char text[9][64]; - static int text_len[9]; - static char box_buffer[512]; - static int field_len; - static int box_len; - nk_flags active; - - nk_layout_row(ctx, NK_STATIC, 25, 2, ratio); - nk_label(ctx, "Default:", NK_TEXT_LEFT); - - nk_edit_string(ctx, NK_EDIT_SIMPLE, text[0], &text_len[0], 64, nk_filter_default); - nk_label(ctx, "Int:", NK_TEXT_LEFT); - nk_edit_string(ctx, NK_EDIT_SIMPLE, text[1], &text_len[1], 64, nk_filter_decimal); - nk_label(ctx, "Float:", NK_TEXT_LEFT); - nk_edit_string(ctx, NK_EDIT_SIMPLE, text[2], &text_len[2], 64, nk_filter_float); - nk_label(ctx, "Hex:", NK_TEXT_LEFT); - nk_edit_string(ctx, NK_EDIT_SIMPLE, text[4], &text_len[4], 64, nk_filter_hex); - nk_label(ctx, "Octal:", NK_TEXT_LEFT); - nk_edit_string(ctx, NK_EDIT_SIMPLE, text[5], &text_len[5], 64, nk_filter_oct); - nk_label(ctx, "Binary:", NK_TEXT_LEFT); - nk_edit_string(ctx, NK_EDIT_SIMPLE, text[6], &text_len[6], 64, nk_filter_binary); - - nk_label(ctx, "Password:", NK_TEXT_LEFT); - { - int i = 0; - int old_len = text_len[8]; - char buffer[64]; - for (i = 0; i < text_len[8]; ++i) buffer[i] = '*'; - nk_edit_string(ctx, NK_EDIT_FIELD, buffer, &text_len[8], 64, nk_filter_default); - if (old_len < text_len[8]) - memcpy(&text[8][old_len], &buffer[old_len], (nk_size)(text_len[8] - old_len)); - } - - nk_label(ctx, "Field:", NK_TEXT_LEFT); - nk_edit_string(ctx, NK_EDIT_FIELD, field_buffer, &field_len, 64, nk_filter_default); - - nk_label(ctx, "Box:", NK_TEXT_LEFT); - nk_layout_row_static(ctx, 180, 278, 1); - nk_edit_string(ctx, NK_EDIT_BOX, box_buffer, &box_len, 512, nk_filter_default); - - nk_layout_row(ctx, NK_STATIC, 25, 2, ratio); - active = nk_edit_string(ctx, NK_EDIT_FIELD|NK_EDIT_SIG_ENTER, text[7], &text_len[7], 64, nk_filter_ascii); - if (nk_button_label(ctx, "Submit") || - (active & NK_EDIT_COMMITED)) - { - text[7][text_len[7]] = '\n'; - text_len[7]++; - memcpy(&box_buffer[box_len], &text[7], (nk_size)text_len[7]); - box_len += text_len[7]; - text_len[7] = 0; - } - nk_layout_row_end(ctx); - nk_tree_pop(ctx); - } - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Chart", NK_MINIMIZED)) - { - /* Chart Widgets - * This library has two different rather simple charts. The line and the - * column chart. Both provide a simple way of visualizing values and - * have a retained mode and immediate mode API version. For the retain - * mode version `nk_plot` and `nk_plot_function` you either provide - * an array or a callback to call to handle drawing the graph. - * For the immediate mode version you start by calling `nk_chart_begin` - * and need to provide min and max values for scaling on the Y-axis. - * and then call `nk_chart_push` to push values into the chart. - * Finally `nk_chart_end` needs to be called to end the process. */ - float id = 0; - static int col_index = -1; - static int line_index = -1; - float step = (2*3.141592654f) / 32; - - int i; - int index = -1; - struct nk_rect bounds; - - /* line chart */ - id = 0; - index = -1; - nk_layout_row_dynamic(ctx, 100, 1); - bounds = nk_widget_bounds(ctx); - if (nk_chart_begin(ctx, NK_CHART_LINES, 32, -1.0f, 1.0f)) { - for (i = 0; i < 32; ++i) { - nk_flags res = nk_chart_push(ctx, (float)cos(id)); - if (res & NK_CHART_HOVERING) - index = (int)i; - if (res & NK_CHART_CLICKED) - line_index = (int)i; - id += step; - } - nk_chart_end(ctx); - } - - if (index != -1) { - char buffer[NK_MAX_NUMBER_BUFFER]; - float val = (float)cos((float)index*step); - sprintf(buffer, "Value: %.2f", val); - nk_tooltip(ctx, buffer); - } - if (line_index != -1) { - nk_layout_row_dynamic(ctx, 20, 1); - nk_labelf(ctx, NK_TEXT_LEFT, "Selected value: %.2f", (float)cos((float)index*step)); - } - - /* column chart */ - nk_layout_row_dynamic(ctx, 100, 1); - bounds = nk_widget_bounds(ctx); - if (nk_chart_begin(ctx, NK_CHART_COLUMN, 32, 0.0f, 1.0f)) { - for (i = 0; i < 32; ++i) { - nk_flags res = nk_chart_push(ctx, (float)fabs(sin(id))); - if (res & NK_CHART_HOVERING) - index = (int)i; - if (res & NK_CHART_CLICKED) - col_index = (int)i; - id += step; - } - nk_chart_end(ctx); - } - if (index != -1) { - char buffer[NK_MAX_NUMBER_BUFFER]; - sprintf(buffer, "Value: %.2f", (float)fabs(sin(step * (float)index))); - nk_tooltip(ctx, buffer); - } - if (col_index != -1) { - nk_layout_row_dynamic(ctx, 20, 1); - nk_labelf(ctx, NK_TEXT_LEFT, "Selected value: %.2f", (float)fabs(sin(step * (float)col_index))); - } - - /* mixed chart */ - nk_layout_row_dynamic(ctx, 100, 1); - bounds = nk_widget_bounds(ctx); - if (nk_chart_begin(ctx, NK_CHART_COLUMN, 32, 0.0f, 1.0f)) { - nk_chart_add_slot(ctx, NK_CHART_LINES, 32, -1.0f, 1.0f); - nk_chart_add_slot(ctx, NK_CHART_LINES, 32, -1.0f, 1.0f); - for (id = 0, i = 0; i < 32; ++i) { - nk_chart_push_slot(ctx, (float)fabs(sin(id)), 0); - nk_chart_push_slot(ctx, (float)cos(id), 1); - nk_chart_push_slot(ctx, (float)sin(id), 2); - id += step; - } - } - nk_chart_end(ctx); - - /* mixed colored chart */ - nk_layout_row_dynamic(ctx, 100, 1); - bounds = nk_widget_bounds(ctx); - if (nk_chart_begin_colored(ctx, NK_CHART_LINES, nk_rgb(255,0,0), nk_rgb(150,0,0), 32, 0.0f, 1.0f)) { - nk_chart_add_slot_colored(ctx, NK_CHART_LINES, nk_rgb(0,0,255), nk_rgb(0,0,150),32, -1.0f, 1.0f); - nk_chart_add_slot_colored(ctx, NK_CHART_LINES, nk_rgb(0,255,0), nk_rgb(0,150,0), 32, -1.0f, 1.0f); - for (id = 0, i = 0; i < 32; ++i) { - nk_chart_push_slot(ctx, (float)fabs(sin(id)), 0); - nk_chart_push_slot(ctx, (float)cos(id), 1); - nk_chart_push_slot(ctx, (float)sin(id), 2); - id += step; - } - } - nk_chart_end(ctx); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Popup", NK_MINIMIZED)) - { - static struct nk_color color = {255,0,0, 255}; - static int select[4]; - static int popup_active; - const struct nk_input *in = &ctx->input; - struct nk_rect bounds; - - /* menu contextual */ - nk_layout_row_static(ctx, 30, 150, 1); - bounds = nk_widget_bounds(ctx); - nk_label(ctx, "Right click me for menu", NK_TEXT_LEFT); - - if (nk_contextual_begin(ctx, 0, nk_vec2(100, 300), bounds)) { - static size_t prog = 40; - static int slider = 10; - - nk_layout_row_dynamic(ctx, 25, 1); - nk_checkbox_label(ctx, "Menu", &show_menu); - nk_progress(ctx, &prog, 100, NK_MODIFIABLE); - nk_slider_int(ctx, 0, &slider, 16, 1); - if (nk_contextual_item_label(ctx, "About", NK_TEXT_CENTERED)) - show_app_about = nk_true; - nk_selectable_label(ctx, select[0]?"Unselect":"Select", NK_TEXT_LEFT, &select[0]); - nk_selectable_label(ctx, select[1]?"Unselect":"Select", NK_TEXT_LEFT, &select[1]); - nk_selectable_label(ctx, select[2]?"Unselect":"Select", NK_TEXT_LEFT, &select[2]); - nk_selectable_label(ctx, select[3]?"Unselect":"Select", NK_TEXT_LEFT, &select[3]); - nk_contextual_end(ctx); - } - - /* color contextual */ - nk_layout_row_begin(ctx, NK_STATIC, 30, 2); - nk_layout_row_push(ctx, 100); - nk_label(ctx, "Right Click here:", NK_TEXT_LEFT); - nk_layout_row_push(ctx, 50); - bounds = nk_widget_bounds(ctx); - nk_button_color(ctx, color); - nk_layout_row_end(ctx); - - if (nk_contextual_begin(ctx, 0, nk_vec2(350, 60), bounds)) { - nk_layout_row_dynamic(ctx, 30, 4); - color.r = (nk_byte)nk_propertyi(ctx, "#r", 0, color.r, 255, 1, 1); - color.g = (nk_byte)nk_propertyi(ctx, "#g", 0, color.g, 255, 1, 1); - color.b = (nk_byte)nk_propertyi(ctx, "#b", 0, color.b, 255, 1, 1); - color.a = (nk_byte)nk_propertyi(ctx, "#a", 0, color.a, 255, 1, 1); - nk_contextual_end(ctx); - } - - /* popup */ - nk_layout_row_begin(ctx, NK_STATIC, 30, 2); - nk_layout_row_push(ctx, 100); - nk_label(ctx, "Popup:", NK_TEXT_LEFT); - nk_layout_row_push(ctx, 50); - if (nk_button_label(ctx, "Popup")) - popup_active = 1; - nk_layout_row_end(ctx); - - if (popup_active) - { - static struct nk_rect s = {20, 100, 220, 90}; - if (nk_popup_begin(ctx, NK_POPUP_STATIC, "Error", 0, s)) - { - nk_layout_row_dynamic(ctx, 25, 1); - nk_label(ctx, "A terrible error as occured", NK_TEXT_LEFT); - nk_layout_row_dynamic(ctx, 25, 2); - if (nk_button_label(ctx, "OK")) { - popup_active = 0; - nk_popup_close(ctx); - } - if (nk_button_label(ctx, "Cancel")) { - popup_active = 0; - nk_popup_close(ctx); - } - nk_popup_end(ctx); - } else popup_active = nk_false; - } - - /* tooltip */ - nk_layout_row_static(ctx, 30, 150, 1); - bounds = nk_widget_bounds(ctx); - nk_label(ctx, "Hover me for tooltip", NK_TEXT_LEFT); - if (nk_input_is_mouse_hovering_rect(in, bounds)) - nk_tooltip(ctx, "This is a tooltip"); - - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Layout", NK_MINIMIZED)) - { - if (nk_tree_push(ctx, NK_TREE_NODE, "Widget", NK_MINIMIZED)) - { - float ratio_two[] = {0.2f, 0.6f, 0.2f}; - float width_two[] = {100, 200, 50}; - - nk_layout_row_dynamic(ctx, 30, 1); - nk_label(ctx, "Dynamic fixed column layout with generated position and size:", NK_TEXT_LEFT); - nk_layout_row_dynamic(ctx, 30, 3); - nk_button_label(ctx, "button"); - nk_button_label(ctx, "button"); - nk_button_label(ctx, "button"); - - nk_layout_row_dynamic(ctx, 30, 1); - nk_label(ctx, "static fixed column layout with generated position and size:", NK_TEXT_LEFT); - nk_layout_row_static(ctx, 30, 100, 3); - nk_button_label(ctx, "button"); - nk_button_label(ctx, "button"); - nk_button_label(ctx, "button"); - - nk_layout_row_dynamic(ctx, 30, 1); - nk_label(ctx, "Dynamic array-based custom column layout with generated position and custom size:",NK_TEXT_LEFT); - nk_layout_row(ctx, NK_DYNAMIC, 30, 3, ratio_two); - nk_button_label(ctx, "button"); - nk_button_label(ctx, "button"); - nk_button_label(ctx, "button"); - - nk_layout_row_dynamic(ctx, 30, 1); - nk_label(ctx, "Static array-based custom column layout with generated position and custom size:",NK_TEXT_LEFT ); - nk_layout_row(ctx, NK_STATIC, 30, 3, width_two); - nk_button_label(ctx, "button"); - nk_button_label(ctx, "button"); - nk_button_label(ctx, "button"); - - nk_layout_row_dynamic(ctx, 30, 1); - nk_label(ctx, "Dynamic immediate mode custom column layout with generated position and custom size:",NK_TEXT_LEFT); - nk_layout_row_begin(ctx, NK_DYNAMIC, 30, 3); - nk_layout_row_push(ctx, 0.2f); - nk_button_label(ctx, "button"); - nk_layout_row_push(ctx, 0.6f); - nk_button_label(ctx, "button"); - nk_layout_row_push(ctx, 0.2f); - nk_button_label(ctx, "button"); - nk_layout_row_end(ctx); - - nk_layout_row_dynamic(ctx, 30, 1); - nk_label(ctx, "Static immediate mode custom column layout with generated position and custom size:", NK_TEXT_LEFT); - nk_layout_row_begin(ctx, NK_STATIC, 30, 3); - nk_layout_row_push(ctx, 100); - nk_button_label(ctx, "button"); - nk_layout_row_push(ctx, 200); - nk_button_label(ctx, "button"); - nk_layout_row_push(ctx, 50); - nk_button_label(ctx, "button"); - nk_layout_row_end(ctx); - - nk_layout_row_dynamic(ctx, 30, 1); - nk_label(ctx, "Static free space with custom position and custom size:", NK_TEXT_LEFT); - nk_layout_space_begin(ctx, NK_STATIC, 120, 4); - nk_layout_space_push(ctx, nk_rect(100, 0, 100, 30)); - nk_button_label(ctx, "button"); - nk_layout_space_push(ctx, nk_rect(0, 15, 100, 30)); - nk_button_label(ctx, "button"); - nk_layout_space_push(ctx, nk_rect(200, 15, 100, 30)); - nk_button_label(ctx, "button"); - nk_layout_space_push(ctx, nk_rect(100, 30, 100, 30)); - nk_button_label(ctx, "button"); - nk_layout_space_end(ctx); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Group", NK_MINIMIZED)) - { - static int group_titlebar = nk_false; - static int group_border = nk_true; - static int group_no_scrollbar = nk_false; - static int group_width = 320; - static int group_height = 200; - - nk_flags group_flags = 0; - if (group_border) group_flags |= NK_WINDOW_BORDER; - if (group_no_scrollbar) group_flags |= NK_WINDOW_NO_SCROLLBAR; - if (group_titlebar) group_flags |= NK_WINDOW_TITLE; - - nk_layout_row_dynamic(ctx, 30, 3); - nk_checkbox_label(ctx, "Titlebar", &group_titlebar); - nk_checkbox_label(ctx, "Border", &group_border); - nk_checkbox_label(ctx, "No Scrollbar", &group_no_scrollbar); - - nk_layout_row_begin(ctx, NK_STATIC, 22, 3); - nk_layout_row_push(ctx, 50); - nk_label(ctx, "size:", NK_TEXT_LEFT); - nk_layout_row_push(ctx, 130); - nk_property_int(ctx, "#Width:", 100, &group_width, 500, 10, 1); - nk_layout_row_push(ctx, 130); - nk_property_int(ctx, "#Height:", 100, &group_height, 500, 10, 1); - nk_layout_row_end(ctx); - - nk_layout_row_static(ctx, (float)group_height, group_width, 2); - if (nk_group_begin(ctx, "Group", group_flags)) { - int i = 0; - static int selected[16]; - nk_layout_row_static(ctx, 18, 100, 1); - for (i = 0; i < 16; ++i) - nk_selectable_label(ctx, (selected[i]) ? "Selected": "Unselected", NK_TEXT_CENTERED, &selected[i]); - nk_group_end(ctx); - } - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Notebook", NK_MINIMIZED)) - { - static int current_tab = 0; - struct nk_vec2 item_padding; - struct nk_rect bounds; - float step = (2*3.141592654f) / 32; - enum chart_type {CHART_LINE, CHART_HISTO, CHART_MIXED}; - const char *names[] = {"Lines", "Columns", "Mixed"}; - float id = 0; - int i; - - /* Header */ - nk_style_push_vec2(ctx, &ctx->style.window.spacing, nk_vec2(0,0)); - nk_style_push_float(ctx, &ctx->style.button.rounding, 0); - nk_layout_row_begin(ctx, NK_STATIC, 20, 3); - for (i = 0; i < 3; ++i) { - /* make sure button perfectly fits text */ - const struct nk_user_font *f = ctx->style.font; - float text_width = f->width(f->userdata, f->height, names[i], nk_strlen(names[i])); - float widget_width = text_width + 3 * ctx->style.button.padding.x; - nk_layout_row_push(ctx, widget_width); - if (current_tab == i) { - /* active tab gets highlighted */ - struct nk_style_item button_color = ctx->style.button.normal; - ctx->style.button.normal = ctx->style.button.active; - current_tab = nk_button_label(ctx, names[i]) ? i: current_tab; - ctx->style.button.normal = button_color; - } else current_tab = nk_button_label(ctx, names[i]) ? i: current_tab; - } - nk_style_pop_float(ctx); - - /* Body */ - nk_layout_row_dynamic(ctx, 140, 1); - if (nk_group_begin(ctx, "Notebook", NK_WINDOW_BORDER)) - { - nk_style_pop_vec2(ctx); - switch (current_tab) { - case CHART_LINE: - nk_layout_row_dynamic(ctx, 100, 1); - bounds = nk_widget_bounds(ctx); - if (nk_chart_begin_colored(ctx, NK_CHART_LINES, nk_rgb(255,0,0), nk_rgb(150,0,0), 32, 0.0f, 1.0f)) { - nk_chart_add_slot_colored(ctx, NK_CHART_LINES, nk_rgb(0,0,255), nk_rgb(0,0,150),32, -1.0f, 1.0f); - for (i = 0, id = 0; i < 32; ++i) { - nk_chart_push_slot(ctx, (float)fabs(sin(id)), 0); - nk_chart_push_slot(ctx, (float)cos(id), 1); - id += step; - } - } - nk_chart_end(ctx); - break; - case CHART_HISTO: - nk_layout_row_dynamic(ctx, 100, 1); - bounds = nk_widget_bounds(ctx); - if (nk_chart_begin_colored(ctx, NK_CHART_COLUMN, nk_rgb(255,0,0), nk_rgb(150,0,0), 32, 0.0f, 1.0f)) { - for (i = 0, id = 0; i < 32; ++i) { - nk_chart_push_slot(ctx, (float)fabs(sin(id)), 0); - id += step; - } - } - nk_chart_end(ctx); - break; - case CHART_MIXED: - nk_layout_row_dynamic(ctx, 100, 1); - bounds = nk_widget_bounds(ctx); - if (nk_chart_begin_colored(ctx, NK_CHART_LINES, nk_rgb(255,0,0), nk_rgb(150,0,0), 32, 0.0f, 1.0f)) { - nk_chart_add_slot_colored(ctx, NK_CHART_LINES, nk_rgb(0,0,255), nk_rgb(0,0,150),32, -1.0f, 1.0f); - nk_chart_add_slot_colored(ctx, NK_CHART_COLUMN, nk_rgb(0,255,0), nk_rgb(0,150,0), 32, 0.0f, 1.0f); - for (i = 0, id = 0; i < 32; ++i) { - nk_chart_push_slot(ctx, (float)fabs(sin(id)), 0); - nk_chart_push_slot(ctx, (float)fabs(cos(id)), 1); - nk_chart_push_slot(ctx, (float)fabs(sin(id)), 2); - id += step; - } - } - nk_chart_end(ctx); - break; - } - nk_group_end(ctx); - } else nk_style_pop_vec2(ctx); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Simple", NK_MINIMIZED)) - { - nk_layout_row_dynamic(ctx, 300, 2); - if (nk_group_begin(ctx, "Group_Without_Border", 0)) { - int i = 0; - char buffer[64]; - nk_layout_row_static(ctx, 18, 150, 1); - for (i = 0; i < 64; ++i) { - sprintf(buffer, "0x%02x", i); - nk_labelf(ctx, NK_TEXT_LEFT, "%s: scrollable region", buffer); - } - nk_group_end(ctx); - } - if (nk_group_begin(ctx, "Group_With_Border", NK_WINDOW_BORDER)) { - int i = 0; - char buffer[64]; - nk_layout_row_dynamic(ctx, 25, 2); - for (i = 0; i < 64; ++i) { - sprintf(buffer, "%08d", ((((i%7)*10)^32))+(64+(i%2)*2)); - nk_button_label(ctx, buffer); - } - nk_group_end(ctx); - } - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Complex", NK_MINIMIZED)) - { - int i; - nk_layout_space_begin(ctx, NK_STATIC, 500, 64); - nk_layout_space_push(ctx, nk_rect(0,0,150,500)); - if (nk_group_begin(ctx, "Group_left", NK_WINDOW_BORDER)) { - static int selected[32]; - nk_layout_row_static(ctx, 18, 100, 1); - for (i = 0; i < 32; ++i) - nk_selectable_label(ctx, (selected[i]) ? "Selected": "Unselected", NK_TEXT_CENTERED, &selected[i]); - nk_group_end(ctx); - } - - nk_layout_space_push(ctx, nk_rect(160,0,150,240)); - if (nk_group_begin(ctx, "Group_top", NK_WINDOW_BORDER)) { - nk_layout_row_dynamic(ctx, 25, 1); - nk_button_label(ctx, "#FFAA"); - nk_button_label(ctx, "#FFBB"); - nk_button_label(ctx, "#FFCC"); - nk_button_label(ctx, "#FFDD"); - nk_button_label(ctx, "#FFEE"); - nk_button_label(ctx, "#FFFF"); - nk_group_end(ctx); - } - - nk_layout_space_push(ctx, nk_rect(160,250,150,250)); - if (nk_group_begin(ctx, "Group_buttom", NK_WINDOW_BORDER)) { - nk_layout_row_dynamic(ctx, 25, 1); - nk_button_label(ctx, "#FFAA"); - nk_button_label(ctx, "#FFBB"); - nk_button_label(ctx, "#FFCC"); - nk_button_label(ctx, "#FFDD"); - nk_button_label(ctx, "#FFEE"); - nk_button_label(ctx, "#FFFF"); - nk_group_end(ctx); - } - - nk_layout_space_push(ctx, nk_rect(320,0,150,150)); - if (nk_group_begin(ctx, "Group_right_top", NK_WINDOW_BORDER)) { - static int selected[4]; - nk_layout_row_static(ctx, 18, 100, 1); - for (i = 0; i < 4; ++i) - nk_selectable_label(ctx, (selected[i]) ? "Selected": "Unselected", NK_TEXT_CENTERED, &selected[i]); - nk_group_end(ctx); - } - - nk_layout_space_push(ctx, nk_rect(320,160,150,150)); - if (nk_group_begin(ctx, "Group_right_center", NK_WINDOW_BORDER)) { - static int selected[4]; - nk_layout_row_static(ctx, 18, 100, 1); - for (i = 0; i < 4; ++i) - nk_selectable_label(ctx, (selected[i]) ? "Selected": "Unselected", NK_TEXT_CENTERED, &selected[i]); - nk_group_end(ctx); - } - - nk_layout_space_push(ctx, nk_rect(320,320,150,150)); - if (nk_group_begin(ctx, "Group_right_bottom", NK_WINDOW_BORDER)) { - static int selected[4]; - nk_layout_row_static(ctx, 18, 100, 1); - for (i = 0; i < 4; ++i) - nk_selectable_label(ctx, (selected[i]) ? "Selected": "Unselected", NK_TEXT_CENTERED, &selected[i]); - nk_group_end(ctx); - } - nk_layout_space_end(ctx); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Splitter", NK_MINIMIZED)) - { - const struct nk_input *in = &ctx->input; - nk_layout_row_static(ctx, 20, 320, 1); - nk_label(ctx, "Use slider and spinner to change tile size", NK_TEXT_LEFT); - nk_label(ctx, "Drag the space between tiles to change tile ratio", NK_TEXT_LEFT); - - if (nk_tree_push(ctx, NK_TREE_NODE, "Vertical", NK_MINIMIZED)) - { - static float a = 100, b = 100, c = 100; - struct nk_rect bounds; - - float row_layout[5]; - row_layout[0] = a; - row_layout[1] = 8; - row_layout[2] = b; - row_layout[3] = 8; - row_layout[4] = c; - - /* header */ - nk_layout_row_static(ctx, 30, 100, 2); - nk_label(ctx, "left:", NK_TEXT_LEFT); - nk_slider_float(ctx, 10.0f, &a, 200.0f, 10.0f); - - nk_label(ctx, "middle:", NK_TEXT_LEFT); - nk_slider_float(ctx, 10.0f, &b, 200.0f, 10.0f); - - nk_label(ctx, "right:", NK_TEXT_LEFT); - nk_slider_float(ctx, 10.0f, &c, 200.0f, 10.0f); - - /* tiles */ - nk_layout_row(ctx, NK_STATIC, 200, 5, row_layout); - - /* left space */ - if (nk_group_begin(ctx, "left", NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER|NK_WINDOW_NO_SCROLLBAR)) { - nk_layout_row_dynamic(ctx, 25, 1); - nk_button_label(ctx, "#FFAA"); - nk_button_label(ctx, "#FFBB"); - nk_button_label(ctx, "#FFCC"); - nk_button_label(ctx, "#FFDD"); - nk_button_label(ctx, "#FFEE"); - nk_button_label(ctx, "#FFFF"); - nk_group_end(ctx); - } - - /* scaler */ - bounds = nk_widget_bounds(ctx); - nk_spacing(ctx, 1); - if ((nk_input_is_mouse_hovering_rect(in, bounds) || - nk_input_is_mouse_prev_hovering_rect(in, bounds)) && - nk_input_is_mouse_down(in, NK_BUTTON_LEFT)) - { - a = row_layout[0] + in->mouse.delta.x; - b = row_layout[2] - in->mouse.delta.x; - } - - /* middle space */ - if (nk_group_begin(ctx, "center", NK_WINDOW_BORDER|NK_WINDOW_NO_SCROLLBAR)) { - nk_layout_row_dynamic(ctx, 25, 1); - nk_button_label(ctx, "#FFAA"); - nk_button_label(ctx, "#FFBB"); - nk_button_label(ctx, "#FFCC"); - nk_button_label(ctx, "#FFDD"); - nk_button_label(ctx, "#FFEE"); - nk_button_label(ctx, "#FFFF"); - nk_group_end(ctx); - } - - /* scaler */ - bounds = nk_widget_bounds(ctx); - nk_spacing(ctx, 1); - if ((nk_input_is_mouse_hovering_rect(in, bounds) || - nk_input_is_mouse_prev_hovering_rect(in, bounds)) && - nk_input_is_mouse_down(in, NK_BUTTON_LEFT)) - { - b = (row_layout[2] + in->mouse.delta.x); - c = (row_layout[4] - in->mouse.delta.x); - } - - /* right space */ - if (nk_group_begin(ctx, "right", NK_WINDOW_BORDER|NK_WINDOW_NO_SCROLLBAR)) { - nk_layout_row_dynamic(ctx, 25, 1); - nk_button_label(ctx, "#FFAA"); - nk_button_label(ctx, "#FFBB"); - nk_button_label(ctx, "#FFCC"); - nk_button_label(ctx, "#FFDD"); - nk_button_label(ctx, "#FFEE"); - nk_button_label(ctx, "#FFFF"); - nk_group_end(ctx); - } - - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Horizontal", NK_MINIMIZED)) - { - static float a = 100, b = 100, c = 100; - struct nk_rect bounds; - - /* header */ - nk_layout_row_static(ctx, 30, 100, 2); - nk_label(ctx, "top:", NK_TEXT_LEFT); - nk_slider_float(ctx, 10.0f, &a, 200.0f, 10.0f); - - nk_label(ctx, "middle:", NK_TEXT_LEFT); - nk_slider_float(ctx, 10.0f, &b, 200.0f, 10.0f); - - nk_label(ctx, "bottom:", NK_TEXT_LEFT); - nk_slider_float(ctx, 10.0f, &c, 200.0f, 10.0f); - - /* top space */ - nk_layout_row_dynamic(ctx, a, 1); - if (nk_group_begin(ctx, "top", NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER)) { - nk_layout_row_dynamic(ctx, 25, 3); - nk_button_label(ctx, "#FFAA"); - nk_button_label(ctx, "#FFBB"); - nk_button_label(ctx, "#FFCC"); - nk_button_label(ctx, "#FFDD"); - nk_button_label(ctx, "#FFEE"); - nk_button_label(ctx, "#FFFF"); - nk_group_end(ctx); - } - - /* scaler */ - nk_layout_row_dynamic(ctx, 8, 1); - bounds = nk_widget_bounds(ctx); - nk_spacing(ctx, 1); - if ((nk_input_is_mouse_hovering_rect(in, bounds) || - nk_input_is_mouse_prev_hovering_rect(in, bounds)) && - nk_input_is_mouse_down(in, NK_BUTTON_LEFT)) - { - a = a + in->mouse.delta.y; - b = b - in->mouse.delta.y; - } - - /* middle space */ - nk_layout_row_dynamic(ctx, b, 1); - if (nk_group_begin(ctx, "middle", NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER)) { - nk_layout_row_dynamic(ctx, 25, 3); - nk_button_label(ctx, "#FFAA"); - nk_button_label(ctx, "#FFBB"); - nk_button_label(ctx, "#FFCC"); - nk_button_label(ctx, "#FFDD"); - nk_button_label(ctx, "#FFEE"); - nk_button_label(ctx, "#FFFF"); - nk_group_end(ctx); - } - - { - /* scaler */ - nk_layout_row_dynamic(ctx, 8, 1); - bounds = nk_widget_bounds(ctx); - if ((nk_input_is_mouse_hovering_rect(in, bounds) || - nk_input_is_mouse_prev_hovering_rect(in, bounds)) && - nk_input_is_mouse_down(in, NK_BUTTON_LEFT)) - { - b = b + in->mouse.delta.y; - c = c - in->mouse.delta.y; - } - } - - /* bottom space */ - nk_layout_row_dynamic(ctx, c, 1); - if (nk_group_begin(ctx, "bottom", NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER)) { - nk_layout_row_dynamic(ctx, 25, 3); - nk_button_label(ctx, "#FFAA"); - nk_button_label(ctx, "#FFBB"); - nk_button_label(ctx, "#FFCC"); - nk_button_label(ctx, "#FFDD"); - nk_button_label(ctx, "#FFEE"); - nk_button_label(ctx, "#FFFF"); - nk_group_end(ctx); - } - nk_tree_pop(ctx); - } - nk_tree_pop(ctx); - } - nk_tree_pop(ctx); - } - } - nk_end(ctx); - return !nk_window_is_closed(ctx, "Overview"); -} - diff --git a/deps/nuklear/demo/sdl_opengl2/main.c b/deps/nuklear/demo/sdl_opengl2/main.c deleted file mode 100644 index 0d96551c..00000000 --- a/deps/nuklear/demo/sdl_opengl2/main.c +++ /dev/null @@ -1,181 +0,0 @@ -/* nuklear - v1.17 - public domain */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define NK_INCLUDE_FIXED_TYPES -#define NK_INCLUDE_STANDARD_IO -#define NK_INCLUDE_STANDARD_VARARGS -#define NK_INCLUDE_DEFAULT_ALLOCATOR -#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT -#define NK_INCLUDE_FONT_BAKING -#define NK_INCLUDE_DEFAULT_FONT -#define NK_IMPLEMENTATION -#define NK_SDL_GL2_IMPLEMENTATION -#include "../../nuklear.h" -#include "nuklear_sdl_gl2.h" - -#define WINDOW_WIDTH 1200 -#define WINDOW_HEIGHT 800 - -#define MAX_VERTEX_MEMORY 512 * 1024 -#define MAX_ELEMENT_MEMORY 128 * 1024 - -#define UNUSED(a) (void)a -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) < (b) ? (b) : (a)) -#define LEN(a) (sizeof(a)/sizeof(a)[0]) - -/* =============================================================== - * - * EXAMPLE - * - * ===============================================================*/ -/* This are some code examples to provide a small overview of what can be - * done with this library. To try out an example uncomment the include - * and the corresponding function. */ -/*#include "../style.c"*/ -/*#include "../calculator.c"*/ -/*#include "../overview.c"*/ -/*#include "../node_editor.c"*/ - -/* =============================================================== - * - * DEMO - * - * ===============================================================*/ -int -main(int argc, char* argv[]) -{ - /* Platform */ - SDL_Window *win; - SDL_GLContext glContext; - struct nk_color background; - int win_width, win_height; - int running = 1; - - /* GUI */ - struct nk_context *ctx; - - /* SDL setup */ - SDL_SetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED, "0"); - SDL_Init(SDL_INIT_VIDEO); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); - win = SDL_CreateWindow("Demo", - SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN|SDL_WINDOW_ALLOW_HIGHDPI); - glContext = SDL_GL_CreateContext(win); - SDL_GetWindowSize(win, &win_width, &win_height); - - /* GUI */ - ctx = nk_sdl_init(win); - /* Load Fonts: if none of these are loaded a default font will be used */ - /* Load Cursor: if you uncomment cursor loading please hide the cursor */ - {struct nk_font_atlas *atlas; - nk_sdl_font_stash_begin(&atlas); - /*struct nk_font *droid = nk_font_atlas_add_from_file(atlas, "../../../extra_font/DroidSans.ttf", 14, 0);*/ - /*struct nk_font *roboto = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Roboto-Regular.ttf", 16, 0);*/ - /*struct nk_font *future = nk_font_atlas_add_from_file(atlas, "../../../extra_font/kenvector_future_thin.ttf", 13, 0);*/ - /*struct nk_font *clean = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyClean.ttf", 12, 0);*/ - /*struct nk_font *tiny = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyTiny.ttf", 10, 0);*/ - /*struct nk_font *cousine = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Cousine-Regular.ttf", 13, 0);*/ - nk_sdl_font_stash_end(); - /*nk_style_load_all_cursors(ctx, atlas->cursors);*/ - /*nk_style_set_font(ctx, &roboto->handle)*/;} - - /* style.c */ - /*set_style(ctx, THEME_WHITE);*/ - /*set_style(ctx, THEME_RED);*/ - /*set_style(ctx, THEME_BLUE);*/ - /*set_style(ctx, THEME_DARK);*/ - - background = nk_rgb(28,48,62); - while (running) - { - /* Input */ - SDL_Event evt; - nk_input_begin(ctx); - while (SDL_PollEvent(&evt)) { - if (evt.type == SDL_QUIT) goto cleanup; - nk_sdl_handle_event(&evt); - } - nk_input_end(ctx); - - /* GUI */ - if (nk_begin(ctx, "Demo", nk_rect(50, 50, 210, 250), - NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE| - NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE)) - { - enum {EASY, HARD}; - static int op = EASY; - static int property = 20; - - nk_layout_row_static(ctx, 30, 80, 1); - if (nk_button_label(ctx, "button")) - fprintf(stdout, "button pressed\n"); - nk_layout_row_dynamic(ctx, 30, 2); - if (nk_option_label(ctx, "easy", op == EASY)) op = EASY; - if (nk_option_label(ctx, "hard", op == HARD)) op = HARD; - nk_layout_row_dynamic(ctx, 25, 1); - nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1); - - nk_layout_row_dynamic(ctx, 20, 1); - nk_label(ctx, "background:", NK_TEXT_LEFT); - nk_layout_row_dynamic(ctx, 25, 1); - if (nk_combo_begin_color(ctx, background, nk_vec2(nk_widget_width(ctx),400))) { - nk_layout_row_dynamic(ctx, 120, 1); - background = nk_color_picker(ctx, background, NK_RGBA); - nk_layout_row_dynamic(ctx, 25, 1); - background.r = (nk_byte)nk_propertyi(ctx, "#R:", 0, background.r, 255, 1,1); - background.g = (nk_byte)nk_propertyi(ctx, "#G:", 0, background.g, 255, 1,1); - background.b = (nk_byte)nk_propertyi(ctx, "#B:", 0, background.b, 255, 1,1); - background.a = (nk_byte)nk_propertyi(ctx, "#A:", 0, background.a, 255, 1,1); - nk_combo_end(ctx); - } - } - nk_end(ctx); - - /* -------------- EXAMPLES ---------------- */ - /*calculator(ctx);*/ - /*overview(ctx);*/ - /*node_editor(ctx);*/ - /* ----------------------------------------- */ - - /* Draw */ - {float bg[4]; - nk_color_fv(bg, background); - SDL_GetWindowSize(win, &win_width, &win_height); - glViewport(0, 0, win_width, win_height); - glClear(GL_COLOR_BUFFER_BIT); - glClearColor(bg[0], bg[1], bg[2], bg[3]); - /* IMPORTANT: `nk_sdl_render` modifies some global OpenGL state - * with blending, scissor, face culling, depth test and viewport and - * defaults everything back into a default state. - * Make sure to either a.) save and restore or b.) reset your own state after - * rendering the UI. */ - nk_sdl_render(NK_ANTI_ALIASING_ON, MAX_VERTEX_MEMORY, MAX_ELEMENT_MEMORY); - SDL_GL_SwapWindow(win);} - } - -cleanup: - nk_sdl_shutdown(); - SDL_GL_DeleteContext(glContext); - SDL_DestroyWindow(win); - SDL_Quit(); - return 0; -} - diff --git a/deps/nuklear/demo/sdl_opengl2/nuklear_sdl_gl2.h b/deps/nuklear/demo/sdl_opengl2/nuklear_sdl_gl2.h deleted file mode 100644 index 45c59702..00000000 --- a/deps/nuklear/demo/sdl_opengl2/nuklear_sdl_gl2.h +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Nuklear - v1.17 - public domain - * no warrenty implied; use at your own risk. - * authored from 2015-2016 by Micha Mettke - */ -/* - * ============================================================== - * - * API - * - * =============================================================== - */ -#ifndef NK_SDL_GL2_H_ -#define NK_SDL_GL2_H_ - -#include -NK_API struct nk_context* nk_sdl_init(SDL_Window *win); -NK_API void nk_sdl_font_stash_begin(struct nk_font_atlas **atlas); -NK_API void nk_sdl_font_stash_end(void); -NK_API int nk_sdl_handle_event(SDL_Event *evt); -NK_API void nk_sdl_render(enum nk_anti_aliasing , int max_vertex_buffer, int max_element_buffer); -NK_API void nk_sdl_shutdown(void); - -#endif -/* - * ============================================================== - * - * IMPLEMENTATION - * - * =============================================================== - */ -#ifdef NK_SDL_GL2_IMPLEMENTATION - -struct nk_sdl_device { - struct nk_buffer cmds; - struct nk_draw_null_texture null; - GLuint font_tex; -}; - -struct nk_sdl_vertex { - float position[2]; - float uv[2]; - nk_byte col[4]; -}; - -static struct nk_sdl { - SDL_Window *win; - struct nk_sdl_device ogl; - struct nk_context ctx; - struct nk_font_atlas atlas; -} sdl; - -NK_INTERN void -nk_sdl_device_upload_atlas(const void *image, int width, int height) -{ - struct nk_sdl_device *dev = &sdl.ogl; - glGenTextures(1, &dev->font_tex); - glBindTexture(GL_TEXTURE_2D, dev->font_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, image); -} - -NK_API void -nk_sdl_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_buffer) -{ - /* setup global state */ - struct nk_sdl_device *dev = &sdl.ogl; - int width, height; - int display_width, display_height; - struct nk_vec2 scale; - - SDL_GetWindowSize(sdl.win, &width, &height); - SDL_GL_GetDrawableSize(sdl.win, &display_width, &display_height); - scale.x = (float)display_width/(float)width; - scale.y = (float)display_height/(float)height; - - glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT|GL_TRANSFORM_BIT); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnable(GL_BLEND); - glEnable(GL_TEXTURE_2D); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - /* setup viewport/project */ - glViewport(0,0,(GLsizei)display_width,(GLsizei)display_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, width, height, 0.0f, -1.0f, 1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - { - GLsizei vs = sizeof(struct nk_sdl_vertex); - size_t vp = offsetof(struct nk_sdl_vertex, position); - size_t vt = offsetof(struct nk_sdl_vertex, uv); - size_t vc = offsetof(struct nk_sdl_vertex, col); - - /* convert from command queue into draw list and draw to screen */ - const struct nk_draw_command *cmd; - const nk_draw_index *offset = NULL; - struct nk_buffer vbuf, ebuf; - - /* fill converting configuration */ - struct nk_convert_config config; - static const struct nk_draw_vertex_layout_element vertex_layout[] = { - {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_sdl_vertex, position)}, - {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_sdl_vertex, uv)}, - {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_sdl_vertex, col)}, - {NK_VERTEX_LAYOUT_END} - }; - NK_MEMSET(&config, 0, sizeof(config)); - config.vertex_layout = vertex_layout; - config.vertex_size = sizeof(struct nk_sdl_vertex); - config.vertex_alignment = NK_ALIGNOF(struct nk_sdl_vertex); - config.null = dev->null; - config.circle_segment_count = 22; - config.curve_segment_count = 22; - config.arc_segment_count = 22; - config.global_alpha = 1.0f; - config.shape_AA = AA; - config.line_AA = AA; - - /* convert shapes into vertexes */ - nk_buffer_init_default(&vbuf); - nk_buffer_init_default(&ebuf); - nk_convert(&sdl.ctx, &dev->cmds, &vbuf, &ebuf, &config); - - /* setup vertex buffer pointer */ - {const void *vertices = nk_buffer_memory_const(&vbuf); - glVertexPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vp)); - glTexCoordPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vt)); - glColorPointer(4, GL_UNSIGNED_BYTE, vs, (const void*)((const nk_byte*)vertices + vc));} - - /* iterate over and execute each draw command */ - offset = (const nk_draw_index*)nk_buffer_memory_const(&ebuf); - nk_draw_foreach(cmd, &sdl.ctx, &dev->cmds) - { - if (!cmd->elem_count) continue; - glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id); - glScissor( - (GLint)(cmd->clip_rect.x * scale.x), - (GLint)((height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * scale.y), - (GLint)(cmd->clip_rect.w * scale.x), - (GLint)(cmd->clip_rect.h * scale.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset); - offset += cmd->elem_count; - } - nk_clear(&sdl.ctx); - nk_buffer_free(&vbuf); - nk_buffer_free(&ebuf); - } - - /* default OpenGL state */ - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - - glBindTexture(GL_TEXTURE_2D, 0); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); -} - -static void -nk_sdl_clipbard_paste(nk_handle usr, struct nk_text_edit *edit) -{ - const char *text = SDL_GetClipboardText(); - if (text) nk_textedit_paste(edit, text, nk_strlen(text)); - (void)usr; -} - -static void -nk_sdl_clipbard_copy(nk_handle usr, const char *text, int len) -{ - char *str = 0; - (void)usr; - if (!len) return; - str = (char*)malloc((size_t)len+1); - if (!str) return; - memcpy(str, text, (size_t)len); - str[len] = '\0'; - SDL_SetClipboardText(str); - free(str); -} - -NK_API struct nk_context* -nk_sdl_init(SDL_Window *win) -{ - sdl.win = win; - nk_init_default(&sdl.ctx, 0); - sdl.ctx.clip.copy = nk_sdl_clipbard_copy; - sdl.ctx.clip.paste = nk_sdl_clipbard_paste; - sdl.ctx.clip.userdata = nk_handle_ptr(0); - nk_buffer_init_default(&sdl.ogl.cmds); - return &sdl.ctx; -} - -NK_API void -nk_sdl_font_stash_begin(struct nk_font_atlas **atlas) -{ - nk_font_atlas_init_default(&sdl.atlas); - nk_font_atlas_begin(&sdl.atlas); - *atlas = &sdl.atlas; -} - -NK_API void -nk_sdl_font_stash_end(void) -{ - const void *image; int w, h; - image = nk_font_atlas_bake(&sdl.atlas, &w, &h, NK_FONT_ATLAS_RGBA32); - nk_sdl_device_upload_atlas(image, w, h); - nk_font_atlas_end(&sdl.atlas, nk_handle_id((int)sdl.ogl.font_tex), &sdl.ogl.null); - if (sdl.atlas.default_font) - nk_style_set_font(&sdl.ctx, &sdl.atlas.default_font->handle); -} - -NK_API int -nk_sdl_handle_event(SDL_Event *evt) -{ - struct nk_context *ctx = &sdl.ctx; - - /* optional grabbing behavior */ - if (ctx->input.mouse.grab) { - SDL_SetRelativeMouseMode(SDL_TRUE); - ctx->input.mouse.grab = 0; - } else if (ctx->input.mouse.ungrab) { - int x = (int)ctx->input.mouse.prev.x, y = (int)ctx->input.mouse.prev.y; - SDL_SetRelativeMouseMode(SDL_FALSE); - SDL_WarpMouseInWindow(sdl.win, x, y); - ctx->input.mouse.ungrab = 0; - } - if (evt->type == SDL_KEYUP || evt->type == SDL_KEYDOWN) { - /* key events */ - int down = evt->type == SDL_KEYDOWN; - const Uint8* state = SDL_GetKeyboardState(0); - SDL_Keycode sym = evt->key.keysym.sym; - if (sym == SDLK_RSHIFT || sym == SDLK_LSHIFT) - nk_input_key(ctx, NK_KEY_SHIFT, down); - else if (sym == SDLK_DELETE) - nk_input_key(ctx, NK_KEY_DEL, down); - else if (sym == SDLK_RETURN) - nk_input_key(ctx, NK_KEY_ENTER, down); - else if (sym == SDLK_TAB) - nk_input_key(ctx, NK_KEY_TAB, down); - else if (sym == SDLK_BACKSPACE) - nk_input_key(ctx, NK_KEY_BACKSPACE, down); - else if (sym == SDLK_HOME) { - nk_input_key(ctx, NK_KEY_TEXT_START, down); - nk_input_key(ctx, NK_KEY_SCROLL_START, down); - } else if (sym == SDLK_END) { - nk_input_key(ctx, NK_KEY_TEXT_END, down); - nk_input_key(ctx, NK_KEY_SCROLL_END, down); - } else if (sym == SDLK_PAGEDOWN) { - nk_input_key(ctx, NK_KEY_SCROLL_DOWN, down); - } else if (sym == SDLK_PAGEUP) { - nk_input_key(ctx, NK_KEY_SCROLL_UP, down); - } else if (sym == SDLK_z) - nk_input_key(ctx, NK_KEY_TEXT_UNDO, down && state[SDL_SCANCODE_LCTRL]); - else if (sym == SDLK_r) - nk_input_key(ctx, NK_KEY_TEXT_REDO, down && state[SDL_SCANCODE_LCTRL]); - else if (sym == SDLK_c) - nk_input_key(ctx, NK_KEY_COPY, down && state[SDL_SCANCODE_LCTRL]); - else if (sym == SDLK_v) - nk_input_key(ctx, NK_KEY_PASTE, down && state[SDL_SCANCODE_LCTRL]); - else if (sym == SDLK_x) - nk_input_key(ctx, NK_KEY_CUT, down && state[SDL_SCANCODE_LCTRL]); - else if (sym == SDLK_b) - nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down && state[SDL_SCANCODE_LCTRL]); - else if (sym == SDLK_e) - nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down && state[SDL_SCANCODE_LCTRL]); - else if (sym == SDLK_UP) - nk_input_key(ctx, NK_KEY_UP, down); - else if (sym == SDLK_DOWN) - nk_input_key(ctx, NK_KEY_DOWN, down); - else if (sym == SDLK_LEFT) { - if (state[SDL_SCANCODE_LCTRL]) - nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, down); - else nk_input_key(ctx, NK_KEY_LEFT, down); - } else if (sym == SDLK_RIGHT) { - if (state[SDL_SCANCODE_LCTRL]) - nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, down); - else nk_input_key(ctx, NK_KEY_RIGHT, down); - } else return 0; - return 1; - } else if (evt->type == SDL_MOUSEBUTTONDOWN || evt->type == SDL_MOUSEBUTTONUP) { - /* mouse button */ - int down = evt->type == SDL_MOUSEBUTTONDOWN; - const int x = evt->button.x, y = evt->button.y; - if (evt->button.button == SDL_BUTTON_LEFT) - nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down); - if (evt->button.button == SDL_BUTTON_MIDDLE) - nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down); - if (evt->button.button == SDL_BUTTON_RIGHT) - nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down); - else return 0; - return 1; - } else if (evt->type == SDL_MOUSEMOTION) { - if (ctx->input.mouse.grabbed) { - int x = (int)ctx->input.mouse.prev.x, y = (int)ctx->input.mouse.prev.y; - nk_input_motion(ctx, x + evt->motion.xrel, y + evt->motion.yrel); - } else nk_input_motion(ctx, evt->motion.x, evt->motion.y); - return 1; - } else if (evt->type == SDL_TEXTINPUT) { - nk_glyph glyph; - memcpy(glyph, evt->text.text, NK_UTF_SIZE); - nk_input_glyph(ctx, glyph); - return 1; - } else if (evt->type == SDL_MOUSEWHEEL) { - nk_input_scroll(ctx,(float)evt->wheel.y); - return 1; - } - return 0; -} - -NK_API -void nk_sdl_shutdown(void) -{ - struct nk_sdl_device *dev = &sdl.ogl; - nk_font_atlas_clear(&sdl.atlas); - nk_free(&sdl.ctx); - glDeleteTextures(1, &dev->font_tex); - nk_buffer_free(&dev->cmds); - memset(&sdl, 0, sizeof(sdl)); -} - -#endif diff --git a/deps/nuklear/demo/sdl_opengl3/main.c b/deps/nuklear/demo/sdl_opengl3/main.c deleted file mode 100644 index aee4f827..00000000 --- a/deps/nuklear/demo/sdl_opengl3/main.c +++ /dev/null @@ -1,195 +0,0 @@ -/* nuklear - v1.17 - public domain */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define NK_INCLUDE_FIXED_TYPES -#define NK_INCLUDE_STANDARD_IO -#define NK_INCLUDE_STANDARD_VARARGS -#define NK_INCLUDE_DEFAULT_ALLOCATOR -#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT -#define NK_INCLUDE_FONT_BAKING -#define NK_INCLUDE_DEFAULT_FONT -#define NK_IMPLEMENTATION -#define NK_SDL_GL3_IMPLEMENTATION -#include "../../nuklear.h" -#include "nuklear_sdl_gl3.h" - -#define WINDOW_WIDTH 800 -#define WINDOW_HEIGHT 600 - -#define MAX_VERTEX_MEMORY 512 * 1024 -#define MAX_ELEMENT_MEMORY 128 * 1024 - -#define UNUSED(a) (void)a -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) < (b) ? (b) : (a)) -#define LEN(a) (sizeof(a)/sizeof(a)[0]) - -/* =============================================================== - * - * EXAMPLE - * - * ===============================================================*/ -/* This are some code examples to provide a small overview of what can be - * done with this library. To try out an example uncomment the include - * and the corresponding function. */ -/*#include "../style.c"*/ -/*#include "../calculator.c"*/ -/*#include "../overview.c"*/ -/*#include "../node_editor.c"*/ - -/* =============================================================== - * - * DEMO - * - * ===============================================================*/ -int -main(int argc, char* argv[]) -{ - /* Platform */ - SDL_Window *win; - SDL_GLContext glContext; - struct nk_color background; - int win_width, win_height; - int running = 1; - - /* GUI */ - struct nk_context *ctx; - - /* SDL setup */ - SDL_SetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED, "0"); - SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_EVENTS); - SDL_GL_SetAttribute (SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); - SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - win = SDL_CreateWindow("Demo", - SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN|SDL_WINDOW_ALLOW_HIGHDPI); - glContext = SDL_GL_CreateContext(win); - SDL_GetWindowSize(win, &win_width, &win_height); - - /* OpenGL setup */ - glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); - glewExperimental = 1; - if (glewInit() != GLEW_OK) { - fprintf(stderr, "Failed to setup GLEW\n"); - exit(1); - } - - ctx = nk_sdl_init(win); - /* Load Fonts: if none of these are loaded a default font will be used */ - /* Load Cursor: if you uncomment cursor loading please hide the cursor */ - {struct nk_font_atlas *atlas; - nk_sdl_font_stash_begin(&atlas); - /*struct nk_font *droid = nk_font_atlas_add_from_file(atlas, "../../../extra_font/DroidSans.ttf", 14, 0);*/ - /*struct nk_font *roboto = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Roboto-Regular.ttf", 16, 0);*/ - /*struct nk_font *future = nk_font_atlas_add_from_file(atlas, "../../../extra_font/kenvector_future_thin.ttf", 13, 0);*/ - /*struct nk_font *clean = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyClean.ttf", 12, 0);*/ - /*struct nk_font *tiny = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyTiny.ttf", 10, 0);*/ - /*struct nk_font *cousine = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Cousine-Regular.ttf", 13, 0);*/ - nk_sdl_font_stash_end(); - /*nk_style_load_all_cursors(ctx, atlas->cursors);*/ - /*nk_style_set_font(ctx, &roboto->handle)*/;} - - /* style.c */ - /*set_style(ctx, THEME_WHITE);*/ - /*set_style(ctx, THEME_RED);*/ - /*set_style(ctx, THEME_BLUE);*/ - /*set_style(ctx, THEME_DARK);*/ - - background = nk_rgb(28,48,62); - while (running) - { - /* Input */ - SDL_Event evt; - nk_input_begin(ctx); - while (SDL_PollEvent(&evt)) { - if (evt.type == SDL_QUIT) goto cleanup; - nk_sdl_handle_event(&evt); - } - nk_input_end(ctx); - - - /* GUI */ - if (nk_begin(ctx, "Demo", nk_rect(50, 50, 200, 200), - NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE| - NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE)) - { - nk_menubar_begin(ctx); - nk_layout_row_begin(ctx, NK_STATIC, 25, 2); - nk_layout_row_push(ctx, 45); - if (nk_menu_begin_label(ctx, "FILE", NK_TEXT_LEFT, nk_vec2(120, 200))) { - nk_layout_row_dynamic(ctx, 30, 1); - nk_menu_item_label(ctx, "OPEN", NK_TEXT_LEFT); - nk_menu_item_label(ctx, "CLOSE", NK_TEXT_LEFT); - nk_menu_end(ctx); - } - nk_layout_row_push(ctx, 45); - if (nk_menu_begin_label(ctx, "EDIT", NK_TEXT_LEFT, nk_vec2(120, 200))) { - nk_layout_row_dynamic(ctx, 30, 1); - nk_menu_item_label(ctx, "COPY", NK_TEXT_LEFT); - nk_menu_item_label(ctx, "CUT", NK_TEXT_LEFT); - nk_menu_item_label(ctx, "PASTE", NK_TEXT_LEFT); - nk_menu_end(ctx); - } - nk_layout_row_end(ctx); - nk_menubar_end(ctx); - - enum {EASY, HARD}; - static int op = EASY; - static int property = 20; - nk_layout_row_static(ctx, 30, 80, 1); - if (nk_button_label(ctx, "button")) - fprintf(stdout, "button pressed\n"); - nk_layout_row_dynamic(ctx, 30, 2); - if (nk_option_label(ctx, "easy", op == EASY)) op = EASY; - if (nk_option_label(ctx, "hard", op == HARD)) op = HARD; - nk_layout_row_dynamic(ctx, 25, 1); - nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1); - } - nk_end(ctx); - - /* -------------- EXAMPLES ---------------- */ - /*calculator(ctx);*/ - /*overview(ctx);*/ - /*node_editor(ctx);*/ - /* ----------------------------------------- */ - - /* Draw */ - {float bg[4]; - nk_color_fv(bg, background); - SDL_GetWindowSize(win, &win_width, &win_height); - glViewport(0, 0, win_width, win_height); - glClear(GL_COLOR_BUFFER_BIT); - glClearColor(bg[0], bg[1], bg[2], bg[3]); - /* IMPORTANT: `nk_sdl_render` modifies some global OpenGL state - * with blending, scissor, face culling, depth test and viewport and - * defaults everything back into a default state. - * Make sure to either a.) save and restore or b.) reset your own state after - * rendering the UI. */ - nk_sdl_render(NK_ANTI_ALIASING_ON, MAX_VERTEX_MEMORY, MAX_ELEMENT_MEMORY); - SDL_GL_SwapWindow(win);} - } - -cleanup: - nk_sdl_shutdown(); - SDL_GL_DeleteContext(glContext); - SDL_DestroyWindow(win); - SDL_Quit(); - return 0; -} - diff --git a/deps/nuklear/demo/sdl_opengl3/nuklear_sdl_gl3.h b/deps/nuklear/demo/sdl_opengl3/nuklear_sdl_gl3.h deleted file mode 100644 index 17c0899d..00000000 --- a/deps/nuklear/demo/sdl_opengl3/nuklear_sdl_gl3.h +++ /dev/null @@ -1,437 +0,0 @@ -/* - * Nuklear - v1.17 - public domain - * no warrenty implied; use at your own risk. - * authored from 2015-2016 by Micha Mettke - */ -/* - * ============================================================== - * - * API - * - * =============================================================== - */ -#ifndef NK_SDL_GL3_H_ -#define NK_SDL_GL3_H_ - -#include -#include - -NK_API struct nk_context* nk_sdl_init(SDL_Window *win); -NK_API void nk_sdl_font_stash_begin(struct nk_font_atlas **atlas); -NK_API void nk_sdl_font_stash_end(void); -NK_API int nk_sdl_handle_event(SDL_Event *evt); -NK_API void nk_sdl_render(enum nk_anti_aliasing , int max_vertex_buffer, int max_element_buffer); -NK_API void nk_sdl_shutdown(void); -NK_API void nk_sdl_device_destroy(void); -NK_API void nk_sdl_device_create(void); - -#endif - -/* - * ============================================================== - * - * IMPLEMENTATION - * - * =============================================================== - */ -#ifdef NK_SDL_GL3_IMPLEMENTATION - -#include - -struct nk_sdl_device { - struct nk_buffer cmds; - struct nk_draw_null_texture null; - GLuint vbo, vao, ebo; - GLuint prog; - GLuint vert_shdr; - GLuint frag_shdr; - GLint attrib_pos; - GLint attrib_uv; - GLint attrib_col; - GLint uniform_tex; - GLint uniform_proj; - GLuint font_tex; -}; - -struct nk_sdl_vertex { - float position[2]; - float uv[2]; - nk_byte col[4]; -}; - -static struct nk_sdl { - SDL_Window *win; - struct nk_sdl_device ogl; - struct nk_context ctx; - struct nk_font_atlas atlas; -} sdl; - -#ifdef __APPLE__ - #define NK_SHADER_VERSION "#version 150\n" -#else - #define NK_SHADER_VERSION "#version 300 es\n" -#endif -NK_API void -nk_sdl_device_create(void) -{ - GLint status; - static const GLchar *vertex_shader = - NK_SHADER_VERSION - "uniform mat4 ProjMtx;\n" - "in vec2 Position;\n" - "in vec2 TexCoord;\n" - "in vec4 Color;\n" - "out vec2 Frag_UV;\n" - "out vec4 Frag_Color;\n" - "void main() {\n" - " Frag_UV = TexCoord;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy, 0, 1);\n" - "}\n"; - static const GLchar *fragment_shader = - NK_SHADER_VERSION - "precision mediump float;\n" - "uniform sampler2D Texture;\n" - "in vec2 Frag_UV;\n" - "in vec4 Frag_Color;\n" - "out vec4 Out_Color;\n" - "void main(){\n" - " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" - "}\n"; - - struct nk_sdl_device *dev = &sdl.ogl; - nk_buffer_init_default(&dev->cmds); - dev->prog = glCreateProgram(); - dev->vert_shdr = glCreateShader(GL_VERTEX_SHADER); - dev->frag_shdr = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(dev->vert_shdr, 1, &vertex_shader, 0); - glShaderSource(dev->frag_shdr, 1, &fragment_shader, 0); - glCompileShader(dev->vert_shdr); - glCompileShader(dev->frag_shdr); - glGetShaderiv(dev->vert_shdr, GL_COMPILE_STATUS, &status); - assert(status == GL_TRUE); - glGetShaderiv(dev->frag_shdr, GL_COMPILE_STATUS, &status); - assert(status == GL_TRUE); - glAttachShader(dev->prog, dev->vert_shdr); - glAttachShader(dev->prog, dev->frag_shdr); - glLinkProgram(dev->prog); - glGetProgramiv(dev->prog, GL_LINK_STATUS, &status); - assert(status == GL_TRUE); - - dev->uniform_tex = glGetUniformLocation(dev->prog, "Texture"); - dev->uniform_proj = glGetUniformLocation(dev->prog, "ProjMtx"); - dev->attrib_pos = glGetAttribLocation(dev->prog, "Position"); - dev->attrib_uv = glGetAttribLocation(dev->prog, "TexCoord"); - dev->attrib_col = glGetAttribLocation(dev->prog, "Color"); - - { - /* buffer setup */ - GLsizei vs = sizeof(struct nk_sdl_vertex); - size_t vp = offsetof(struct nk_sdl_vertex, position); - size_t vt = offsetof(struct nk_sdl_vertex, uv); - size_t vc = offsetof(struct nk_sdl_vertex, col); - - glGenBuffers(1, &dev->vbo); - glGenBuffers(1, &dev->ebo); - glGenVertexArrays(1, &dev->vao); - - glBindVertexArray(dev->vao); - glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); - - glEnableVertexAttribArray((GLuint)dev->attrib_pos); - glEnableVertexAttribArray((GLuint)dev->attrib_uv); - glEnableVertexAttribArray((GLuint)dev->attrib_col); - - glVertexAttribPointer((GLuint)dev->attrib_pos, 2, GL_FLOAT, GL_FALSE, vs, (void*)vp); - glVertexAttribPointer((GLuint)dev->attrib_uv, 2, GL_FLOAT, GL_FALSE, vs, (void*)vt); - glVertexAttribPointer((GLuint)dev->attrib_col, 4, GL_UNSIGNED_BYTE, GL_TRUE, vs, (void*)vc); - } - - glBindTexture(GL_TEXTURE_2D, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindVertexArray(0); -} - -NK_INTERN void -nk_sdl_device_upload_atlas(const void *image, int width, int height) -{ - struct nk_sdl_device *dev = &sdl.ogl; - glGenTextures(1, &dev->font_tex); - glBindTexture(GL_TEXTURE_2D, dev->font_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, image); -} - -NK_API void -nk_sdl_device_destroy(void) -{ - struct nk_sdl_device *dev = &sdl.ogl; - glDetachShader(dev->prog, dev->vert_shdr); - glDetachShader(dev->prog, dev->frag_shdr); - glDeleteShader(dev->vert_shdr); - glDeleteShader(dev->frag_shdr); - glDeleteProgram(dev->prog); - glDeleteTextures(1, &dev->font_tex); - glDeleteBuffers(1, &dev->vbo); - glDeleteBuffers(1, &dev->ebo); - nk_buffer_free(&dev->cmds); -} - -NK_API void -nk_sdl_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_buffer) -{ - struct nk_sdl_device *dev = &sdl.ogl; - int width, height; - int display_width, display_height; - struct nk_vec2 scale; - GLfloat ortho[4][4] = { - {2.0f, 0.0f, 0.0f, 0.0f}, - {0.0f,-2.0f, 0.0f, 0.0f}, - {0.0f, 0.0f,-1.0f, 0.0f}, - {-1.0f,1.0f, 0.0f, 1.0f}, - }; - SDL_GetWindowSize(sdl.win, &width, &height); - SDL_GL_GetDrawableSize(sdl.win, &display_width, &display_height); - ortho[0][0] /= (GLfloat)width; - ortho[1][1] /= (GLfloat)height; - - scale.x = (float)display_width/(float)width; - scale.y = (float)display_height/(float)height; - - /* setup global state */ - glViewport(0,0,display_width,display_height); - glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glActiveTexture(GL_TEXTURE0); - - /* setup program */ - glUseProgram(dev->prog); - glUniform1i(dev->uniform_tex, 0); - glUniformMatrix4fv(dev->uniform_proj, 1, GL_FALSE, &ortho[0][0]); - { - /* convert from command queue into draw list and draw to screen */ - const struct nk_draw_command *cmd; - void *vertices, *elements; - const nk_draw_index *offset = NULL; - - /* allocate vertex and element buffer */ - glBindVertexArray(dev->vao); - glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); - - glBufferData(GL_ARRAY_BUFFER, max_vertex_buffer, NULL, GL_STREAM_DRAW); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, max_element_buffer, NULL, GL_STREAM_DRAW); - - /* load vertices/elements directly into vertex/element buffer */ - vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - elements = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); - { - /* fill convert configuration */ - struct nk_convert_config config; - static const struct nk_draw_vertex_layout_element vertex_layout[] = { - {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_sdl_vertex, position)}, - {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_sdl_vertex, uv)}, - {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_sdl_vertex, col)}, - {NK_VERTEX_LAYOUT_END} - }; - NK_MEMSET(&config, 0, sizeof(config)); - config.vertex_layout = vertex_layout; - config.vertex_size = sizeof(struct nk_sdl_vertex); - config.vertex_alignment = NK_ALIGNOF(struct nk_sdl_vertex); - config.null = dev->null; - config.circle_segment_count = 22; - config.curve_segment_count = 22; - config.arc_segment_count = 22; - config.global_alpha = 1.0f; - config.shape_AA = AA; - config.line_AA = AA; - - /* setup buffers to load vertices and elements */ - {struct nk_buffer vbuf, ebuf; - nk_buffer_init_fixed(&vbuf, vertices, (nk_size)max_vertex_buffer); - nk_buffer_init_fixed(&ebuf, elements, (nk_size)max_element_buffer); - nk_convert(&sdl.ctx, &dev->cmds, &vbuf, &ebuf, &config);} - } - glUnmapBuffer(GL_ARRAY_BUFFER); - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - - /* iterate over and execute each draw command */ - nk_draw_foreach(cmd, &sdl.ctx, &dev->cmds) { - if (!cmd->elem_count) continue; - glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id); - glScissor((GLint)(cmd->clip_rect.x * scale.x), - (GLint)((height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * scale.y), - (GLint)(cmd->clip_rect.w * scale.x), - (GLint)(cmd->clip_rect.h * scale.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset); - offset += cmd->elem_count; - } - nk_clear(&sdl.ctx); - } - - glUseProgram(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindVertexArray(0); - glDisable(GL_BLEND); - glDisable(GL_SCISSOR_TEST); -} - -static void -nk_sdl_clipbard_paste(nk_handle usr, struct nk_text_edit *edit) -{ - const char *text = SDL_GetClipboardText(); - if (text) nk_textedit_paste(edit, text, nk_strlen(text)); - (void)usr; -} - -static void -nk_sdl_clipbard_copy(nk_handle usr, const char *text, int len) -{ - char *str = 0; - (void)usr; - if (!len) return; - str = (char*)malloc((size_t)len+1); - if (!str) return; - memcpy(str, text, (size_t)len); - str[len] = '\0'; - SDL_SetClipboardText(str); - free(str); -} - -NK_API struct nk_context* -nk_sdl_init(SDL_Window *win) -{ - sdl.win = win; - nk_init_default(&sdl.ctx, 0); - sdl.ctx.clip.copy = nk_sdl_clipbard_copy; - sdl.ctx.clip.paste = nk_sdl_clipbard_paste; - sdl.ctx.clip.userdata = nk_handle_ptr(0); - nk_sdl_device_create(); - return &sdl.ctx; -} - -NK_API void -nk_sdl_font_stash_begin(struct nk_font_atlas **atlas) -{ - nk_font_atlas_init_default(&sdl.atlas); - nk_font_atlas_begin(&sdl.atlas); - *atlas = &sdl.atlas; -} - -NK_API void -nk_sdl_font_stash_end(void) -{ - const void *image; int w, h; - image = nk_font_atlas_bake(&sdl.atlas, &w, &h, NK_FONT_ATLAS_RGBA32); - nk_sdl_device_upload_atlas(image, w, h); - nk_font_atlas_end(&sdl.atlas, nk_handle_id((int)sdl.ogl.font_tex), &sdl.ogl.null); - if (sdl.atlas.default_font) - nk_style_set_font(&sdl.ctx, &sdl.atlas.default_font->handle); - -} - -NK_API int -nk_sdl_handle_event(SDL_Event *evt) -{ - struct nk_context *ctx = &sdl.ctx; - if (evt->type == SDL_KEYUP || evt->type == SDL_KEYDOWN) { - /* key events */ - int down = evt->type == SDL_KEYDOWN; - const Uint8* state = SDL_GetKeyboardState(0); - SDL_Keycode sym = evt->key.keysym.sym; - if (sym == SDLK_RSHIFT || sym == SDLK_LSHIFT) - nk_input_key(ctx, NK_KEY_SHIFT, down); - else if (sym == SDLK_DELETE) - nk_input_key(ctx, NK_KEY_DEL, down); - else if (sym == SDLK_RETURN) - nk_input_key(ctx, NK_KEY_ENTER, down); - else if (sym == SDLK_TAB) - nk_input_key(ctx, NK_KEY_TAB, down); - else if (sym == SDLK_BACKSPACE) - nk_input_key(ctx, NK_KEY_BACKSPACE, down); - else if (sym == SDLK_HOME) { - nk_input_key(ctx, NK_KEY_TEXT_START, down); - nk_input_key(ctx, NK_KEY_SCROLL_START, down); - } else if (sym == SDLK_END) { - nk_input_key(ctx, NK_KEY_TEXT_END, down); - nk_input_key(ctx, NK_KEY_SCROLL_END, down); - } else if (sym == SDLK_PAGEDOWN) { - nk_input_key(ctx, NK_KEY_SCROLL_DOWN, down); - } else if (sym == SDLK_PAGEUP) { - nk_input_key(ctx, NK_KEY_SCROLL_UP, down); - } else if (sym == SDLK_z) - nk_input_key(ctx, NK_KEY_TEXT_UNDO, down && state[SDL_SCANCODE_LCTRL]); - else if (sym == SDLK_r) - nk_input_key(ctx, NK_KEY_TEXT_REDO, down && state[SDL_SCANCODE_LCTRL]); - else if (sym == SDLK_c) - nk_input_key(ctx, NK_KEY_COPY, down && state[SDL_SCANCODE_LCTRL]); - else if (sym == SDLK_v) - nk_input_key(ctx, NK_KEY_PASTE, down && state[SDL_SCANCODE_LCTRL]); - else if (sym == SDLK_x) - nk_input_key(ctx, NK_KEY_CUT, down && state[SDL_SCANCODE_LCTRL]); - else if (sym == SDLK_b) - nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down && state[SDL_SCANCODE_LCTRL]); - else if (sym == SDLK_e) - nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down && state[SDL_SCANCODE_LCTRL]); - else if (sym == SDLK_UP) - nk_input_key(ctx, NK_KEY_UP, down); - else if (sym == SDLK_DOWN) - nk_input_key(ctx, NK_KEY_DOWN, down); - else if (sym == SDLK_LEFT) { - if (state[SDL_SCANCODE_LCTRL]) - nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, down); - else nk_input_key(ctx, NK_KEY_LEFT, down); - } else if (sym == SDLK_RIGHT) { - if (state[SDL_SCANCODE_LCTRL]) - nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, down); - else nk_input_key(ctx, NK_KEY_RIGHT, down); - } else return 0; - return 1; - } else if (evt->type == SDL_MOUSEBUTTONDOWN || evt->type == SDL_MOUSEBUTTONUP) { - /* mouse button */ - int down = evt->type == SDL_MOUSEBUTTONDOWN; - const int x = evt->button.x, y = evt->button.y; - if (evt->button.button == SDL_BUTTON_LEFT) - nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down); - if (evt->button.button == SDL_BUTTON_MIDDLE) - nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down); - if (evt->button.button == SDL_BUTTON_RIGHT) - nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down); - return 1; - } else if (evt->type == SDL_MOUSEMOTION) { - if (ctx->input.mouse.grabbed) { - int x = (int)ctx->input.mouse.prev.x, y = (int)ctx->input.mouse.prev.y; - nk_input_motion(ctx, x + evt->motion.xrel, y + evt->motion.yrel); - } else nk_input_motion(ctx, evt->motion.x, evt->motion.y); - return 1; - } else if (evt->type == SDL_TEXTINPUT) { - nk_glyph glyph; - memcpy(glyph, evt->text.text, NK_UTF_SIZE); - nk_input_glyph(ctx, glyph); - return 1; - } else if (evt->type == SDL_MOUSEWHEEL) { - nk_input_scroll(ctx,(float)evt->wheel.y); - return 1; - } - return 0; -} - -NK_API -void nk_sdl_shutdown(void) -{ - nk_font_atlas_clear(&sdl.atlas); - nk_free(&sdl.ctx); - nk_sdl_device_destroy(); - memset(&sdl, 0, sizeof(sdl)); -} - -#endif diff --git a/deps/nuklear/demo/style.c b/deps/nuklear/demo/style.c deleted file mode 100644 index 8cea1521..00000000 --- a/deps/nuklear/demo/style.c +++ /dev/null @@ -1,132 +0,0 @@ -enum theme {THEME_BLACK, THEME_WHITE, THEME_RED, THEME_BLUE, THEME_DARK}; - -void -set_style(struct nk_context *ctx, enum theme theme) -{ - struct nk_color table[NK_COLOR_COUNT]; - if (theme == THEME_WHITE) { - table[NK_COLOR_TEXT] = nk_rgba(70, 70, 70, 255); - table[NK_COLOR_WINDOW] = nk_rgba(175, 175, 175, 255); - table[NK_COLOR_HEADER] = nk_rgba(175, 175, 175, 255); - table[NK_COLOR_BORDER] = nk_rgba(0, 0, 0, 255); - table[NK_COLOR_BUTTON] = nk_rgba(185, 185, 185, 255); - table[NK_COLOR_BUTTON_HOVER] = nk_rgba(170, 170, 170, 255); - table[NK_COLOR_BUTTON_ACTIVE] = nk_rgba(160, 160, 160, 255); - table[NK_COLOR_TOGGLE] = nk_rgba(150, 150, 150, 255); - table[NK_COLOR_TOGGLE_HOVER] = nk_rgba(120, 120, 120, 255); - table[NK_COLOR_TOGGLE_CURSOR] = nk_rgba(175, 175, 175, 255); - table[NK_COLOR_SELECT] = nk_rgba(190, 190, 190, 255); - table[NK_COLOR_SELECT_ACTIVE] = nk_rgba(175, 175, 175, 255); - table[NK_COLOR_SLIDER] = nk_rgba(190, 190, 190, 255); - table[NK_COLOR_SLIDER_CURSOR] = nk_rgba(80, 80, 80, 255); - table[NK_COLOR_SLIDER_CURSOR_HOVER] = nk_rgba(70, 70, 70, 255); - table[NK_COLOR_SLIDER_CURSOR_ACTIVE] = nk_rgba(60, 60, 60, 255); - table[NK_COLOR_PROPERTY] = nk_rgba(175, 175, 175, 255); - table[NK_COLOR_EDIT] = nk_rgba(150, 150, 150, 255); - table[NK_COLOR_EDIT_CURSOR] = nk_rgba(0, 0, 0, 255); - table[NK_COLOR_COMBO] = nk_rgba(175, 175, 175, 255); - table[NK_COLOR_CHART] = nk_rgba(160, 160, 160, 255); - table[NK_COLOR_CHART_COLOR] = nk_rgba(45, 45, 45, 255); - table[NK_COLOR_CHART_COLOR_HIGHLIGHT] = nk_rgba( 255, 0, 0, 255); - table[NK_COLOR_SCROLLBAR] = nk_rgba(180, 180, 180, 255); - table[NK_COLOR_SCROLLBAR_CURSOR] = nk_rgba(140, 140, 140, 255); - table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgba(150, 150, 150, 255); - table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgba(160, 160, 160, 255); - table[NK_COLOR_TAB_HEADER] = nk_rgba(180, 180, 180, 255); - nk_style_from_table(ctx, table); - } else if (theme == THEME_RED) { - table[NK_COLOR_TEXT] = nk_rgba(190, 190, 190, 255); - table[NK_COLOR_WINDOW] = nk_rgba(30, 33, 40, 215); - table[NK_COLOR_HEADER] = nk_rgba(181, 45, 69, 220); - table[NK_COLOR_BORDER] = nk_rgba(51, 55, 67, 255); - table[NK_COLOR_BUTTON] = nk_rgba(181, 45, 69, 255); - table[NK_COLOR_BUTTON_HOVER] = nk_rgba(190, 50, 70, 255); - table[NK_COLOR_BUTTON_ACTIVE] = nk_rgba(195, 55, 75, 255); - table[NK_COLOR_TOGGLE] = nk_rgba(51, 55, 67, 255); - table[NK_COLOR_TOGGLE_HOVER] = nk_rgba(45, 60, 60, 255); - table[NK_COLOR_TOGGLE_CURSOR] = nk_rgba(181, 45, 69, 255); - table[NK_COLOR_SELECT] = nk_rgba(51, 55, 67, 255); - table[NK_COLOR_SELECT_ACTIVE] = nk_rgba(181, 45, 69, 255); - table[NK_COLOR_SLIDER] = nk_rgba(51, 55, 67, 255); - table[NK_COLOR_SLIDER_CURSOR] = nk_rgba(181, 45, 69, 255); - table[NK_COLOR_SLIDER_CURSOR_HOVER] = nk_rgba(186, 50, 74, 255); - table[NK_COLOR_SLIDER_CURSOR_ACTIVE] = nk_rgba(191, 55, 79, 255); - table[NK_COLOR_PROPERTY] = nk_rgba(51, 55, 67, 255); - table[NK_COLOR_EDIT] = nk_rgba(51, 55, 67, 225); - table[NK_COLOR_EDIT_CURSOR] = nk_rgba(190, 190, 190, 255); - table[NK_COLOR_COMBO] = nk_rgba(51, 55, 67, 255); - table[NK_COLOR_CHART] = nk_rgba(51, 55, 67, 255); - table[NK_COLOR_CHART_COLOR] = nk_rgba(170, 40, 60, 255); - table[NK_COLOR_CHART_COLOR_HIGHLIGHT] = nk_rgba( 255, 0, 0, 255); - table[NK_COLOR_SCROLLBAR] = nk_rgba(30, 33, 40, 255); - table[NK_COLOR_SCROLLBAR_CURSOR] = nk_rgba(64, 84, 95, 255); - table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgba(70, 90, 100, 255); - table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgba(75, 95, 105, 255); - table[NK_COLOR_TAB_HEADER] = nk_rgba(181, 45, 69, 220); - nk_style_from_table(ctx, table); - } else if (theme == THEME_BLUE) { - table[NK_COLOR_TEXT] = nk_rgba(20, 20, 20, 255); - table[NK_COLOR_WINDOW] = nk_rgba(202, 212, 214, 215); - table[NK_COLOR_HEADER] = nk_rgba(137, 182, 224, 220); - table[NK_COLOR_BORDER] = nk_rgba(140, 159, 173, 255); - table[NK_COLOR_BUTTON] = nk_rgba(137, 182, 224, 255); - table[NK_COLOR_BUTTON_HOVER] = nk_rgba(142, 187, 229, 255); - table[NK_COLOR_BUTTON_ACTIVE] = nk_rgba(147, 192, 234, 255); - table[NK_COLOR_TOGGLE] = nk_rgba(177, 210, 210, 255); - table[NK_COLOR_TOGGLE_HOVER] = nk_rgba(182, 215, 215, 255); - table[NK_COLOR_TOGGLE_CURSOR] = nk_rgba(137, 182, 224, 255); - table[NK_COLOR_SELECT] = nk_rgba(177, 210, 210, 255); - table[NK_COLOR_SELECT_ACTIVE] = nk_rgba(137, 182, 224, 255); - table[NK_COLOR_SLIDER] = nk_rgba(177, 210, 210, 255); - table[NK_COLOR_SLIDER_CURSOR] = nk_rgba(137, 182, 224, 245); - table[NK_COLOR_SLIDER_CURSOR_HOVER] = nk_rgba(142, 188, 229, 255); - table[NK_COLOR_SLIDER_CURSOR_ACTIVE] = nk_rgba(147, 193, 234, 255); - table[NK_COLOR_PROPERTY] = nk_rgba(210, 210, 210, 255); - table[NK_COLOR_EDIT] = nk_rgba(210, 210, 210, 225); - table[NK_COLOR_EDIT_CURSOR] = nk_rgba(20, 20, 20, 255); - table[NK_COLOR_COMBO] = nk_rgba(210, 210, 210, 255); - table[NK_COLOR_CHART] = nk_rgba(210, 210, 210, 255); - table[NK_COLOR_CHART_COLOR] = nk_rgba(137, 182, 224, 255); - table[NK_COLOR_CHART_COLOR_HIGHLIGHT] = nk_rgba( 255, 0, 0, 255); - table[NK_COLOR_SCROLLBAR] = nk_rgba(190, 200, 200, 255); - table[NK_COLOR_SCROLLBAR_CURSOR] = nk_rgba(64, 84, 95, 255); - table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgba(70, 90, 100, 255); - table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgba(75, 95, 105, 255); - table[NK_COLOR_TAB_HEADER] = nk_rgba(156, 193, 220, 255); - nk_style_from_table(ctx, table); - } else if (theme == THEME_DARK) { - table[NK_COLOR_TEXT] = nk_rgba(210, 210, 210, 255); - table[NK_COLOR_WINDOW] = nk_rgba(57, 67, 71, 215); - table[NK_COLOR_HEADER] = nk_rgba(51, 51, 56, 220); - table[NK_COLOR_BORDER] = nk_rgba(46, 46, 46, 255); - table[NK_COLOR_BUTTON] = nk_rgba(48, 83, 111, 255); - table[NK_COLOR_BUTTON_HOVER] = nk_rgba(58, 93, 121, 255); - table[NK_COLOR_BUTTON_ACTIVE] = nk_rgba(63, 98, 126, 255); - table[NK_COLOR_TOGGLE] = nk_rgba(50, 58, 61, 255); - table[NK_COLOR_TOGGLE_HOVER] = nk_rgba(45, 53, 56, 255); - table[NK_COLOR_TOGGLE_CURSOR] = nk_rgba(48, 83, 111, 255); - table[NK_COLOR_SELECT] = nk_rgba(57, 67, 61, 255); - table[NK_COLOR_SELECT_ACTIVE] = nk_rgba(48, 83, 111, 255); - table[NK_COLOR_SLIDER] = nk_rgba(50, 58, 61, 255); - table[NK_COLOR_SLIDER_CURSOR] = nk_rgba(48, 83, 111, 245); - table[NK_COLOR_SLIDER_CURSOR_HOVER] = nk_rgba(53, 88, 116, 255); - table[NK_COLOR_SLIDER_CURSOR_ACTIVE] = nk_rgba(58, 93, 121, 255); - table[NK_COLOR_PROPERTY] = nk_rgba(50, 58, 61, 255); - table[NK_COLOR_EDIT] = nk_rgba(50, 58, 61, 225); - table[NK_COLOR_EDIT_CURSOR] = nk_rgba(210, 210, 210, 255); - table[NK_COLOR_COMBO] = nk_rgba(50, 58, 61, 255); - table[NK_COLOR_CHART] = nk_rgba(50, 58, 61, 255); - table[NK_COLOR_CHART_COLOR] = nk_rgba(48, 83, 111, 255); - table[NK_COLOR_CHART_COLOR_HIGHLIGHT] = nk_rgba(255, 0, 0, 255); - table[NK_COLOR_SCROLLBAR] = nk_rgba(50, 58, 61, 255); - table[NK_COLOR_SCROLLBAR_CURSOR] = nk_rgba(48, 83, 111, 255); - table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgba(53, 88, 116, 255); - table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgba(58, 93, 121, 255); - table[NK_COLOR_TAB_HEADER] = nk_rgba(48, 83, 111, 255); - nk_style_from_table(ctx, table); - } else { - nk_style_default(ctx); - } -} - - diff --git a/deps/nuklear/demo/x11/main.c b/deps/nuklear/demo/x11/main.c deleted file mode 100644 index 8f4b12c7..00000000 --- a/deps/nuklear/demo/x11/main.c +++ /dev/null @@ -1,203 +0,0 @@ -/* nuklear - v1.17 - public domain */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NK_INCLUDE_FIXED_TYPES -#define NK_INCLUDE_STANDARD_IO -#define NK_INCLUDE_STANDARD_VARARGS -#define NK_INCLUDE_DEFAULT_ALLOCATOR -#define NK_IMPLEMENTATION -#define NK_XLIB_IMPLEMENTATION -#include "../../nuklear.h" -#include "nuklear_xlib.h" - -#define DTIME 20 -#define WINDOW_WIDTH 800 -#define WINDOW_HEIGHT 600 - -#define UNUSED(a) (void)a -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) < (b) ? (b) : (a)) -#define LEN(a) (sizeof(a)/sizeof(a)[0]) - -typedef struct XWindow XWindow; -struct XWindow { - Display *dpy; - Window root; - Visual *vis; - Colormap cmap; - XWindowAttributes attr; - XSetWindowAttributes swa; - Window win; - int screen; - XFont *font; - unsigned int width; - unsigned int height; -}; - -static void -die(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fputs("\n", stderr); - exit(EXIT_FAILURE); -} - -static void* -xcalloc(size_t siz, size_t n) -{ - void *ptr = calloc(siz, n); - if (!ptr) die("Out of memory\n"); - return ptr; -} - -static long -timestamp(void) -{ - struct timeval tv; - if (gettimeofday(&tv, NULL) < 0) return 0; - return (long)((long)tv.tv_sec * 1000 + (long)tv.tv_usec/1000); -} - -static void -sleep_for(long t) -{ - struct timespec req; - const time_t sec = (int)(t/1000); - const long ms = t - (sec * 1000); - req.tv_sec = sec; - req.tv_nsec = ms * 1000000L; - while(-1 == nanosleep(&req, &req)); -} - -/* =============================================================== - * - * EXAMPLE - * - * ===============================================================*/ -/* This are some code examples to provide a small overview of what can be - * done with this library. To try out an example uncomment the include - * and the corresponding function. */ -/*#include "../style.c"*/ -/*#include "../calculator.c"*/ -#include "../overview.c" -#include "../node_editor.c" - -/* =============================================================== - * - * DEMO - * - * ===============================================================*/ -int -main(void) -{ - long dt; - long started; - int running = 1; - XWindow xw; - struct nk_context *ctx; - - /* X11 */ - memset(&xw, 0, sizeof xw); - xw.dpy = XOpenDisplay(NULL); - if (!xw.dpy) die("Could not open a display; perhaps $DISPLAY is not set?"); - - xw.root = DefaultRootWindow(xw.dpy); - xw.screen = XDefaultScreen(xw.dpy); - xw.vis = XDefaultVisual(xw.dpy, xw.screen); - xw.cmap = XCreateColormap(xw.dpy,xw.root,xw.vis,AllocNone); - xw.swa.colormap = xw.cmap; - xw.swa.event_mask = - ExposureMask | KeyPressMask | KeyReleaseMask | - ButtonPress | ButtonReleaseMask| ButtonMotionMask | - Button1MotionMask | Button3MotionMask | Button4MotionMask | Button5MotionMask| - PointerMotionMask | KeymapStateMask; - xw.win = XCreateWindow(xw.dpy, xw.root, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, - XDefaultDepth(xw.dpy, xw.screen), InputOutput, - xw.vis, CWEventMask | CWColormap, &xw.swa); - XStoreName(xw.dpy, xw.win, "X11"); - XMapWindow(xw.dpy, xw.win); - XGetWindowAttributes(xw.dpy, xw.win, &xw.attr); - xw.width = (unsigned int)xw.attr.width; - xw.height = (unsigned int)xw.attr.height; - - /* GUI */ - xw.font = nk_xfont_create(xw.dpy, "fixed"); - ctx = nk_xlib_init(xw.font, xw.dpy, xw.screen, xw.win, xw.width, xw.height); - - /* style.c */ - /*set_style(ctx, THEME_WHITE);*/ - /*set_style(ctx, THEME_RED);*/ - /*set_style(ctx, THEME_BLUE);*/ - /*set_style(ctx, THEME_DARK);*/ - - while (running) - { - /* Input */ - XEvent evt; - started = timestamp(); - nk_input_begin(ctx); - while (XCheckWindowEvent(xw.dpy, xw.win, xw.swa.event_mask, &evt)){ - if (XFilterEvent(&evt, xw.win)) continue; - nk_xlib_handle_event(xw.dpy, xw.screen, xw.win, &evt); - } - nk_input_end(ctx); - - /* GUI */ - if (nk_begin(ctx, "Demo", nk_rect(50, 50, 200, 200), - NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE| - NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE)) - { - enum {EASY, HARD}; - static int op = EASY; - static int property = 20; - - nk_layout_row_static(ctx, 30, 80, 1); - if (nk_button_label(ctx, "button")) - fprintf(stdout, "button pressed\n"); - nk_layout_row_dynamic(ctx, 30, 2); - if (nk_option_label(ctx, "easy", op == EASY)) op = EASY; - if (nk_option_label(ctx, "hard", op == HARD)) op = HARD; - nk_layout_row_dynamic(ctx, 25, 1); - nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1); - } - nk_end(ctx); - if (nk_window_is_closed(ctx, "Demo")) break; - - /* -------------- EXAMPLES ---------------- */ - /*calculator(ctx);*/ - overview(ctx); - node_editor(ctx); - /* ----------------------------------------- */ - - /* Draw */ - XClearWindow(xw.dpy, xw.win); - nk_xlib_render(xw.win, nk_rgb(30,30,30)); - XFlush(xw.dpy); - - /* Timing */ - dt = timestamp() - started; - if (dt < DTIME) - sleep_for(DTIME - dt); - } - - nk_xfont_del(xw.dpy, xw.font); - nk_xlib_shutdown(); - XUnmapWindow(xw.dpy, xw.win); - XFreeColormap(xw.dpy, xw.cmap); - XDestroyWindow(xw.dpy, xw.win); - XCloseDisplay(xw.dpy); - return 0; -} - diff --git a/deps/nuklear/demo/x11/nuklear_xlib.h b/deps/nuklear/demo/x11/nuklear_xlib.h deleted file mode 100644 index df66d78a..00000000 --- a/deps/nuklear/demo/x11/nuklear_xlib.h +++ /dev/null @@ -1,693 +0,0 @@ -/* - * Nuklear - v1.17 - public domain - * no warrenty implied; use at your own risk. - * authored from 2015-2016 by Micha Mettke - */ -/* - * ============================================================== - * - * API - * - * =============================================================== - */ -#ifndef NK_XLIB_H_ -#define NK_XLIB_H_ - -#include -/* Font */ -typedef struct XFont XFont; -NK_API XFont* nk_xfont_create(Display *dpy, const char *name); -NK_API void nk_xfont_del(Display *dpy, XFont *font); - -NK_API struct nk_context* nk_xlib_init(XFont *font, Display *dpy, int screen, Window root, unsigned int w, unsigned int h); -NK_API int nk_xlib_handle_event(Display *dpy, int screen, Window win, XEvent *evt); -NK_API void nk_xlib_render(Drawable screen, struct nk_color clear); -NK_API void nk_xlib_shutdown(void); -NK_API void nk_xlib_set_font(XFont *font); - -#endif -/* - * ============================================================== - * - * IMPLEMENTATION - * - * =============================================================== - */ -#ifdef NK_XLIB_IMPLEMENTATION -#include -#include -#include -#include - -typedef struct XSurface XSurface; -struct XFont { - int ascent; - int descent; - int height; - XFontSet set; - XFontStruct *xfont; - struct nk_user_font handle; -}; -struct XSurface { - GC gc; - Display *dpy; - int screen; - Window root; - Drawable drawable; - unsigned int w, h; -}; -static struct { - struct nk_context ctx; - struct XSurface *surf; - Cursor cursor; - Display *dpy; - Window root; -} xlib; - -#ifndef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif -#ifndef MAX -#define MAX(a,b) ((a) < (b) ? (b) : (a)) -#endif - -static unsigned long -nk_color_from_byte(const nk_byte *c) -{ - unsigned long res = 0; - res |= (unsigned long)c[0] << 16; - res |= (unsigned long)c[1] << 8; - res |= (unsigned long)c[2] << 0; - return (res); -} - -static XSurface* -nk_xsurf_create(int screen, unsigned int w, unsigned int h) -{ - XSurface *surface = (XSurface*)calloc(1, sizeof(XSurface)); - surface->w = w; - surface->h = h; - surface->dpy = xlib.dpy; - surface->screen = screen; - surface->root = xlib.root; - surface->gc = XCreateGC(xlib.dpy, xlib.root, 0, NULL); - XSetLineAttributes(xlib.dpy, surface->gc, 1, LineSolid, CapButt, JoinMiter); - surface->drawable = XCreatePixmap(xlib.dpy, xlib.root, w, h, - (unsigned int)DefaultDepth(xlib.dpy, screen)); - return surface; -} - -static void -nk_xsurf_resize(XSurface *surf, unsigned int w, unsigned int h) -{ - if(!surf) return; - if (surf->w == w && surf->h == h) return; - surf->w = w; surf->h = h; - if(surf->drawable) XFreePixmap(surf->dpy, surf->drawable); - surf->drawable = XCreatePixmap(surf->dpy, surf->root, w, h, - (unsigned int)DefaultDepth(surf->dpy, surf->screen)); -} - -static void -nk_xsurf_scissor(XSurface *surf, float x, float y, float w, float h) -{ - XRectangle clip_rect; - clip_rect.x = (short)(x-1); - clip_rect.y = (short)(y-1); - clip_rect.width = (unsigned short)(w+2); - clip_rect.height = (unsigned short)(h+2); - XSetClipRectangles(surf->dpy, surf->gc, 0, 0, &clip_rect, 1, Unsorted); -} - -static void -nk_xsurf_stroke_line(XSurface *surf, short x0, short y0, short x1, - short y1, unsigned int line_thickness, struct nk_color col) -{ - unsigned long c = nk_color_from_byte(&col.r); - XSetForeground(surf->dpy, surf->gc, c); - XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter); - XDrawLine(surf->dpy, surf->drawable, surf->gc, (int)x0, (int)y0, (int)x1, (int)y1); - XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter); -} - -static void -nk_xsurf_stroke_rect(XSurface* surf, short x, short y, unsigned short w, - unsigned short h, unsigned short r, unsigned short line_thickness, struct nk_color col) -{ - unsigned long c = nk_color_from_byte(&col.r); - XSetForeground(surf->dpy, surf->gc, c); - XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter); - if (r == 0) { - XDrawRectangle(surf->dpy, surf->drawable, surf->gc, x, y, w, h); - } else { - short xc = x + r; - short yc = y + r; - short wc = (short)(w - 2 * r); - short hc = (short)(h - 2 * r); - - XDrawLine(surf->dpy, surf->drawable, surf->gc, xc, y, xc+wc, y); - XDrawLine(surf->dpy, surf->drawable, surf->gc, x+w, yc, x+w, yc+hc); - XDrawLine(surf->dpy, surf->drawable, surf->gc, xc, y+h, xc+wc, y+h); - XDrawLine(surf->dpy, surf->drawable, surf->gc, x, yc, x, yc+hc); - - XDrawArc(surf->dpy, surf->drawable, surf->gc, xc + wc - r, y, - (unsigned)r*2, (unsigned)r*2, 0 * 64, 90 * 64); - XDrawArc(surf->dpy, surf->drawable, surf->gc, x, y, - (unsigned)r*2, (unsigned)r*2, 90 * 64, 90 * 64); - XDrawArc(surf->dpy, surf->drawable, surf->gc, x, yc + hc - r, - (unsigned)r*2, (unsigned)2*r, 180 * 64, 90 * 64); - XDrawArc(surf->dpy, surf->drawable, surf->gc, xc + wc - r, yc + hc - r, - (unsigned)r*2, (unsigned)2*r, -90 * 64, 90 * 64); - } - XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter); -} - -static void -nk_xsurf_fill_rect(XSurface* surf, short x, short y, unsigned short w, - unsigned short h, unsigned short r, struct nk_color col) -{ - unsigned long c = nk_color_from_byte(&col.r); - XSetForeground(surf->dpy, surf->gc, c); - if (r == 0) { - XFillRectangle(surf->dpy, surf->drawable, surf->gc, x, y, w, h); - } else { - short xc = x + r; - short yc = y + r; - short wc = (short)(w - 2 * r); - short hc = (short)(h - 2 * r); - - XPoint pnts[12]; - pnts[0].x = x; - pnts[0].y = yc; - pnts[1].x = xc; - pnts[1].y = yc; - pnts[2].x = xc; - pnts[2].y = y; - - pnts[3].x = xc + wc; - pnts[3].y = y; - pnts[4].x = xc + wc; - pnts[4].y = yc; - pnts[5].x = x + w; - pnts[5].y = yc; - - pnts[6].x = x + w; - pnts[6].y = yc + hc; - pnts[7].x = xc + wc; - pnts[7].y = yc + hc; - pnts[8].x = xc + wc; - pnts[8].y = y + h; - - pnts[9].x = xc; - pnts[9].y = y + h; - pnts[10].x = xc; - pnts[10].y = yc + hc; - pnts[11].x = x; - pnts[11].y = yc + hc; - - XFillPolygon(surf->dpy, surf->drawable, surf->gc, pnts, 12, Convex, CoordModeOrigin); - XFillArc(surf->dpy, surf->drawable, surf->gc, xc + wc - r, y, - (unsigned)r*2, (unsigned)r*2, 0 * 64, 90 * 64); - XFillArc(surf->dpy, surf->drawable, surf->gc, x, y, - (unsigned)r*2, (unsigned)r*2, 90 * 64, 90 * 64); - XFillArc(surf->dpy, surf->drawable, surf->gc, x, yc + hc - r, - (unsigned)r*2, (unsigned)2*r, 180 * 64, 90 * 64); - XFillArc(surf->dpy, surf->drawable, surf->gc, xc + wc - r, yc + hc - r, - (unsigned)r*2, (unsigned)2*r, -90 * 64, 90 * 64); - } -} - -static void -nk_xsurf_fill_triangle(XSurface *surf, short x0, short y0, short x1, - short y1, short x2, short y2, struct nk_color col) -{ - XPoint pnts[3]; - unsigned long c = nk_color_from_byte(&col.r); - pnts[0].x = (short)x0; - pnts[0].y = (short)y0; - pnts[1].x = (short)x1; - pnts[1].y = (short)y1; - pnts[2].x = (short)x2; - pnts[2].y = (short)y2; - XSetForeground(surf->dpy, surf->gc, c); - XFillPolygon(surf->dpy, surf->drawable, surf->gc, pnts, 3, Convex, CoordModeOrigin); -} - -static void -nk_xsurf_stroke_triangle(XSurface *surf, short x0, short y0, short x1, - short y1, short x2, short y2, unsigned short line_thickness, struct nk_color col) -{ - XPoint pnts[3]; - unsigned long c = nk_color_from_byte(&col.r); - XSetForeground(surf->dpy, surf->gc, c); - XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter); - XDrawLine(surf->dpy, surf->drawable, surf->gc, x0, y0, x1, y1); - XDrawLine(surf->dpy, surf->drawable, surf->gc, x1, y1, x2, y2); - XDrawLine(surf->dpy, surf->drawable, surf->gc, x2, y2, x0, y0); - XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter); -} - -static void -nk_xsurf_fill_polygon(XSurface *surf, const struct nk_vec2i *pnts, int count, - struct nk_color col) -{ - int i = 0; - #define MAX_POINTS 64 - XPoint xpnts[MAX_POINTS]; - unsigned long c = nk_color_from_byte(&col.r); - XSetForeground(surf->dpy, surf->gc, c); - for (i = 0; i < count && i < MAX_POINTS; ++i) { - xpnts[i].x = pnts[i].x; - xpnts[i].y = pnts[i].y; - } - XFillPolygon(surf->dpy, surf->drawable, surf->gc, xpnts, count, Convex, CoordModeOrigin); - #undef MAX_POINTS -} - -static void -nk_xsurf_stroke_polygon(XSurface *surf, const struct nk_vec2i *pnts, int count, - unsigned short line_thickness, struct nk_color col) -{ - int i = 0; - unsigned long c = nk_color_from_byte(&col.r); - XSetForeground(surf->dpy, surf->gc, c); - XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter); - for (i = 1; i < count; ++i) - XDrawLine(surf->dpy, surf->drawable, surf->gc, pnts[i-1].x, pnts[i-1].y, pnts[i].x, pnts[i].y); - XDrawLine(surf->dpy, surf->drawable, surf->gc, pnts[count-1].x, pnts[count-1].y, pnts[0].x, pnts[0].y); - XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter); -} - -static void -nk_xsurf_stroke_polyline(XSurface *surf, const struct nk_vec2i *pnts, - int count, unsigned short line_thickness, struct nk_color col) -{ - int i = 0; - unsigned long c = nk_color_from_byte(&col.r); - XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter); - XSetForeground(surf->dpy, surf->gc, c); - for (i = 0; i < count-1; ++i) - XDrawLine(surf->dpy, surf->drawable, surf->gc, pnts[i].x, pnts[i].y, pnts[i+1].x, pnts[i+1].y); - XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter); -} - -static void -nk_xsurf_fill_circle(XSurface *surf, short x, short y, unsigned short w, - unsigned short h, struct nk_color col) -{ - unsigned long c = nk_color_from_byte(&col.r); - XSetForeground(surf->dpy, surf->gc, c); - XFillArc(surf->dpy, surf->drawable, surf->gc, (int)x, (int)y, - (unsigned)w, (unsigned)h, 0, 360 * 64); -} - -static void -nk_xsurf_stroke_circle(XSurface *surf, short x, short y, unsigned short w, - unsigned short h, unsigned short line_thickness, struct nk_color col) -{ - unsigned long c = nk_color_from_byte(&col.r); - XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter); - XSetForeground(surf->dpy, surf->gc, c); - XDrawArc(surf->dpy, surf->drawable, surf->gc, (int)x, (int)y, - (unsigned)w, (unsigned)h, 0, 360 * 64); - XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter); -} - -static void -nk_xsurf_stroke_curve(XSurface *surf, struct nk_vec2i p1, - struct nk_vec2i p2, struct nk_vec2i p3, struct nk_vec2i p4, - unsigned int num_segments, unsigned short line_thickness, struct nk_color col) -{ - unsigned int i_step; - float t_step; - struct nk_vec2i last = p1; - - XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter); - num_segments = MAX(num_segments, 1); - t_step = 1.0f/(float)num_segments; - for (i_step = 1; i_step <= num_segments; ++i_step) { - float t = t_step * (float)i_step; - float u = 1.0f - t; - float w1 = u*u*u; - float w2 = 3*u*u*t; - float w3 = 3*u*t*t; - float w4 = t * t *t; - float x = w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x; - float y = w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y; - nk_xsurf_stroke_line(surf, last.x, last.y, (short)x, (short)y, line_thickness,col); - last.x = (short)x; last.y = (short)y; - } - XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter); -} - -static void -nk_xsurf_draw_text(XSurface *surf, short x, short y, unsigned short w, unsigned short h, - const char *text, int len, XFont *font, struct nk_color cbg, struct nk_color cfg) -{ - int tx, ty; - unsigned long bg = nk_color_from_byte(&cbg.r); - unsigned long fg = nk_color_from_byte(&cfg.r); - - XSetForeground(surf->dpy, surf->gc, bg); - XFillRectangle(surf->dpy, surf->drawable, surf->gc, (int)x, (int)y, (unsigned)w, (unsigned)h); - if(!text || !font || !len) return; - - tx = (int)x; - ty = (int)y + font->ascent; - XSetForeground(surf->dpy, surf->gc, fg); - if(font->set) - XmbDrawString(surf->dpy,surf->drawable,font->set,surf->gc,tx,ty,(const char*)text,(int)len); - else - XDrawString(surf->dpy, surf->drawable, surf->gc, tx, ty, (const char*)text, (int)len); -} - -static void -nk_xsurf_clear(XSurface *surf, unsigned long color) -{ - XSetForeground(surf->dpy, surf->gc, color); - XFillRectangle(surf->dpy, surf->drawable, surf->gc, 0, 0, surf->w, surf->h); -} - -static void -nk_xsurf_blit(Drawable target, XSurface *surf, unsigned int w, unsigned int h) -{ - XCopyArea(surf->dpy, surf->drawable, target, surf->gc, 0, 0, w, h, 0, 0); -} - -static void -nk_xsurf_del(XSurface *surf) -{ - XFreePixmap(surf->dpy, surf->drawable); - XFreeGC(surf->dpy, surf->gc); - free(surf); -} - -XFont* -nk_xfont_create(Display *dpy, const char *name) -{ - int n; - char *def, **missing; - XFont *font = (XFont*)calloc(1, sizeof(XFont)); - font->set = XCreateFontSet(dpy, name, &missing, &n, &def); - if(missing) { - while(n--) - fprintf(stderr, "missing fontset: %s\n", missing[n]); - XFreeStringList(missing); - } - - if(font->set) { - XFontStruct **xfonts; - char **font_names; - XExtentsOfFontSet(font->set); - n = XFontsOfFontSet(font->set, &xfonts, &font_names); - while(n--) { - font->ascent = MAX(font->ascent, (*xfonts)->ascent); - font->descent = MAX(font->descent,(*xfonts)->descent); - xfonts++; - } - } else { - if(!(font->xfont = XLoadQueryFont(dpy, name)) - && !(font->xfont = XLoadQueryFont(dpy, "fixed"))) { - free(font); - return 0; - } - font->ascent = font->xfont->ascent; - font->descent = font->xfont->descent; - } - font->height = font->ascent + font->descent; - return font; -} - -static float -nk_xfont_get_text_width(nk_handle handle, float height, const char *text, int len) -{ - XFont *font = (XFont*)handle.ptr; - XRectangle r; - if(!font || !text) - return 0; - - if(font->set) { - XmbTextExtents(font->set, (const char*)text, len, NULL, &r); - return (float)r.width; - } else{ - int w = XTextWidth(font->xfont, (const char*)text, len); - return (float)w; - } -} - -void -nk_xfont_del(Display *dpy, XFont *font) -{ - if(!font) return; - if(font->set) - XFreeFontSet(dpy, font->set); - else - XFreeFont(dpy, font->xfont); - free(font); -} - -NK_API struct nk_context* -nk_xlib_init(XFont *xfont, Display *dpy, int screen, Window root, - unsigned int w, unsigned int h) -{ - struct nk_user_font *font = &xfont->handle; - font->userdata = nk_handle_ptr(xfont); - font->height = (float)xfont->height; - font->width = nk_xfont_get_text_width; - xlib.dpy = dpy; - xlib.root = root; - - if (!setlocale(LC_ALL,"")) return 0; - if (!XSupportsLocale()) return 0; - if (!XSetLocaleModifiers("@im=none")) return 0; - - /* create invisible cursor */ - {static XColor dummy; char data[1] = {0}; - Pixmap blank = XCreateBitmapFromData(dpy, root, data, 1, 1); - if (blank == None) return 0; - xlib.cursor = XCreatePixmapCursor(dpy, blank, blank, &dummy, &dummy, 0, 0); - XFreePixmap(dpy, blank);} - - xlib.surf = nk_xsurf_create(screen, w, h); - nk_init_default(&xlib.ctx, font); - return &xlib.ctx; -} - -NK_API void -nk_xlib_set_font(XFont *xfont) -{ - struct nk_user_font *font = &xfont->handle; - font->userdata = nk_handle_ptr(xfont); - font->height = (float)xfont->height; - font->width = nk_xfont_get_text_width; - nk_style_set_font(&xlib.ctx, font); -} - -NK_API int -nk_xlib_handle_event(Display *dpy, int screen, Window win, XEvent *evt) -{ - struct nk_context *ctx = &xlib.ctx; - - /* optional grabbing behavior */ - if (ctx->input.mouse.grab) { - XDefineCursor(xlib.dpy, xlib.root, xlib.cursor); - ctx->input.mouse.grab = 0; - } else if (ctx->input.mouse.ungrab) { - XWarpPointer(xlib.dpy, None, xlib.root, 0, 0, 0, 0, - (int)ctx->input.mouse.prev.x, (int)ctx->input.mouse.prev.y); - XUndefineCursor(xlib.dpy, xlib.root); - ctx->input.mouse.ungrab = 0; - } - - if (evt->type == KeyPress || evt->type == KeyRelease) - { - /* Key handler */ - int ret, down = (evt->type == KeyPress); - KeySym *code = XGetKeyboardMapping(xlib.surf->dpy, (KeyCode)evt->xkey.keycode, 1, &ret); - if (*code == XK_Shift_L || *code == XK_Shift_R) nk_input_key(ctx, NK_KEY_SHIFT, down); - else if (*code == XK_Delete) nk_input_key(ctx, NK_KEY_DEL, down); - else if (*code == XK_Return) nk_input_key(ctx, NK_KEY_ENTER, down); - else if (*code == XK_Tab) nk_input_key(ctx, NK_KEY_TAB, down); - else if (*code == XK_Left) nk_input_key(ctx, NK_KEY_LEFT, down); - else if (*code == XK_Right) nk_input_key(ctx, NK_KEY_RIGHT, down); - else if (*code == XK_Up) nk_input_key(ctx, NK_KEY_UP, down); - else if (*code == XK_Down) nk_input_key(ctx, NK_KEY_DOWN, down); - else if (*code == XK_BackSpace) nk_input_key(ctx, NK_KEY_BACKSPACE, down); - else if (*code == XK_Escape) nk_input_key(ctx, NK_KEY_TEXT_RESET_MODE, down); - else if (*code == XK_Page_Up) nk_input_key(ctx, NK_KEY_SCROLL_UP, down); - else if (*code == XK_Page_Down) nk_input_key(ctx, NK_KEY_SCROLL_DOWN, down); - else if (*code == XK_Home) { - nk_input_key(ctx, NK_KEY_TEXT_START, down); - nk_input_key(ctx, NK_KEY_SCROLL_START, down); - } else if (*code == XK_End) { - nk_input_key(ctx, NK_KEY_TEXT_END, down); - nk_input_key(ctx, NK_KEY_SCROLL_END, down); - } else { - if (*code == 'c' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_COPY, down); - else if (*code == 'v' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_PASTE, down); - else if (*code == 'x' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_CUT, down); - else if (*code == 'z' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_TEXT_UNDO, down); - else if (*code == 'r' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_TEXT_REDO, down); - else if (*code == XK_Left && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, down); - else if (*code == XK_Right && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, down); - else if (*code == 'b' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down); - else if (*code == 'e' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down); - else { - if (*code == 'i') - nk_input_key(ctx, NK_KEY_TEXT_INSERT_MODE, down); - else if (*code == 'r') - nk_input_key(ctx, NK_KEY_TEXT_REPLACE_MODE, down); - if (down) { - char buf[32]; - KeySym keysym = 0; - if (XLookupString((XKeyEvent*)evt, buf, 32, &keysym, NULL) != NoSymbol) - nk_input_glyph(ctx, buf); - } - } - } - XFree(code); - return 1; - } else if (evt->type == ButtonPress || evt->type == ButtonRelease) { - /* Button handler */ - int down = (evt->type == ButtonPress); - const int x = evt->xbutton.x, y = evt->xbutton.y; - if (evt->xbutton.button == Button1) - nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down); - if (evt->xbutton.button == Button2) - nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down); - else if (evt->xbutton.button == Button3) - nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down); - else if (evt->xbutton.button == Button4) - nk_input_scroll(ctx, 1.0f); - else if (evt->xbutton.button == Button5) - nk_input_scroll(ctx, -1.0f); - else return 0; - return 1; - } else if (evt->type == MotionNotify) { - /* Mouse motion handler */ - const int x = evt->xmotion.x, y = evt->xmotion.y; - nk_input_motion(ctx, x, y); - if (ctx->input.mouse.grabbed) { - ctx->input.mouse.pos.x = ctx->input.mouse.prev.x; - ctx->input.mouse.pos.y = ctx->input.mouse.prev.y; - XWarpPointer(xlib.dpy, None, xlib.surf->root, 0, 0, 0, 0, (int)ctx->input.mouse.pos.x, (int)ctx->input.mouse.pos.y); - } - return 1; - } else if (evt->type == Expose || evt->type == ConfigureNotify) { - /* Window resize handler */ - unsigned int width, height; - XWindowAttributes attr; - XGetWindowAttributes(dpy, win, &attr); - width = (unsigned int)attr.width; - height = (unsigned int)attr.height; - nk_xsurf_resize(xlib.surf, width, height); - return 1; - } else if (evt->type == KeymapNotify) { - XRefreshKeyboardMapping(&evt->xmapping); - return 1; - } - return 0; -} - -NK_API void -nk_xlib_shutdown(void) -{ - nk_xsurf_del(xlib.surf); - nk_free(&xlib.ctx); - XFreeCursor(xlib.dpy, xlib.cursor); - nk_memset(&xlib, 0, sizeof(xlib)); -} - -NK_API void -nk_xlib_render(Drawable screen, struct nk_color clear) -{ - const struct nk_command *cmd; - struct nk_context *ctx = &xlib.ctx; - XSurface *surf = xlib.surf; - - nk_xsurf_clear(xlib.surf, nk_color_from_byte(&clear.r)); - nk_foreach(cmd, &xlib.ctx) - { - switch (cmd->type) { - case NK_COMMAND_NOP: break; - case NK_COMMAND_SCISSOR: { - const struct nk_command_scissor *s =(const struct nk_command_scissor*)cmd; - nk_xsurf_scissor(surf, s->x, s->y, s->w, s->h); - } break; - case NK_COMMAND_LINE: { - const struct nk_command_line *l = (const struct nk_command_line *)cmd; - nk_xsurf_stroke_line(surf, l->begin.x, l->begin.y, l->end.x, - l->end.y, l->line_thickness, l->color); - } break; - case NK_COMMAND_RECT: { - const struct nk_command_rect *r = (const struct nk_command_rect *)cmd; - nk_xsurf_stroke_rect(surf, r->x, r->y, r->w, r->h, - (unsigned short)r->rounding, r->line_thickness, r->color); - } break; - case NK_COMMAND_RECT_FILLED: { - const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled *)cmd; - nk_xsurf_fill_rect(surf, r->x, r->y, r->w, r->h, - (unsigned short)r->rounding, r->color); - } break; - case NK_COMMAND_CIRCLE: { - const struct nk_command_circle *c = (const struct nk_command_circle *)cmd; - nk_xsurf_stroke_circle(surf, c->x, c->y, c->w, c->h, c->line_thickness, c->color); - } break; - case NK_COMMAND_CIRCLE_FILLED: { - const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd; - nk_xsurf_fill_circle(surf, c->x, c->y, c->w, c->h, c->color); - } break; - case NK_COMMAND_TRIANGLE: { - const struct nk_command_triangle*t = (const struct nk_command_triangle*)cmd; - nk_xsurf_stroke_triangle(surf, t->a.x, t->a.y, t->b.x, t->b.y, - t->c.x, t->c.y, t->line_thickness, t->color); - } break; - case NK_COMMAND_TRIANGLE_FILLED: { - const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled *)cmd; - nk_xsurf_fill_triangle(surf, t->a.x, t->a.y, t->b.x, t->b.y, - t->c.x, t->c.y, t->color); - } break; - case NK_COMMAND_POLYGON: { - const struct nk_command_polygon *p =(const struct nk_command_polygon*)cmd; - nk_xsurf_stroke_polygon(surf, p->points, p->point_count, p->line_thickness,p->color); - } break; - case NK_COMMAND_POLYGON_FILLED: { - const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled *)cmd; - nk_xsurf_fill_polygon(surf, p->points, p->point_count, p->color); - } break; - case NK_COMMAND_POLYLINE: { - const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd; - nk_xsurf_stroke_polyline(surf, p->points, p->point_count, p->line_thickness, p->color); - } break; - case NK_COMMAND_TEXT: { - const struct nk_command_text *t = (const struct nk_command_text*)cmd; - nk_xsurf_draw_text(surf, t->x, t->y, t->w, t->h, - (const char*)t->string, t->length, - (XFont*)t->font->userdata.ptr, - t->background, t->foreground); - } break; - case NK_COMMAND_CURVE: { - const struct nk_command_curve *q = (const struct nk_command_curve *)cmd; - nk_xsurf_stroke_curve(surf, q->begin, q->ctrl[0], q->ctrl[1], - q->end, 22, q->line_thickness, q->color); - } break; - case NK_COMMAND_RECT_MULTI_COLOR: - case NK_COMMAND_IMAGE: - case NK_COMMAND_ARC: - case NK_COMMAND_ARC_FILLED: - default: break; - } - } - nk_clear(ctx); - nk_xsurf_blit(screen, surf, surf->w, surf->h); -} -#endif diff --git a/deps/nuklear/demo/x11_opengl2/main.c b/deps/nuklear/demo/x11_opengl2/main.c deleted file mode 100644 index cfe5604c..00000000 --- a/deps/nuklear/demo/x11_opengl2/main.c +++ /dev/null @@ -1,320 +0,0 @@ -/* nuklear - v1.17 - public domain */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define NK_INCLUDE_FIXED_TYPES -#define NK_INCLUDE_STANDARD_IO -#define NK_INCLUDE_STANDARD_VARARGS -#define NK_INCLUDE_DEFAULT_ALLOCATOR -#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT -#define NK_INCLUDE_FONT_BAKING -#define NK_INCLUDE_DEFAULT_FONT -#define NK_IMPLEMENTATION -#define NK_XLIB_GL2_IMPLEMENTATION -#include "../../nuklear.h" -#include "nuklear_xlib_gl2.h" - -#define WINDOW_WIDTH 1200 -#define WINDOW_HEIGHT 800 - -#define MAX_VERTEX_BUFFER 512 * 1024 -#define MAX_ELEMENT_BUFFER 128 * 1024 - -#define UNUSED(a) (void)a -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) < (b) ? (b) : (a)) -#define LEN(a) (sizeof(a)/sizeof(a)[0]) - -/* =============================================================== - * - * EXAMPLE - * - * ===============================================================*/ -/* This are some code examples to provide a small overview of what can be - * done with this library. To try out an example uncomment the include - * and the corresponding function. */ -/*#include "../style.c"*/ -/*#include "../calculator.c"*/ -/*#include "../overview.c"*/ -/*#include "../node_editor.c"*/ - -/* =============================================================== - * - * DEMO - * - * ===============================================================*/ -struct XWindow { - Display *dpy; - Window win; - XVisualInfo *vis; - Colormap cmap; - XSetWindowAttributes swa; - XWindowAttributes attr; - GLXFBConfig fbc; - int width, height; -}; -static int gl_err = FALSE; -static int gl_error_handler(Display *dpy, XErrorEvent *ev) -{UNUSED((dpy, ev)); gl_err = TRUE;return 0;} - -static void -die(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fputs("\n", stderr); - exit(EXIT_FAILURE); -} - -static int -has_extension(const char *string, const char *ext) -{ - const char *start, *where, *term; - where = strchr(ext, ' '); - if (where || *ext == '\0') - return FALSE; - - for (start = string;;) { - where = strstr((const char*)start, ext); - if (!where) break; - term = where + strlen(ext); - if (where == start || *(where - 1) == ' ') { - if (*term == ' ' || *term == '\0') - return TRUE; - } - start = term; - } - return FALSE; -} - -int main(int argc, char **argv) -{ - /* Platform */ - int running = 1; - struct XWindow win; - GLXContext glContext; - struct nk_context *ctx; - struct nk_color background; - - memset(&win, 0, sizeof(win)); - win.dpy = XOpenDisplay(NULL); - if (!win.dpy) die("Failed to open X display\n"); - { - /* check glx version */ - int glx_major, glx_minor; - if (!glXQueryVersion(win.dpy, &glx_major, &glx_minor)) - die("[X11]: Error: Failed to query OpenGL version\n"); - if ((glx_major == 1 && glx_minor < 3) || (glx_major < 1)) - die("[X11]: Error: Invalid GLX version!\n"); - } - { - /* find and pick matching framebuffer visual */ - int fb_count; - static GLint attr[] = { - GLX_X_RENDERABLE, True, - GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, - GLX_RED_SIZE, 8, - GLX_GREEN_SIZE, 8, - GLX_BLUE_SIZE, 8, - GLX_ALPHA_SIZE, 8, - GLX_DEPTH_SIZE, 24, - GLX_STENCIL_SIZE, 8, - GLX_DOUBLEBUFFER, True, - None - }; - GLXFBConfig *fbc; - fbc = glXChooseFBConfig(win.dpy, DefaultScreen(win.dpy), attr, &fb_count); - if (!fbc) die("[X11]: Error: failed to retrieve framebuffer configuration\n"); - { - /* pick framebuffer with most samples per pixel */ - int i; - int fb_best = -1, best_num_samples = -1; - for (i = 0; i < fb_count; ++i) { - XVisualInfo *vi = glXGetVisualFromFBConfig(win.dpy, fbc[i]); - if (vi) { - int sample_buffer, samples; - glXGetFBConfigAttrib(win.dpy, fbc[i], GLX_SAMPLE_BUFFERS, &sample_buffer); - glXGetFBConfigAttrib(win.dpy, fbc[i], GLX_SAMPLES, &samples); - if ((fb_best < 0) || (sample_buffer && samples > best_num_samples)) - fb_best = i; best_num_samples = samples; - } - } - win.fbc = fbc[fb_best]; - XFree(fbc); - win.vis = glXGetVisualFromFBConfig(win.dpy, win.fbc); - } - } - { - /* create window */ - win.cmap = XCreateColormap(win.dpy, RootWindow(win.dpy, win.vis->screen), win.vis->visual, AllocNone); - win.swa.colormap = win.cmap; - win.swa.background_pixmap = None; - win.swa.border_pixel = 0; - win.swa.event_mask = - ExposureMask | KeyPressMask | KeyReleaseMask | - ButtonPress | ButtonReleaseMask| ButtonMotionMask | - Button1MotionMask | Button3MotionMask | Button4MotionMask | Button5MotionMask| - PointerMotionMask| StructureNotifyMask; - win.win = XCreateWindow(win.dpy, RootWindow(win.dpy, win.vis->screen), 0, 0, - WINDOW_WIDTH, WINDOW_HEIGHT, 0, win.vis->depth, InputOutput, - win.vis->visual, CWBorderPixel|CWColormap|CWEventMask, &win.swa); - if (!win.win) die("[X11]: Failed to create window\n"); - XFree(win.vis); - XStoreName(win.dpy, win.win, "Demo"); - XMapWindow(win.dpy, win.win); - } - { - /* create opengl context */ - typedef GLXContext(*glxCreateContext)(Display*, GLXFBConfig, GLXContext, Bool, const int*); - int(*old_handler)(Display*, XErrorEvent*) = XSetErrorHandler(gl_error_handler); - const char *extensions_str = glXQueryExtensionsString(win.dpy, DefaultScreen(win.dpy)); - glxCreateContext create_context = (glxCreateContext) - glXGetProcAddressARB((const GLubyte*)"glXCreateContextAttribsARB"); - - gl_err = FALSE; - if (!has_extension(extensions_str, "GLX_ARB_create_context") || !create_context) { - fprintf(stdout, "[X11]: glXCreateContextAttribARB() not found...\n"); - fprintf(stdout, "[X11]: ... using old-style GLX context\n"); - glContext = glXCreateNewContext(win.dpy, win.fbc, GLX_RGBA_TYPE, 0, True); - } else { - GLint attr[] = { - GLX_CONTEXT_MAJOR_VERSION_ARB, 3, - GLX_CONTEXT_MINOR_VERSION_ARB, 0, - None - }; - glContext = create_context(win.dpy, win.fbc, 0, True, attr); - XSync(win.dpy, False); - if (gl_err || !glContext) { - /* Could not create GL 3.0 context. Fallback to old 2.x context. - * If a version below 3.0 is requested, implementations will - * return the newest context version compatible with OpenGL - * version less than version 3.0.*/ - attr[1] = 1; attr[3] = 0; - gl_err = FALSE; - fprintf(stdout, "[X11] Failed to create OpenGL 3.0 context\n"); - fprintf(stdout, "[X11] ... using old-style GLX context!\n"); - glContext = create_context(win.dpy, win.fbc, 0, True, attr); - } - } - XSync(win.dpy, False); - XSetErrorHandler(old_handler); - if (gl_err || !glContext) - die("[X11]: Failed to create an OpenGL context\n"); - glXMakeCurrent(win.dpy, win.win, glContext); - } - - ctx = nk_x11_init(win.dpy, win.win); - /* Load Fonts: if none of these are loaded a default font will be used */ - /* Load Cursor: if you uncomment cursor loading please hide the cursor */ - {struct nk_font_atlas *atlas; - nk_x11_font_stash_begin(&atlas); - /*struct nk_font *droid = nk_font_atlas_add_from_file(atlas, "../../../extra_font/DroidSans.ttf", 14, 0);*/ - /*struct nk_font *roboto = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Roboto-Regular.ttf", 14, 0);*/ - /*struct nk_font *future = nk_font_atlas_add_from_file(atlas, "../../../extra_font/kenvector_future_thin.ttf", 13, 0);*/ - /*struct nk_font *clean = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyClean.ttf", 12, 0);*/ - /*struct nk_font *tiny = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyTiny.ttf", 10, 0);*/ - /*struct nk_font *cousine = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Cousine-Regular.ttf", 13, 0);*/ - nk_x11_font_stash_end(); - /*nk_style_load_all_cursors(ctx, atlas->cursors);*/ - /*nk_style_set_font(ctx, &droid->handle);*/} - - /* style.c */ - /*set_style(ctx, THEME_WHITE);*/ - /*set_style(ctx, THEME_RED);*/ - /*set_style(ctx, THEME_BLUE);*/ - /*set_style(ctx, THEME_DARK);*/ - - background = nk_rgb(28,48,62); - while (running) - { - /* Input */ - XEvent evt; - nk_input_begin(ctx); - while (XCheckWindowEvent(win.dpy, win.win, win.swa.event_mask, &evt)){ - if (XFilterEvent(&evt, win.win)) continue; - nk_x11_handle_event(&evt); - } - nk_input_end(ctx); - - /* GUI */ - if (nk_begin(ctx, "Demo", nk_rect(50, 50, 200, 200), - NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE| - NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE)) - { - enum {EASY, HARD}; - static int op = EASY; - static int property = 20; - - nk_layout_row_static(ctx, 30, 80, 1); - if (nk_button_label(ctx, "button")) - fprintf(stdout, "button pressed\n"); - nk_layout_row_dynamic(ctx, 30, 2); - if (nk_option_label(ctx, "easy", op == EASY)) op = EASY; - if (nk_option_label(ctx, "hard", op == HARD)) op = HARD; - nk_layout_row_dynamic(ctx, 25, 1); - nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1); - - nk_layout_row_dynamic(ctx, 20, 1); - nk_label(ctx, "background:", NK_TEXT_LEFT); - nk_layout_row_dynamic(ctx, 25, 1); - if (nk_combo_begin_color(ctx, background, nk_vec2(nk_widget_width(ctx),400))) { - nk_layout_row_dynamic(ctx, 120, 1); - background = nk_color_picker(ctx, background, NK_RGBA); - nk_layout_row_dynamic(ctx, 25, 1); - background.r = (nk_byte)nk_propertyi(ctx, "#R:", 0, background.r, 255, 1,1); - background.g = (nk_byte)nk_propertyi(ctx, "#G:", 0, background.g, 255, 1,1); - background.b = (nk_byte)nk_propertyi(ctx, "#B:", 0, background.b, 255, 1,1); - background.a = (nk_byte)nk_propertyi(ctx, "#A:", 0, background.a, 255, 1,1); - nk_combo_end(ctx); - } - } - nk_end(ctx); - if (nk_window_is_closed(ctx, "Demo")) break; - - /* -------------- EXAMPLES ---------------- */ - /*calculator(ctx);*/ - /*overview(ctx);*/ - /*node_editor(ctx);*/ - /* ----------------------------------------- */ - - /* Draw */ - {float bg[4]; - nk_color_fv(bg, background); - XGetWindowAttributes(win.dpy, win.win, &win.attr); - glViewport(0, 0, win.width, win.height); - glClear(GL_COLOR_BUFFER_BIT); - glClearColor(bg[0], bg[1], bg[2], bg[3]); - /* IMPORTANT: `nk_x11_render` modifies some global OpenGL state - * with blending, scissor, face culling, depth test and viewport and - * defaults everything back into a default state. - * Make sure to either a.) save and restore or b.) reset your own state after - * rendering the UI. */ - nk_x11_render(NK_ANTI_ALIASING_ON, MAX_VERTEX_BUFFER, MAX_ELEMENT_BUFFER); - glXSwapBuffers(win.dpy, win.win);} - } - - nk_x11_shutdown(); - glXMakeCurrent(win.dpy, 0, 0); - glXDestroyContext(win.dpy, glContext); - XUnmapWindow(win.dpy, win.win); - XFreeColormap(win.dpy, win.cmap); - XDestroyWindow(win.dpy, win.win); - XCloseDisplay(win.dpy); - return 0; - -} diff --git a/deps/nuklear/demo/x11_opengl2/nuklear_xlib_gl2.h b/deps/nuklear/demo/x11_opengl2/nuklear_xlib_gl2.h deleted file mode 100644 index a8144550..00000000 --- a/deps/nuklear/demo/x11_opengl2/nuklear_xlib_gl2.h +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Nuklear - v1.17 - public domain - * no warrenty implied; use at your own risk. - * authored from 2015-2016 by Micha Mettke - */ -/* - * ============================================================== - * - * API - * - * =============================================================== - */ -#ifndef NK_XLIB_GL3_H_ -#define NK_XLIB_GL3_H_ - -#include -NK_API struct nk_context* nk_x11_init(Display *dpy, Window win); -NK_API void nk_x11_font_stash_begin(struct nk_font_atlas **atlas); -NK_API void nk_x11_font_stash_end(void); -NK_API int nk_x11_handle_event(XEvent *evt); -NK_API void nk_x11_render(enum nk_anti_aliasing, int max_vertex_buffer, int max_element_buffer); -NK_API void nk_x11_shutdown(void); - -#endif -/* - * ============================================================== - * - * IMPLEMENTATION - * - * =============================================================== - */ -#ifdef NK_XLIB_GL2_IMPLEMENTATION -#include -#include -#include - -#include -#include -#include -#include - -#include - -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif - -struct nk_x11_vertex { - float position[2]; - float uv[2]; - nk_byte col[4]; -}; - -struct nk_x11_device { - struct nk_buffer cmds; - struct nk_draw_null_texture null; - GLuint font_tex; -}; - -static struct nk_x11 { - struct nk_x11_device ogl; - struct nk_context ctx; - struct nk_font_atlas atlas; - Cursor cursor; - Display *dpy; - Window win; -} x11; - -NK_INTERN void -nk_x11_device_upload_atlas(const void *image, int width, int height) -{ - struct nk_x11_device *dev = &x11.ogl; - glGenTextures(1, &dev->font_tex); - glBindTexture(GL_TEXTURE_2D, dev->font_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, image); -} - -NK_API void -nk_x11_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_buffer) -{ - /* setup global state */ - struct nk_x11_device *dev = &x11.ogl; - int width, height; - - XWindowAttributes attr; - XGetWindowAttributes(x11.dpy, x11.win, &attr); - width = attr.width; - height = attr.height; - - glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT|GL_TRANSFORM_BIT); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnable(GL_BLEND); - glEnable(GL_TEXTURE_2D); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - /* setup viewport/project */ - glViewport(0,0,(GLsizei)width,(GLsizei)height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, width, height, 0.0f, -1.0f, 1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - { - GLsizei vs = sizeof(struct nk_x11_vertex); - size_t vp = offsetof(struct nk_x11_vertex, position); - size_t vt = offsetof(struct nk_x11_vertex, uv); - size_t vc = offsetof(struct nk_x11_vertex, col); - - /* convert from command queue into draw list and draw to screen */ - const struct nk_draw_command *cmd; - const nk_draw_index *offset = NULL; - struct nk_buffer vbuf, ebuf; - - /* fill convert configuration */ - struct nk_convert_config config; - static const struct nk_draw_vertex_layout_element vertex_layout[] = { - {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_x11_vertex, position)}, - {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_x11_vertex, uv)}, - {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_x11_vertex, col)}, - {NK_VERTEX_LAYOUT_END} - }; - NK_MEMSET(&config, 0, sizeof(config)); - config.vertex_layout = vertex_layout; - config.vertex_size = sizeof(struct nk_x11_vertex); - config.vertex_alignment = NK_ALIGNOF(struct nk_x11_vertex); - config.null = dev->null; - config.circle_segment_count = 22; - config.curve_segment_count = 22; - config.arc_segment_count = 22; - config.global_alpha = 1.0f; - config.shape_AA = AA; - config.line_AA = AA; - - /* convert shapes into vertexes */ - nk_buffer_init_default(&vbuf); - nk_buffer_init_default(&ebuf); - nk_convert(&x11.ctx, &dev->cmds, &vbuf, &ebuf, &config); - - /* setup vertex buffer pointer */ - {const void *vertices = nk_buffer_memory_const(&vbuf); - glVertexPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vp)); - glTexCoordPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vt)); - glColorPointer(4, GL_UNSIGNED_BYTE, vs, (const void*)((const nk_byte*)vertices + vc));} - - /* iterate over and execute each draw command */ - offset = (const nk_draw_index*)nk_buffer_memory_const(&ebuf); - nk_draw_foreach(cmd, &x11.ctx, &dev->cmds) - { - if (!cmd->elem_count) continue; - glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id); - glScissor( - (GLint)(cmd->clip_rect.x), - (GLint)((height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h))), - (GLint)(cmd->clip_rect.w), - (GLint)(cmd->clip_rect.h)); - glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset); - offset += cmd->elem_count; - } - nk_clear(&x11.ctx); - nk_buffer_free(&vbuf); - nk_buffer_free(&ebuf); - } - - /* default OpenGL state */ - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - - glBindTexture(GL_TEXTURE_2D, 0); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - -} - -NK_API void -nk_x11_font_stash_begin(struct nk_font_atlas **atlas) -{ - nk_font_atlas_init_default(&x11.atlas); - nk_font_atlas_begin(&x11.atlas); - *atlas = &x11.atlas; -} - -NK_API void -nk_x11_font_stash_end(void) -{ - const void *image; int w, h; - image = nk_font_atlas_bake(&x11.atlas, &w, &h, NK_FONT_ATLAS_RGBA32); - nk_x11_device_upload_atlas(image, w, h); - nk_font_atlas_end(&x11.atlas, nk_handle_id((int)x11.ogl.font_tex), &x11.ogl.null); - if (x11.atlas.default_font) - nk_style_set_font(&x11.ctx, &x11.atlas.default_font->handle); -} - -NK_API int -nk_x11_handle_event(XEvent *evt) -{ - struct nk_context *ctx = &x11.ctx; - - /* optional grabbing behavior */ - if (ctx->input.mouse.grab) { - XDefineCursor(x11.dpy, x11.win, x11.cursor); - ctx->input.mouse.grab = 0; - } else if (ctx->input.mouse.ungrab) { - XWarpPointer(x11.dpy, None, x11.win, 0, 0, 0, 0, - (int)ctx->input.mouse.pos.x, (int)ctx->input.mouse.pos.y); - XUndefineCursor(x11.dpy, x11.win); - ctx->input.mouse.ungrab = 0; - } - - if (evt->type == KeyPress || evt->type == KeyRelease) - { - /* Key handler */ - int ret, down = (evt->type == KeyPress); - KeySym *code = XGetKeyboardMapping(x11.dpy, (KeyCode)evt->xkey.keycode, 1, &ret); - if (*code == XK_Shift_L || *code == XK_Shift_R) nk_input_key(ctx, NK_KEY_SHIFT, down); - else if (*code == XK_Delete) nk_input_key(ctx, NK_KEY_DEL, down); - else if (*code == XK_Return) nk_input_key(ctx, NK_KEY_ENTER, down); - else if (*code == XK_Tab) nk_input_key(ctx, NK_KEY_TAB, down); - else if (*code == XK_Left) nk_input_key(ctx, NK_KEY_LEFT, down); - else if (*code == XK_Right) nk_input_key(ctx, NK_KEY_RIGHT, down); - else if (*code == XK_Up) nk_input_key(ctx, NK_KEY_UP, down); - else if (*code == XK_Down) nk_input_key(ctx, NK_KEY_DOWN, down); - else if (*code == XK_BackSpace) nk_input_key(ctx, NK_KEY_BACKSPACE, down); - else if (*code == XK_space && !down) nk_input_char(ctx, ' '); - else if (*code == XK_Page_Up) nk_input_key(ctx, NK_KEY_SCROLL_UP, down); - else if (*code == XK_Page_Down) nk_input_key(ctx, NK_KEY_SCROLL_DOWN, down); - else if (*code == XK_Home) { - nk_input_key(ctx, NK_KEY_TEXT_START, down); - nk_input_key(ctx, NK_KEY_SCROLL_START, down); - } else if (*code == XK_End) { - nk_input_key(ctx, NK_KEY_TEXT_END, down); - nk_input_key(ctx, NK_KEY_SCROLL_END, down); - } else { - if (*code == 'c' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_COPY, down); - else if (*code == 'v' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_PASTE, down); - else if (*code == 'x' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_CUT, down); - else if (*code == 'z' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_TEXT_UNDO, down); - else if (*code == 'r' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_TEXT_REDO, down); - else if (*code == XK_Left && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, down); - else if (*code == XK_Right && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, down); - else if (*code == 'b' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down); - else if (*code == 'e' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down); - else { - if (*code == 'i') - nk_input_key(ctx, NK_KEY_TEXT_INSERT_MODE, down); - else if (*code == 'r') - nk_input_key(ctx, NK_KEY_TEXT_REPLACE_MODE, down); - if (down) { - char buf[32]; - KeySym keysym = 0; - if (XLookupString((XKeyEvent*)evt, buf, 32, &keysym, NULL) != NoSymbol) - nk_input_glyph(ctx, buf); - } - } - } - XFree(code); - return 1; - } else if (evt->type == ButtonPress || evt->type == ButtonRelease) { - /* Button handler */ - int down = (evt->type == ButtonPress); - const int x = evt->xbutton.x, y = evt->xbutton.y; - if (evt->xbutton.button == Button1) - nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down); - if (evt->xbutton.button == Button2) - nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down); - else if (evt->xbutton.button == Button3) - nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down); - else if (evt->xbutton.button == Button4) - nk_input_scroll(ctx, 1.0f); - else if (evt->xbutton.button == Button5) - nk_input_scroll(ctx, -1.0f); - else return 0; - return 1; - } else if (evt->type == MotionNotify) { - /* Mouse motion handler */ - const int x = evt->xmotion.x, y = evt->xmotion.y; - nk_input_motion(ctx, x, y); - if (ctx->input.mouse.grabbed) { - ctx->input.mouse.pos.x = ctx->input.mouse.prev.x; - ctx->input.mouse.pos.y = ctx->input.mouse.prev.y; - XWarpPointer(x11.dpy, None, x11.win, 0, 0, 0, 0, (int)ctx->input.mouse.pos.x, (int)ctx->input.mouse.pos.y); - } - return 1; - } else if (evt->type == KeymapNotify) { - XRefreshKeyboardMapping(&evt->xmapping); - return 1; - } - return 0; -} - -NK_API struct nk_context* -nk_x11_init(Display *dpy, Window win) -{ - x11.dpy = dpy; - x11.win = win; - - if (!setlocale(LC_ALL,"")) return 0; - if (!XSupportsLocale()) return 0; - if (!XSetLocaleModifiers("@im=none")) return 0; - - /* create invisible cursor */ - {static XColor dummy; char data[1] = {0}; - Pixmap blank = XCreateBitmapFromData(dpy, win, data, 1, 1); - if (blank == None) return 0; - x11.cursor = XCreatePixmapCursor(dpy, blank, blank, &dummy, &dummy, 0, 0); - XFreePixmap(dpy, blank);} - - nk_buffer_init_default(&x11.ogl.cmds); - nk_init_default(&x11.ctx, 0); - return &x11.ctx; -} - -NK_API void -nk_x11_shutdown(void) -{ - struct nk_x11_device *dev = &x11.ogl; - nk_font_atlas_clear(&x11.atlas); - nk_free(&x11.ctx); - glDeleteTextures(1, &dev->font_tex); - nk_buffer_free(&dev->cmds); - XFreeCursor(x11.dpy, x11.cursor); - memset(&x11, 0, sizeof(x11)); -} - -#endif diff --git a/deps/nuklear/demo/x11_opengl3/main.c b/deps/nuklear/demo/x11_opengl3/main.c deleted file mode 100644 index cd026f9b..00000000 --- a/deps/nuklear/demo/x11_opengl3/main.c +++ /dev/null @@ -1,317 +0,0 @@ -/* nuklear - v1.17 - public domain */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NK_INCLUDE_FIXED_TYPES -#define NK_INCLUDE_STANDARD_IO -#define NK_INCLUDE_STANDARD_VARARGS -#define NK_INCLUDE_DEFAULT_ALLOCATOR -#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT -#define NK_INCLUDE_FONT_BAKING -#define NK_INCLUDE_DEFAULT_FONT -#define NK_IMPLEMENTATION -#define NK_XLIB_GL3_IMPLEMENTATION -#define NK_XLIB_LOAD_OPENGL_EXTENSIONS -#include "../../nuklear.h" -#include "nuklear_xlib_gl3.h" - -#define WINDOW_WIDTH 1200 -#define WINDOW_HEIGHT 800 - -#define MAX_VERTEX_BUFFER 512 * 1024 -#define MAX_ELEMENT_BUFFER 128 * 1024 - -#define UNUSED(a) (void)a -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) < (b) ? (b) : (a)) -#define LEN(a) (sizeof(a)/sizeof(a)[0]) - -/* =============================================================== - * - * EXAMPLE - * - * ===============================================================*/ -/* This are some code examples to provide a small overview of what can be - * done with this library. To try out an example uncomment the include - * and the corresponding function. */ -/*#include "../style.c"*/ -/*#include "../calculator.c"*/ -/*#include "../overview.c"*/ -/*#include "../node_editor.c"*/ - -/* =============================================================== - * - * DEMO - * - * ===============================================================*/ -struct XWindow { - Display *dpy; - Window win; - XVisualInfo *vis; - Colormap cmap; - XSetWindowAttributes swa; - XWindowAttributes attr; - GLXFBConfig fbc; - int width, height; -}; -static int gl_err = FALSE; -static int gl_error_handler(Display *dpy, XErrorEvent *ev) -{UNUSED((dpy, ev)); gl_err = TRUE;return 0;} - -static void -die(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fputs("\n", stderr); - exit(EXIT_FAILURE); -} - -static int -has_extension(const char *string, const char *ext) -{ - const char *start, *where, *term; - where = strchr(ext, ' '); - if (where || *ext == '\0') - return FALSE; - - for (start = string;;) { - where = strstr((const char*)start, ext); - if (!where) break; - term = where + strlen(ext); - if (where == start || *(where - 1) == ' ') { - if (*term == ' ' || *term == '\0') - return TRUE; - } - start = term; - } - return FALSE; -} - -int main(int argc, char **argv) -{ - /* Platform */ - int running = 1; - struct XWindow win; - GLXContext glContext; - struct nk_context *ctx; - struct nk_color background; - - memset(&win, 0, sizeof(win)); - win.dpy = XOpenDisplay(NULL); - if (!win.dpy) die("Failed to open X display\n"); - { - /* check glx version */ - int glx_major, glx_minor; - if (!glXQueryVersion(win.dpy, &glx_major, &glx_minor)) - die("[X11]: Error: Failed to query OpenGL version\n"); - if ((glx_major == 1 && glx_minor < 3) || (glx_major < 1)) - die("[X11]: Error: Invalid GLX version!\n"); - } - { - /* find and pick matching framebuffer visual */ - int fb_count; - static GLint attr[] = { - GLX_X_RENDERABLE, True, - GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, - GLX_RED_SIZE, 8, - GLX_GREEN_SIZE, 8, - GLX_BLUE_SIZE, 8, - GLX_ALPHA_SIZE, 8, - GLX_DEPTH_SIZE, 24, - GLX_STENCIL_SIZE, 8, - GLX_DOUBLEBUFFER, True, - None - }; - GLXFBConfig *fbc; - fbc = glXChooseFBConfig(win.dpy, DefaultScreen(win.dpy), attr, &fb_count); - if (!fbc) die("[X11]: Error: failed to retrieve framebuffer configuration\n"); - { - /* pick framebuffer with most samples per pixel */ - int i; - int fb_best = -1, best_num_samples = -1; - for (i = 0; i < fb_count; ++i) { - XVisualInfo *vi = glXGetVisualFromFBConfig(win.dpy, fbc[i]); - if (vi) { - int sample_buffer, samples; - glXGetFBConfigAttrib(win.dpy, fbc[i], GLX_SAMPLE_BUFFERS, &sample_buffer); - glXGetFBConfigAttrib(win.dpy, fbc[i], GLX_SAMPLES, &samples); - if ((fb_best < 0) || (sample_buffer && samples > best_num_samples)) - fb_best = i; best_num_samples = samples; - } - } - win.fbc = fbc[fb_best]; - XFree(fbc); - win.vis = glXGetVisualFromFBConfig(win.dpy, win.fbc); - } - } - { - /* create window */ - win.cmap = XCreateColormap(win.dpy, RootWindow(win.dpy, win.vis->screen), win.vis->visual, AllocNone); - win.swa.colormap = win.cmap; - win.swa.background_pixmap = None; - win.swa.border_pixel = 0; - win.swa.event_mask = - ExposureMask | KeyPressMask | KeyReleaseMask | - ButtonPress | ButtonReleaseMask| ButtonMotionMask | - Button1MotionMask | Button3MotionMask | Button4MotionMask | Button5MotionMask| - PointerMotionMask| StructureNotifyMask; - win.win = XCreateWindow(win.dpy, RootWindow(win.dpy, win.vis->screen), 0, 0, - WINDOW_WIDTH, WINDOW_HEIGHT, 0, win.vis->depth, InputOutput, - win.vis->visual, CWBorderPixel|CWColormap|CWEventMask, &win.swa); - if (!win.win) die("[X11]: Failed to create window\n"); - XFree(win.vis); - XStoreName(win.dpy, win.win, "Demo"); - XMapWindow(win.dpy, win.win); - } - { - /* create opengl context */ - typedef GLXContext(*glxCreateContext)(Display*, GLXFBConfig, GLXContext, Bool, const int*); - int(*old_handler)(Display*, XErrorEvent*) = XSetErrorHandler(gl_error_handler); - const char *extensions_str = glXQueryExtensionsString(win.dpy, DefaultScreen(win.dpy)); - glxCreateContext create_context = (glxCreateContext) - glXGetProcAddressARB((const GLubyte*)"glXCreateContextAttribsARB"); - - gl_err = FALSE; - if (!has_extension(extensions_str, "GLX_ARB_create_context") || !create_context) { - fprintf(stdout, "[X11]: glXCreateContextAttribARB() not found...\n"); - fprintf(stdout, "[X11]: ... using old-style GLX context\n"); - glContext = glXCreateNewContext(win.dpy, win.fbc, GLX_RGBA_TYPE, 0, True); - } else { - GLint attr[] = { - GLX_CONTEXT_MAJOR_VERSION_ARB, 3, - GLX_CONTEXT_MINOR_VERSION_ARB, 0, - None - }; - glContext = create_context(win.dpy, win.fbc, 0, True, attr); - XSync(win.dpy, False); - if (gl_err || !glContext) { - /* Could not create GL 3.0 context. Fallback to old 2.x context. - * If a version below 3.0 is requested, implementations will - * return the newest context version compatible with OpenGL - * version less than version 3.0.*/ - attr[1] = 1; attr[3] = 0; - gl_err = FALSE; - fprintf(stdout, "[X11] Failed to create OpenGL 3.0 context\n"); - fprintf(stdout, "[X11] ... using old-style GLX context!\n"); - glContext = create_context(win.dpy, win.fbc, 0, True, attr); - } - } - XSync(win.dpy, False); - XSetErrorHandler(old_handler); - if (gl_err || !glContext) - die("[X11]: Failed to create an OpenGL context\n"); - glXMakeCurrent(win.dpy, win.win, glContext); - } - - ctx = nk_x11_init(win.dpy, win.win); - /* Load Fonts: if none of these are loaded a default font will be used */ - {struct nk_font_atlas *atlas; - nk_x11_font_stash_begin(&atlas); - /*struct nk_font *droid = nk_font_atlas_add_from_file(atlas, "../../../extra_font/DroidSans.ttf", 14, 0);*/ - /*struct nk_font *roboto = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Roboto-Regular.ttf", 14, 0);*/ - /*struct nk_font *future = nk_font_atlas_add_from_file(atlas, "../../../extra_font/kenvector_future_thin.ttf", 13, 0);*/ - /*struct nk_font *clean = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyClean.ttf", 12, 0);*/ - /*struct nk_font *tiny = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyTiny.ttf", 10, 0);*/ - /*struct nk_font *cousine = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Cousine-Regular.ttf", 13, 0);*/ - nk_x11_font_stash_end(); - /*nk_style_load_all_cursors(ctx, atlas->cursors);*/ - /*nk_style_set_font(ctx, &droid->handle);*/} - - /* style.c */ - /*set_style(ctx, THEME_WHITE);*/ - /*set_style(ctx, THEME_RED);*/ - /*set_style(ctx, THEME_BLUE);*/ - /*set_style(ctx, THEME_DARK);*/ - - background = nk_rgb(28,48,62); - while (running) - { - /* Input */ - XEvent evt; - nk_input_begin(ctx); - while (XCheckWindowEvent(win.dpy, win.win, win.swa.event_mask, &evt)){ - if (XFilterEvent(&evt, win.win)) continue; - nk_x11_handle_event(&evt); - } - nk_input_end(ctx); - - /* GUI */ - if (nk_begin(ctx, "Demo", nk_rect(50, 50, 200, 200), - NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE| - NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE)) - { - enum {EASY, HARD}; - static int op = EASY; - static int property = 20; - - nk_layout_row_static(ctx, 30, 80, 1); - if (nk_button_label(ctx, "button")) - fprintf(stdout, "button pressed\n"); - nk_layout_row_dynamic(ctx, 30, 2); - if (nk_option_label(ctx, "easy", op == EASY)) op = EASY; - if (nk_option_label(ctx, "hard", op == HARD)) op = HARD; - nk_layout_row_dynamic(ctx, 25, 1); - nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1); - - nk_layout_row_dynamic(ctx, 20, 1); - nk_label(ctx, "background:", NK_TEXT_LEFT); - nk_layout_row_dynamic(ctx, 25, 1); - if (nk_combo_begin_color(ctx, background, nk_vec2(nk_widget_width(ctx),400))) { - nk_layout_row_dynamic(ctx, 120, 1); - background = nk_color_picker(ctx, background, NK_RGBA); - nk_layout_row_dynamic(ctx, 25, 1); - background.r = (nk_byte)nk_propertyi(ctx, "#R:", 0, background.r, 255, 1,1); - background.g = (nk_byte)nk_propertyi(ctx, "#G:", 0, background.g, 255, 1,1); - background.b = (nk_byte)nk_propertyi(ctx, "#B:", 0, background.b, 255, 1,1); - background.a = (nk_byte)nk_propertyi(ctx, "#A:", 0, background.a, 255, 1,1); - nk_combo_end(ctx); - } - } - nk_end(ctx); - if (nk_window_is_closed(ctx, "Demo")) break; - - /* -------------- EXAMPLES ---------------- */ - /*calculator(ctx);*/ - /*overview(ctx);*/ - /*node_editor(ctx);*/ - /* ----------------------------------------- */ - - /* Draw */ - {float bg[4]; - nk_color_fv(bg, background); - XGetWindowAttributes(win.dpy, win.win, &win.attr); - glViewport(0, 0, win.width, win.height); - glClear(GL_COLOR_BUFFER_BIT); - glClearColor(bg[0], bg[1], bg[2], bg[3]); - /* IMPORTANT: `nk_x11_render` modifies some global OpenGL state - * with blending, scissor, face culling, depth test and viewport and - * defaults everything back into a default state. - * Make sure to either a.) save and restore or b.) reset your own state after - * rendering the UI. */ - nk_x11_render(NK_ANTI_ALIASING_ON, MAX_VERTEX_BUFFER, MAX_ELEMENT_BUFFER); - glXSwapBuffers(win.dpy, win.win);} - } - - nk_x11_shutdown(); - glXMakeCurrent(win.dpy, 0, 0); - glXDestroyContext(win.dpy, glContext); - XUnmapWindow(win.dpy, win.win); - XFreeColormap(win.dpy, win.cmap); - XDestroyWindow(win.dpy, win.win); - XCloseDisplay(win.dpy); - return 0; - -} diff --git a/deps/nuklear/demo/x11_opengl3/nuklear_xlib_gl3.h b/deps/nuklear/demo/x11_opengl3/nuklear_xlib_gl3.h deleted file mode 100644 index b0f56b98..00000000 --- a/deps/nuklear/demo/x11_opengl3/nuklear_xlib_gl3.h +++ /dev/null @@ -1,725 +0,0 @@ -/* - * Nuklear - v1.17 - public domain - * no warrenty implied; use at your own risk. - * authored from 2015-2016 by Micha Mettke - */ -/* - * ============================================================== - * - * API - * - * =============================================================== - */ -#ifndef NK_XLIB_GL3_H_ -#define NK_XLIB_GL3_H_ - -#include -NK_API struct nk_context* nk_x11_init(Display *dpy, Window win); -NK_API void nk_x11_font_stash_begin(struct nk_font_atlas **atlas); -NK_API void nk_x11_font_stash_end(void); -NK_API int nk_x11_handle_event(XEvent *evt); -NK_API void nk_x11_render(enum nk_anti_aliasing, int max_vertex_buffer, int max_element_buffer); -NK_API void nk_x11_shutdown(void); -NK_API int nk_x11_device_create(void); -NK_API void nk_x11_device_destroy(void); - -#endif -/* - * ============================================================== - * - * IMPLEMENTATION - * - * =============================================================== - */ -#ifdef NK_XLIB_GL3_IMPLEMENTATION -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif - -#ifdef NK_XLIB_LOAD_OPENGL_EXTENSIONS -#include - -/* GL_ARB_vertex_buffer_object */ -typedef void(*nkglGenBuffers)(GLsizei, GLuint*); -typedef void(*nkglBindBuffer)(GLenum, GLuint); -typedef void(*nkglBufferData)(GLenum, GLsizeiptr, const GLvoid*, GLenum); -typedef void(*nkglBufferSubData)(GLenum, GLintptr, GLsizeiptr, const GLvoid*); -typedef void*(*nkglMapBuffer)(GLenum, GLenum); -typedef GLboolean(*nkglUnmapBuffer)(GLenum); -typedef void(*nkglDeleteBuffers)(GLsizei, GLuint*); -/* GL_ARB_vertex_array_object */ -typedef void (*nkglGenVertexArrays)(GLsizei, GLuint*); -typedef void (*nkglBindVertexArray)(GLuint); -typedef void (*nkglDeleteVertexArrays)(GLsizei, const GLuint*); -/* GL_ARB_vertex_program / GL_ARB_fragment_program */ -typedef void(*nkglVertexAttribPointer)(GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid*); -typedef void(*nkglEnableVertexAttribArray)(GLuint); -typedef void(*nkglDisableVertexAttribArray)(GLuint); -/* GL_ARB_framebuffer_object */ -typedef void(*nkglGenerateMipmap)(GLenum target); -/* GLSL/OpenGL 2.0 core */ -typedef GLuint(*nkglCreateShader)(GLenum); -typedef void(*nkglShaderSource)(GLuint, GLsizei, const GLchar**, const GLint*); -typedef void(*nkglCompileShader)(GLuint); -typedef void(*nkglGetShaderiv)(GLuint, GLenum, GLint*); -typedef void(*nkglGetShaderInfoLog)(GLuint, GLsizei, GLsizei*, GLchar*); -typedef void(*nkglDeleteShader)(GLuint); -typedef GLuint(*nkglCreateProgram)(void); -typedef void(*nkglAttachShader)(GLuint, GLuint); -typedef void(*nkglDetachShader)(GLuint, GLuint); -typedef void(*nkglLinkProgram)(GLuint); -typedef void(*nkglUseProgram)(GLuint); -typedef void(*nkglGetProgramiv)(GLuint, GLenum, GLint*); -typedef void(*nkglGetProgramInfoLog)(GLuint, GLsizei, GLsizei*, GLchar*); -typedef void(*nkglDeleteProgram)(GLuint); -typedef GLint(*nkglGetUniformLocation)(GLuint, const GLchar*); -typedef GLint(*nkglGetAttribLocation)(GLuint, const GLchar*); -typedef void(*nkglUniform1i)(GLint, GLint); -typedef void(*nkglUniform1f)(GLint, GLfloat); -typedef void(*nkglUniformMatrix3fv)(GLint, GLsizei, GLboolean, const GLfloat*); -typedef void(*nkglUniformMatrix4fv)(GLint, GLsizei, GLboolean, const GLfloat*); - -static nkglGenBuffers glGenBuffers; -static nkglBindBuffer glBindBuffer; -static nkglBufferData glBufferData; -static nkglBufferSubData glBufferSubData; -static nkglMapBuffer glMapBuffer; -static nkglUnmapBuffer glUnmapBuffer; -static nkglDeleteBuffers glDeleteBuffers; -static nkglGenVertexArrays glGenVertexArrays; -static nkglBindVertexArray glBindVertexArray; -static nkglDeleteVertexArrays glDeleteVertexArrays; -static nkglVertexAttribPointer glVertexAttribPointer; -static nkglEnableVertexAttribArray glEnableVertexAttribArray; -static nkglDisableVertexAttribArray glDisableVertexAttribArray; -static nkglGenerateMipmap glGenerateMipmap; -static nkglCreateShader glCreateShader; -static nkglShaderSource glShaderSource; -static nkglCompileShader glCompileShader; -static nkglGetShaderiv glGetShaderiv; -static nkglGetShaderInfoLog glGetShaderInfoLog; -static nkglDeleteShader glDeleteShader; -static nkglCreateProgram glCreateProgram; -static nkglAttachShader glAttachShader; -static nkglDetachShader glDetachShader; -static nkglLinkProgram glLinkProgram; -static nkglUseProgram glUseProgram; -static nkglGetProgramiv glGetProgramiv; -static nkglGetProgramInfoLog glGetProgramInfoLog; -static nkglDeleteProgram glDeleteProgram; -static nkglGetUniformLocation glGetUniformLocation; -static nkglGetAttribLocation glGetAttribLocation; -static nkglUniform1i glUniform1i; -static nkglUniform1f glUniform1f; -static nkglUniformMatrix3fv glUniformMatrix3fv; -static nkglUniformMatrix4fv glUniformMatrix4fv; - -enum graphics_card_vendors { - VENDOR_UNKNOWN, - VENDOR_NVIDIA, - VENDOR_AMD, - VENDOR_INTEL -}; - -struct opengl_info { - /* info */ - const char *vendor_str; - const char *version_str; - const char *extensions_str; - const char *renderer_str; - const char *glsl_version_str; - enum graphics_card_vendors vendor; - /* version */ - float version; - int major_version; - int minor_version; - /* extensions */ - int glsl_available; - int vertex_buffer_obj_available; - int vertex_array_obj_available; - int map_buffer_range_available; - int fragment_program_available; - int frame_buffer_object_available; -}; -#endif - -struct nk_x11_vertex { - float position[2]; - float uv[2]; - nk_byte col[4]; -}; - -struct nk_x11_device { -#ifdef NK_XLIB_LOAD_OPENGL_EXTENSIONS - struct opengl_info info; -#endif - struct nk_buffer cmds; - struct nk_draw_null_texture null; - GLuint vbo, vao, ebo; - GLuint prog; - GLuint vert_shdr; - GLuint frag_shdr; - GLint attrib_pos; - GLint attrib_uv; - GLint attrib_col; - GLint uniform_tex; - GLint uniform_proj; - GLuint font_tex; -}; - -static struct nk_x11 { - struct nk_x11_device ogl; - struct nk_context ctx; - struct nk_font_atlas atlas; - Cursor cursor; - Display *dpy; - Window win; -} x11; - -#ifdef __APPLE__ - #define NK_SHADER_VERSION "#version 150\n" -#else - #define NK_SHADER_VERSION "#version 300 es\n" -#endif - -#ifdef NK_XLIB_LOAD_OPENGL_EXTENSIONS -#include - -NK_INTERN int -nk_x11_stricmpn(const char *a, const char *b, int len) -{ - int i = 0; - for (i = 0; i < len && a[i] && b[i]; ++i) - if (a[i] != b[i]) return 1; - if (i != len) return 1; - return 0; -} - -NK_INTERN int -nk_x11_check_extension(struct opengl_info *GL, const char *ext) -{ - const char *start, *where, *term; - where = strchr(ext, ' '); - if (where || *ext == '\0') - return FALSE; - - for (start = GL->extensions_str;;) { - where = strstr((const char*)start, ext); - if (!where) break; - term = where + strlen(ext); - if (where == start || *(where - 1) == ' ') { - if (*term == ' ' || *term == '\0') - return TRUE; - } - start = term; - } - return FALSE; -} - -#define GL_EXT(name) (nk##name)nk_gl_ext(#name) -NK_INTERN __GLXextFuncPtr -nk_gl_ext(const char *name) -{ - __GLXextFuncPtr func; - func = glXGetProcAddress((const GLubyte*)name); - if (!func) { - fprintf(stdout, "[GL]: failed to load extension: %s", name); - return NULL; - } - return func; -} - -NK_INTERN int -nk_load_opengl(struct opengl_info *gl) -{ - int failed = FALSE; - gl->version_str = (const char*)glGetString(GL_VERSION); - glGetIntegerv(GL_MAJOR_VERSION, &gl->major_version); - glGetIntegerv(GL_MINOR_VERSION, &gl->minor_version); - if (gl->major_version < 2) { - fprintf(stderr, "[GL]: Graphics card does not fullfill minimum OpenGL 2.0 support\n"); - return 0; - } - - gl->version = (float)gl->major_version + (float)gl->minor_version * 0.1f; - gl->renderer_str = (const char*)glGetString(GL_RENDERER); - gl->extensions_str = (const char*)glGetString(GL_EXTENSIONS); - gl->glsl_version_str = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION); - gl->vendor_str = (const char*)glGetString(GL_VENDOR); - if (!nk_x11_stricmpn(gl->vendor_str, "ATI", 4) || - !nk_x11_stricmpn(gl->vendor_str, "AMD", 4)) - gl->vendor = VENDOR_AMD; - else if (!nk_x11_stricmpn(gl->vendor_str, "NVIDIA", 6)) - gl->vendor = VENDOR_NVIDIA; - else if (!nk_x11_stricmpn(gl->vendor_str, "Intel", 5)) - gl->vendor = VENDOR_INTEL; - else gl->vendor = VENDOR_UNKNOWN; - - /* Extensions */ - gl->glsl_available = (gl->version >= 2.0f); - if (gl->glsl_available) { - /* GLSL core in OpenGL > 2 */ - glCreateShader = GL_EXT(glCreateShader); - glShaderSource = GL_EXT(glShaderSource); - glCompileShader = GL_EXT(glCompileShader); - glGetShaderiv = GL_EXT(glGetShaderiv); - glGetShaderInfoLog = GL_EXT(glGetShaderInfoLog); - glDeleteShader = GL_EXT(glDeleteShader); - glCreateProgram = GL_EXT(glCreateProgram); - glAttachShader = GL_EXT(glAttachShader); - glDetachShader = GL_EXT(glDetachShader); - glLinkProgram = GL_EXT(glLinkProgram); - glUseProgram = GL_EXT(glUseProgram); - glGetProgramiv = GL_EXT(glGetProgramiv); - glGetProgramInfoLog = GL_EXT(glGetProgramInfoLog); - glDeleteProgram = GL_EXT(glDeleteProgram); - glGetUniformLocation = GL_EXT(glGetUniformLocation); - glGetAttribLocation = GL_EXT(glGetAttribLocation); - glUniform1i = GL_EXT(glUniform1i); - glUniform1f = GL_EXT(glUniform1f); - glUniformMatrix3fv = GL_EXT(glUniformMatrix3fv); - glUniformMatrix4fv = GL_EXT(glUniformMatrix4fv); - } - gl->vertex_buffer_obj_available = nk_x11_check_extension(gl, "GL_ARB_vertex_buffer_object"); - if (gl->vertex_buffer_obj_available) { - /* GL_ARB_vertex_buffer_object */ - glGenBuffers = GL_EXT(glGenBuffers); - glBindBuffer = GL_EXT(glBindBuffer); - glBufferData = GL_EXT(glBufferData); - glBufferSubData = GL_EXT(glBufferSubData); - glMapBuffer = GL_EXT(glMapBuffer); - glUnmapBuffer = GL_EXT(glUnmapBuffer); - glDeleteBuffers = GL_EXT(glDeleteBuffers); - } - gl->fragment_program_available = nk_x11_check_extension(gl, "GL_ARB_fragment_program"); - if (gl->fragment_program_available) { - /* GL_ARB_vertex_program / GL_ARB_fragment_program */ - glVertexAttribPointer = GL_EXT(glVertexAttribPointer); - glEnableVertexAttribArray = GL_EXT(glEnableVertexAttribArray); - glDisableVertexAttribArray = GL_EXT(glDisableVertexAttribArray); - } - gl->vertex_array_obj_available = nk_x11_check_extension(gl, "GL_ARB_vertex_array_object"); - if (gl->vertex_array_obj_available) { - /* GL_ARB_vertex_array_object */ - glGenVertexArrays = GL_EXT(glGenVertexArrays); - glBindVertexArray = GL_EXT(glBindVertexArray); - glDeleteVertexArrays = GL_EXT(glDeleteVertexArrays); - } - gl->frame_buffer_object_available = nk_x11_check_extension(gl, "GL_ARB_framebuffer_object"); - if (gl->frame_buffer_object_available) { - /* GL_ARB_framebuffer_object */ - glGenerateMipmap = GL_EXT(glGenerateMipmap); - } - if (!gl->vertex_buffer_obj_available) { - fprintf(stdout, "[GL] Error: GL_ARB_vertex_buffer_object is not available!\n"); - failed = TRUE; - } - if (!gl->fragment_program_available) { - fprintf(stdout, "[GL] Error: GL_ARB_fragment_program is not available!\n"); - failed = TRUE; - } - if (!gl->vertex_array_obj_available) { - fprintf(stdout, "[GL] Error: GL_ARB_vertex_array_object is not available!\n"); - failed = TRUE; - } - if (!gl->frame_buffer_object_available) { - fprintf(stdout, "[GL] Error: GL_ARB_framebuffer_object is not available!\n"); - failed = TRUE; - } - return !failed; -} -#endif - -NK_API int -nk_x11_device_create(void) -{ - GLint status; - static const GLchar *vertex_shader = - NK_SHADER_VERSION - "uniform mat4 ProjMtx;\n" - "in vec2 Position;\n" - "in vec2 TexCoord;\n" - "in vec4 Color;\n" - "out vec2 Frag_UV;\n" - "out vec4 Frag_Color;\n" - "void main() {\n" - " Frag_UV = TexCoord;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy, 0, 1);\n" - "}\n"; - static const GLchar *fragment_shader = - NK_SHADER_VERSION - "precision mediump float;\n" - "uniform sampler2D Texture;\n" - "in vec2 Frag_UV;\n" - "in vec4 Frag_Color;\n" - "out vec4 Out_Color;\n" - "void main(){\n" - " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" - "}\n"; - - struct nk_x11_device *dev = &x11.ogl; -#ifdef NK_XLIB_LOAD_OPENGL_EXTENSIONS - if (!nk_load_opengl(&dev->info)) return 0; -#endif - nk_buffer_init_default(&dev->cmds); - - dev->prog = glCreateProgram(); - dev->vert_shdr = glCreateShader(GL_VERTEX_SHADER); - dev->frag_shdr = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(dev->vert_shdr, 1, &vertex_shader, 0); - glShaderSource(dev->frag_shdr, 1, &fragment_shader, 0); - glCompileShader(dev->vert_shdr); - glCompileShader(dev->frag_shdr); - glGetShaderiv(dev->vert_shdr, GL_COMPILE_STATUS, &status); - assert(status == GL_TRUE); - glGetShaderiv(dev->frag_shdr, GL_COMPILE_STATUS, &status); - assert(status == GL_TRUE); - glAttachShader(dev->prog, dev->vert_shdr); - glAttachShader(dev->prog, dev->frag_shdr); - glLinkProgram(dev->prog); - glGetProgramiv(dev->prog, GL_LINK_STATUS, &status); - assert(status == GL_TRUE); - - dev->uniform_tex = glGetUniformLocation(dev->prog, "Texture"); - dev->uniform_proj = glGetUniformLocation(dev->prog, "ProjMtx"); - dev->attrib_pos = glGetAttribLocation(dev->prog, "Position"); - dev->attrib_uv = glGetAttribLocation(dev->prog, "TexCoord"); - dev->attrib_col = glGetAttribLocation(dev->prog, "Color"); - - { - /* buffer setup */ - GLsizei vs = sizeof(struct nk_x11_vertex); - size_t vp = offsetof(struct nk_x11_vertex, position); - size_t vt = offsetof(struct nk_x11_vertex, uv); - size_t vc = offsetof(struct nk_x11_vertex, col); - - glGenBuffers(1, &dev->vbo); - glGenBuffers(1, &dev->ebo); - glGenVertexArrays(1, &dev->vao); - - glBindVertexArray(dev->vao); - glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); - - glEnableVertexAttribArray((GLuint)dev->attrib_pos); - glEnableVertexAttribArray((GLuint)dev->attrib_uv); - glEnableVertexAttribArray((GLuint)dev->attrib_col); - - glVertexAttribPointer((GLuint)dev->attrib_pos, 2, GL_FLOAT, GL_FALSE, vs, (void*)vp); - glVertexAttribPointer((GLuint)dev->attrib_uv, 2, GL_FLOAT, GL_FALSE, vs, (void*)vt); - glVertexAttribPointer((GLuint)dev->attrib_col, 4, GL_UNSIGNED_BYTE, GL_TRUE, vs, (void*)vc); - } - - glBindTexture(GL_TEXTURE_2D, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindVertexArray(0); - return 1; -} - -NK_INTERN void -nk_x11_device_upload_atlas(const void *image, int width, int height) -{ - struct nk_x11_device *dev = &x11.ogl; - glGenTextures(1, &dev->font_tex); - glBindTexture(GL_TEXTURE_2D, dev->font_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, image); -} - -NK_API void -nk_x11_device_destroy(void) -{ - struct nk_x11_device *dev = &x11.ogl; - glDetachShader(dev->prog, dev->vert_shdr); - glDetachShader(dev->prog, dev->frag_shdr); - glDeleteShader(dev->vert_shdr); - glDeleteShader(dev->frag_shdr); - glDeleteProgram(dev->prog); - glDeleteTextures(1, &dev->font_tex); - glDeleteBuffers(1, &dev->vbo); - glDeleteBuffers(1, &dev->ebo); - nk_buffer_free(&dev->cmds); -} - -NK_API void -nk_x11_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_buffer) -{ - int width, height; - XWindowAttributes attr; - struct nk_x11_device *dev = &x11.ogl; - GLfloat ortho[4][4] = { - {2.0f, 0.0f, 0.0f, 0.0f}, - {0.0f,-2.0f, 0.0f, 0.0f}, - {0.0f, 0.0f,-1.0f, 0.0f}, - {-1.0f,1.0f, 0.0f, 1.0f}, - }; - XGetWindowAttributes(x11.dpy, x11.win, &attr); - width = attr.width; - height = attr.height; - - ortho[0][0] /= (GLfloat)width; - ortho[1][1] /= (GLfloat)height; - - /* setup global state */ - glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glActiveTexture(GL_TEXTURE0); - - /* setup program */ - glUseProgram(dev->prog); - glUniform1i(dev->uniform_tex, 0); - glUniformMatrix4fv(dev->uniform_proj, 1, GL_FALSE, &ortho[0][0]); - glViewport(0,0,(GLsizei)width,(GLsizei)height); - { - /* convert from command queue into draw list and draw to screen */ - const struct nk_draw_command *cmd; - void *vertices, *elements; - const nk_draw_index *offset = NULL; - - /* allocate vertex and element buffer */ - glBindVertexArray(dev->vao); - glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); - - glBufferData(GL_ARRAY_BUFFER, max_vertex_buffer, NULL, GL_STREAM_DRAW); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, max_element_buffer, NULL, GL_STREAM_DRAW); - - /* load draw vertices & elements directly into vertex + element buffer */ - vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - elements = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); - { - /* fill convert configuration */ - struct nk_convert_config config; - static const struct nk_draw_vertex_layout_element vertex_layout[] = { - {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_x11_vertex, position)}, - {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_x11_vertex, uv)}, - {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_x11_vertex, col)}, - {NK_VERTEX_LAYOUT_END} - }; - NK_MEMSET(&config, 0, sizeof(config)); - config.vertex_layout = vertex_layout; - config.vertex_size = sizeof(struct nk_x11_vertex); - config.vertex_alignment = NK_ALIGNOF(struct nk_x11_vertex); - config.null = dev->null; - config.circle_segment_count = 22; - config.curve_segment_count = 22; - config.arc_segment_count = 22; - config.global_alpha = 1.0f; - config.shape_AA = AA; - config.line_AA = AA; - - /* setup buffers to load vertices and elements */ - {struct nk_buffer vbuf, ebuf; - nk_buffer_init_fixed(&vbuf, vertices, (size_t)max_vertex_buffer); - nk_buffer_init_fixed(&ebuf, elements, (size_t)max_element_buffer); - nk_convert(&x11.ctx, &dev->cmds, &vbuf, &ebuf, &config);} - } - glUnmapBuffer(GL_ARRAY_BUFFER); - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - - /* iterate over and execute each draw command */ - nk_draw_foreach(cmd, &x11.ctx, &dev->cmds) - { - if (!cmd->elem_count) continue; - glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id); - glScissor( - (GLint)(cmd->clip_rect.x), - (GLint)((height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h))), - (GLint)(cmd->clip_rect.w), - (GLint)(cmd->clip_rect.h)); - glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset); - offset += cmd->elem_count; - } - nk_clear(&x11.ctx); - } - - /* default OpenGL state */ - glUseProgram(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindVertexArray(0); - glDisable(GL_BLEND); - glDisable(GL_SCISSOR_TEST); -} - -NK_API void -nk_x11_font_stash_begin(struct nk_font_atlas **atlas) -{ - nk_font_atlas_init_default(&x11.atlas); - nk_font_atlas_begin(&x11.atlas); - *atlas = &x11.atlas; -} - -NK_API void -nk_x11_font_stash_end(void) -{ - const void *image; int w, h; - image = nk_font_atlas_bake(&x11.atlas, &w, &h, NK_FONT_ATLAS_RGBA32); - nk_x11_device_upload_atlas(image, w, h); - nk_font_atlas_end(&x11.atlas, nk_handle_id((int)x11.ogl.font_tex), &x11.ogl.null); - if (x11.atlas.default_font) - nk_style_set_font(&x11.ctx, &x11.atlas.default_font->handle); -} - -NK_API int -nk_x11_handle_event(XEvent *evt) -{ - struct nk_context *ctx = &x11.ctx; - - /* optional grabbing behavior */ - if (ctx->input.mouse.grab) { - XDefineCursor(x11.dpy, x11.win, x11.cursor); - ctx->input.mouse.grab = 0; - } else if (ctx->input.mouse.ungrab) { - XWarpPointer(x11.dpy, None, x11.win, 0, 0, 0, 0, - (int)ctx->input.mouse.pos.x, (int)ctx->input.mouse.pos.y); - XUndefineCursor(x11.dpy, x11.win); - ctx->input.mouse.ungrab = 0; - } - - if (evt->type == KeyPress || evt->type == KeyRelease) - { - /* Key handler */ - int ret, down = (evt->type == KeyPress); - KeySym *code = XGetKeyboardMapping(x11.dpy, (KeyCode)evt->xkey.keycode, 1, &ret); - if (*code == XK_Shift_L || *code == XK_Shift_R) nk_input_key(ctx, NK_KEY_SHIFT, down); - else if (*code == XK_Delete) nk_input_key(ctx, NK_KEY_DEL, down); - else if (*code == XK_Return) nk_input_key(ctx, NK_KEY_ENTER, down); - else if (*code == XK_Tab) nk_input_key(ctx, NK_KEY_TAB, down); - else if (*code == XK_Left) nk_input_key(ctx, NK_KEY_LEFT, down); - else if (*code == XK_Right) nk_input_key(ctx, NK_KEY_RIGHT, down); - else if (*code == XK_Up) nk_input_key(ctx, NK_KEY_UP, down); - else if (*code == XK_Down) nk_input_key(ctx, NK_KEY_DOWN, down); - else if (*code == XK_BackSpace) nk_input_key(ctx, NK_KEY_BACKSPACE, down); - else if (*code == XK_space && !down) nk_input_char(ctx, ' '); - else if (*code == XK_Page_Up) nk_input_key(ctx, NK_KEY_SCROLL_UP, down); - else if (*code == XK_Page_Down) nk_input_key(ctx, NK_KEY_SCROLL_DOWN, down); - else if (*code == XK_Home) { - nk_input_key(ctx, NK_KEY_TEXT_START, down); - nk_input_key(ctx, NK_KEY_SCROLL_START, down); - } else if (*code == XK_End) { - nk_input_key(ctx, NK_KEY_TEXT_END, down); - nk_input_key(ctx, NK_KEY_SCROLL_END, down); - } else { - if (*code == 'c' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_COPY, down); - else if (*code == 'v' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_PASTE, down); - else if (*code == 'x' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_CUT, down); - else if (*code == 'z' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_TEXT_UNDO, down); - else if (*code == 'r' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_TEXT_REDO, down); - else if (*code == XK_Left && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, down); - else if (*code == XK_Right && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, down); - else if (*code == 'b' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down); - else if (*code == 'e' && (evt->xkey.state & ControlMask)) - nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down); - else { - if (*code == 'i') - nk_input_key(ctx, NK_KEY_TEXT_INSERT_MODE, down); - else if (*code == 'r') - nk_input_key(ctx, NK_KEY_TEXT_REPLACE_MODE, down); - if (down) { - char buf[32]; - KeySym keysym = 0; - if (XLookupString((XKeyEvent*)evt, buf, 32, &keysym, NULL) != NoSymbol) - nk_input_glyph(ctx, buf); - } - } - } - XFree(code); - return 1; - } else if (evt->type == ButtonPress || evt->type == ButtonRelease) { - /* Button handler */ - int down = (evt->type == ButtonPress); - const int x = evt->xbutton.x, y = evt->xbutton.y; - if (evt->xbutton.button == Button1) - nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down); - if (evt->xbutton.button == Button2) - nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down); - else if (evt->xbutton.button == Button3) - nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down); - else if (evt->xbutton.button == Button4) - nk_input_scroll(ctx, 1.0f); - else if (evt->xbutton.button == Button5) - nk_input_scroll(ctx, -1.0f); - else return 0; - return 1; - } else if (evt->type == MotionNotify) { - /* Mouse motion handler */ - const int x = evt->xmotion.x, y = evt->xmotion.y; - nk_input_motion(ctx, x, y); - if (ctx->input.mouse.grabbed) { - ctx->input.mouse.pos.x = ctx->input.mouse.prev.x; - ctx->input.mouse.pos.y = ctx->input.mouse.prev.y; - XWarpPointer(x11.dpy, None, x11.win, 0, 0, 0, 0, (int)ctx->input.mouse.pos.x, (int)ctx->input.mouse.pos.y); - } - return 1; - } else if (evt->type == KeymapNotify) { - XRefreshKeyboardMapping(&evt->xmapping); - return 1; - } - return 0; -} - -NK_API struct nk_context* -nk_x11_init(Display *dpy, Window win) -{ - if (!setlocale(LC_ALL,"")) return 0; - if (!XSupportsLocale()) return 0; - if (!XSetLocaleModifiers("@im=none")) return 0; - if (!nk_x11_device_create()) return 0; - - x11.dpy = dpy; - x11.win = win; - - /* create invisible cursor */ - {static XColor dummy; char data[1] = {0}; - Pixmap blank = XCreateBitmapFromData(dpy, win, data, 1, 1); - if (blank == None) return 0; - x11.cursor = XCreatePixmapCursor(dpy, blank, blank, &dummy, &dummy, 0, 0); - XFreePixmap(dpy, blank);} - - nk_init_default(&x11.ctx, 0); - return &x11.ctx; -} - -NK_API void -nk_x11_shutdown(void) -{ - nk_font_atlas_clear(&x11.atlas); - nk_free(&x11.ctx); - nk_x11_device_destroy(); - XFreeCursor(x11.dpy, x11.cursor); - memset(&x11, 0, sizeof(x11)); -} - -#endif diff --git a/deps/nuklear/example/canvas.c b/deps/nuklear/example/canvas.c deleted file mode 100644 index c5f5634b..00000000 --- a/deps/nuklear/example/canvas.c +++ /dev/null @@ -1,489 +0,0 @@ -/* nuklear - v1.05 - public domain */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define NK_PRIVATE -#define NK_INCLUDE_FIXED_TYPES -#define NK_INCLUDE_STANDARD_IO -#define NK_INCLUDE_DEFAULT_ALLOCATOR -#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT -#define NK_INCLUDE_FONT_BAKING -#define NK_INCLUDE_DEFAULT_FONT -#define NK_IMPLEMENTATION -#include "../nuklear.h" - -#define STB_IMAGE_IMPLEMENTATION -#include "stb_image.h" - -/* macros */ -#define WINDOW_WIDTH 1200 -#define WINDOW_HEIGHT 800 - -#define MAX_VERTEX_MEMORY 512 * 1024 -#define MAX_ELEMENT_MEMORY 128 * 1024 - -#define UNUSED(a) (void)a -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) < (b) ? (b) : (a)) -#define LEN(a) (sizeof(a)/sizeof(a)[0]) - -#define NK_SHADER_VERSION "#version 150\n" - -/* =============================================================== - * - * DEVICE - * - * ===============================================================*/ -struct nk_glfw_vertex { - float position[2]; - float uv[2]; - nk_byte col[4]; -}; - -struct device { - struct nk_buffer cmds; - struct nk_draw_null_texture null; - GLuint vbo, vao, ebo; - GLuint prog; - GLuint vert_shdr; - GLuint frag_shdr; - GLint attrib_pos; - GLint attrib_uv; - GLint attrib_col; - GLint uniform_tex; - GLint uniform_proj; - GLuint font_tex; -}; - -static void -die(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fputs("\n", stderr); - exit(EXIT_FAILURE); -} - -static struct nk_image -icon_load(const char *filename) -{ - int x,y,n; - GLuint tex; - unsigned char *data = stbi_load(filename, &x, &y, &n, 0); - if (!data) die("[SDL]: failed to load image: %s", filename); - - glGenTextures(1, &tex); - glBindTexture(GL_TEXTURE_2D, tex); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - glGenerateMipmap(GL_TEXTURE_2D); - stbi_image_free(data); - return nk_image_id((int)tex); -} - -static void -device_init(struct device *dev) -{ - GLint status; - static const GLchar *vertex_shader = - NK_SHADER_VERSION - "uniform mat4 ProjMtx;\n" - "in vec2 Position;\n" - "in vec2 TexCoord;\n" - "in vec4 Color;\n" - "out vec2 Frag_UV;\n" - "out vec4 Frag_Color;\n" - "void main() {\n" - " Frag_UV = TexCoord;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy, 0, 1);\n" - "}\n"; - static const GLchar *fragment_shader = - NK_SHADER_VERSION - "precision mediump float;\n" - "uniform sampler2D Texture;\n" - "in vec2 Frag_UV;\n" - "in vec4 Frag_Color;\n" - "out vec4 Out_Color;\n" - "void main(){\n" - " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" - "}\n"; - - nk_buffer_init_default(&dev->cmds); - dev->prog = glCreateProgram(); - dev->vert_shdr = glCreateShader(GL_VERTEX_SHADER); - dev->frag_shdr = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(dev->vert_shdr, 1, &vertex_shader, 0); - glShaderSource(dev->frag_shdr, 1, &fragment_shader, 0); - glCompileShader(dev->vert_shdr); - glCompileShader(dev->frag_shdr); - glGetShaderiv(dev->vert_shdr, GL_COMPILE_STATUS, &status); - assert(status == GL_TRUE); - glGetShaderiv(dev->frag_shdr, GL_COMPILE_STATUS, &status); - assert(status == GL_TRUE); - glAttachShader(dev->prog, dev->vert_shdr); - glAttachShader(dev->prog, dev->frag_shdr); - glLinkProgram(dev->prog); - glGetProgramiv(dev->prog, GL_LINK_STATUS, &status); - assert(status == GL_TRUE); - - dev->uniform_tex = glGetUniformLocation(dev->prog, "Texture"); - dev->uniform_proj = glGetUniformLocation(dev->prog, "ProjMtx"); - dev->attrib_pos = glGetAttribLocation(dev->prog, "Position"); - dev->attrib_uv = glGetAttribLocation(dev->prog, "TexCoord"); - dev->attrib_col = glGetAttribLocation(dev->prog, "Color"); - - { - /* buffer setup */ - GLsizei vs = sizeof(struct nk_glfw_vertex); - size_t vp = offsetof(struct nk_glfw_vertex, position); - size_t vt = offsetof(struct nk_glfw_vertex, uv); - size_t vc = offsetof(struct nk_glfw_vertex, col); - - glGenBuffers(1, &dev->vbo); - glGenBuffers(1, &dev->ebo); - glGenVertexArrays(1, &dev->vao); - - glBindVertexArray(dev->vao); - glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); - - glEnableVertexAttribArray((GLuint)dev->attrib_pos); - glEnableVertexAttribArray((GLuint)dev->attrib_uv); - glEnableVertexAttribArray((GLuint)dev->attrib_col); - - glVertexAttribPointer((GLuint)dev->attrib_pos, 2, GL_FLOAT, GL_FALSE, vs, (void*)vp); - glVertexAttribPointer((GLuint)dev->attrib_uv, 2, GL_FLOAT, GL_FALSE, vs, (void*)vt); - glVertexAttribPointer((GLuint)dev->attrib_col, 4, GL_UNSIGNED_BYTE, GL_TRUE, vs, (void*)vc); - } - - glBindTexture(GL_TEXTURE_2D, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindVertexArray(0); -} - -static void -device_upload_atlas(struct device *dev, const void *image, int width, int height) -{ - glGenTextures(1, &dev->font_tex); - glBindTexture(GL_TEXTURE_2D, dev->font_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, image); -} - -static void -device_shutdown(struct device *dev) -{ - glDetachShader(dev->prog, dev->vert_shdr); - glDetachShader(dev->prog, dev->frag_shdr); - glDeleteShader(dev->vert_shdr); - glDeleteShader(dev->frag_shdr); - glDeleteProgram(dev->prog); - glDeleteTextures(1, &dev->font_tex); - glDeleteBuffers(1, &dev->vbo); - glDeleteBuffers(1, &dev->ebo); - nk_buffer_free(&dev->cmds); -} - -static void -device_draw(struct device *dev, struct nk_context *ctx, int width, int height, - enum nk_anti_aliasing AA) -{ - GLfloat ortho[4][4] = { - {2.0f, 0.0f, 0.0f, 0.0f}, - {0.0f,-2.0f, 0.0f, 0.0f}, - {0.0f, 0.0f,-1.0f, 0.0f}, - {-1.0f,1.0f, 0.0f, 1.0f}, - }; - ortho[0][0] /= (GLfloat)width; - ortho[1][1] /= (GLfloat)height; - - /* setup global state */ - glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glActiveTexture(GL_TEXTURE0); - - /* setup program */ - glUseProgram(dev->prog); - glUniform1i(dev->uniform_tex, 0); - glUniformMatrix4fv(dev->uniform_proj, 1, GL_FALSE, &ortho[0][0]); - { - /* convert from command queue into draw list and draw to screen */ - const struct nk_draw_command *cmd; - void *vertices, *elements; - const nk_draw_index *offset = NULL; - - /* allocate vertex and element buffer */ - glBindVertexArray(dev->vao); - glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); - - glBufferData(GL_ARRAY_BUFFER, MAX_VERTEX_MEMORY, NULL, GL_STREAM_DRAW); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_ELEMENT_MEMORY, NULL, GL_STREAM_DRAW); - - /* load draw vertices & elements directly into vertex + element buffer */ - vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - elements = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); - { - /* fill convert configuration */ - struct nk_convert_config config; - static const struct nk_draw_vertex_layout_element vertex_layout[] = { - {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, position)}, - {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, uv)}, - {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_glfw_vertex, col)}, - {NK_VERTEX_LAYOUT_END} - }; - NK_MEMSET(&config, 0, sizeof(config)); - config.vertex_layout = vertex_layout; - config.vertex_size = sizeof(struct nk_glfw_vertex); - config.vertex_alignment = NK_ALIGNOF(struct nk_glfw_vertex); - config.null = dev->null; - config.circle_segment_count = 22; - config.curve_segment_count = 22; - config.arc_segment_count = 22; - config.global_alpha = 1.0f; - config.shape_AA = AA; - config.line_AA = AA; - - /* setup buffers to load vertices and elements */ - {struct nk_buffer vbuf, ebuf; - nk_buffer_init_fixed(&vbuf, vertices, MAX_VERTEX_MEMORY); - nk_buffer_init_fixed(&ebuf, elements, MAX_ELEMENT_MEMORY); - nk_convert(ctx, &dev->cmds, &vbuf, &ebuf, &config);} - } - glUnmapBuffer(GL_ARRAY_BUFFER); - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - - /* iterate over and execute each draw command */ - nk_draw_foreach(cmd, ctx, &dev->cmds) - { - if (!cmd->elem_count) continue; - glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id); - glScissor( - (GLint)(cmd->clip_rect.x), - (GLint)((height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h))), - (GLint)(cmd->clip_rect.w), - (GLint)(cmd->clip_rect.h)); - glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset); - offset += cmd->elem_count; - } - nk_clear(ctx); - } - - /* default OpenGL state */ - glUseProgram(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindVertexArray(0); - glDisable(GL_BLEND); - glDisable(GL_SCISSOR_TEST); -} - -/* glfw callbacks (I don't know if there is a easier way to access text and scroll )*/ -static void error_callback(int e, const char *d){printf("Error %d: %s\n", e, d);} -static void text_input(GLFWwindow *win, unsigned int codepoint) -{nk_input_unicode((struct nk_context*)glfwGetWindowUserPointer(win), codepoint);} -static void scroll_input(GLFWwindow *win, double _, double yoff) -{UNUSED(_);nk_input_scroll((struct nk_context*)glfwGetWindowUserPointer(win), (float)yoff);} - -static void -pump_input(struct nk_context *ctx, GLFWwindow *win) -{ - double x, y; - nk_input_begin(ctx); - glfwPollEvents(); - - nk_input_key(ctx, NK_KEY_DEL, glfwGetKey(win, GLFW_KEY_DELETE) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_ENTER, glfwGetKey(win, GLFW_KEY_ENTER) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_TAB, glfwGetKey(win, GLFW_KEY_TAB) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_BACKSPACE, glfwGetKey(win, GLFW_KEY_BACKSPACE) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_UP, glfwGetKey(win, GLFW_KEY_UP) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_DOWN, glfwGetKey(win, GLFW_KEY_DOWN) == GLFW_PRESS); - - if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS || - glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS) { - nk_input_key(ctx, NK_KEY_COPY, glfwGetKey(win, GLFW_KEY_C) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_PASTE, glfwGetKey(win, GLFW_KEY_P) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_X) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_E) == GLFW_PRESS); - nk_input_key(ctx, NK_KEY_SHIFT, 1); - } else { - nk_input_key(ctx, NK_KEY_COPY, 0); - nk_input_key(ctx, NK_KEY_PASTE, 0); - nk_input_key(ctx, NK_KEY_CUT, 0); - nk_input_key(ctx, NK_KEY_SHIFT, 0); - } - - glfwGetCursorPos(win, &x, &y); - nk_input_motion(ctx, (int)x, (int)y); - nk_input_button(ctx, NK_BUTTON_LEFT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS); - nk_input_button(ctx, NK_BUTTON_MIDDLE, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS); - nk_input_button(ctx, NK_BUTTON_RIGHT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS); - nk_input_end(ctx); -} - -struct nk_canvas { - struct nk_command_buffer *painter; - struct nk_vec2 item_spacing; - struct nk_vec2 panel_padding; - struct nk_style_item window_background; -}; - -static void -canvas_begin(struct nk_context *ctx, struct nk_canvas *canvas, nk_flags flags, - int x, int y, int width, int height, struct nk_color background_color) -{ - /* save style properties which will be overwritten */ - canvas->panel_padding = ctx->style.window.padding; - canvas->item_spacing = ctx->style.window.spacing; - canvas->window_background = ctx->style.window.fixed_background; - - /* use the complete window space and set background */ - ctx->style.window.spacing = nk_vec2(0,0); - ctx->style.window.padding = nk_vec2(0,0); - ctx->style.window.fixed_background = nk_style_item_color(background_color); - - /* create/update window and set position + size */ - flags = flags & ~NK_WINDOW_DYNAMIC; - nk_begin(ctx, "Window", nk_rect(x, y, width, height), NK_WINDOW_NO_SCROLLBAR|flags); - nk_window_set_bounds(ctx, nk_rect(x, y, width, height)); - - /* allocate the complete window space for drawing */ - {struct nk_rect total_space; - total_space = nk_window_get_content_region(ctx); - nk_layout_row_dynamic(ctx, total_space.h, 1); - nk_widget(&total_space, ctx); - canvas->painter = nk_window_get_canvas(ctx);} -} - -static void -canvas_end(struct nk_context *ctx, struct nk_canvas *canvas) -{ - nk_end(ctx); - ctx->style.window.spacing = canvas->panel_padding; - ctx->style.window.padding = canvas->item_spacing; - ctx->style.window.fixed_background = canvas->window_background; -} - -int main(int argc, char *argv[]) -{ - /* Platform */ - static GLFWwindow *win; - int width = 0, height = 0; - - /* GUI */ - struct device device; - struct nk_font_atlas atlas; - struct nk_context ctx; - - /* GLFW */ - glfwSetErrorCallback(error_callback); - if (!glfwInit()) { - fprintf(stdout, "[GFLW] failed to init!\n"); - exit(1); - } - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - win = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Demo", NULL, NULL); - glfwMakeContextCurrent(win); - glfwSetWindowUserPointer(win, &ctx); - glfwSetCharCallback(win, text_input); - glfwSetScrollCallback(win, scroll_input); - glfwGetWindowSize(win, &width, &height); - - /* OpenGL */ - glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); - glewExperimental = 1; - if (glewInit() != GLEW_OK) { - fprintf(stderr, "Failed to setup GLEW\n"); - exit(1); - } - - /* GUI */ - {device_init(&device); - {const void *image; int w, h; - struct nk_font *font; - nk_font_atlas_init_default(&atlas); - nk_font_atlas_begin(&atlas); - font = nk_font_atlas_add_default(&atlas, 13, 0); - image = nk_font_atlas_bake(&atlas, &w, &h, NK_FONT_ATLAS_RGBA32); - device_upload_atlas(&device, image, w, h); - nk_font_atlas_end(&atlas, nk_handle_id((int)device.font_tex), &device.null); - nk_init_default(&ctx, &font->handle); - - glEnable(GL_TEXTURE_2D); - while (!glfwWindowShouldClose(win)) - { - /* input */ - pump_input(&ctx, win); - - /* draw */ - {struct nk_canvas canvas; - canvas_begin(&ctx, &canvas, 0, 0, 0, width, height, nk_rgb(250,250,250)); - { - nk_fill_rect(canvas.painter, nk_rect(15,15,210,210), 5, nk_rgb(247, 230, 154)); - nk_fill_rect(canvas.painter, nk_rect(20,20,200,200), 5, nk_rgb(188, 174, 118)); - nk_draw_text(canvas.painter, nk_rect(30, 30, 150, 20), "Text to draw", 12, &font->handle, nk_rgb(188,174,118), nk_rgb(0,0,0)); - nk_fill_rect(canvas.painter, nk_rect(250,20,100,100), 0, nk_rgb(0,0,255)); - nk_fill_circle(canvas.painter, nk_rect(20,250,100,100), nk_rgb(255,0,0)); - nk_fill_triangle(canvas.painter, 250, 250, 350, 250, 300, 350, nk_rgb(0,255,0)); - nk_fill_arc(canvas.painter, 300, 180, 50, 0, 3.141592654f * 3.0f / 4.0f, nk_rgb(255,255,0)); - - {float points[12]; - points[0] = 200; points[1] = 250; - points[2] = 250; points[3] = 350; - points[4] = 225; points[5] = 350; - points[6] = 200; points[7] = 300; - points[8] = 175; points[9] = 350; - points[10] = 150; points[11] = 350; - nk_fill_polygon(canvas.painter, points, 6, nk_rgb(0,0,0));} - - nk_stroke_line(canvas.painter, 15, 10, 200, 10, 2.0f, nk_rgb(189,45,75)); - nk_stroke_rect(canvas.painter, nk_rect(370, 20, 100, 100), 10, 3, nk_rgb(0,0,255)); - nk_stroke_curve(canvas.painter, 380, 200, 405, 270, 455, 120, 480, 200, 2, nk_rgb(0,150,220)); - nk_stroke_circle(canvas.painter, nk_rect(20, 370, 100, 100), 5, nk_rgb(0,255,120)); - nk_stroke_triangle(canvas.painter, 370, 250, 470, 250, 420, 350, 6, nk_rgb(255,0,143)); - } - canvas_end(&ctx, &canvas);} - - /* Draw */ - glfwGetWindowSize(win, &width, &height); - glViewport(0, 0, width, height); - glClear(GL_COLOR_BUFFER_BIT); - glClearColor(0.2f, 0.2f, 0.2f, 1.0f); - device_draw(&device, &ctx, width, height, NK_ANTI_ALIASING_ON); - glfwSwapBuffers(win); - }}} - nk_font_atlas_clear(&atlas); - nk_free(&ctx); - device_shutdown(&device); - glfwTerminate(); - return 0; -} - diff --git a/deps/nuklear/example/extended.c b/deps/nuklear/example/extended.c deleted file mode 100644 index e555d654..00000000 --- a/deps/nuklear/example/extended.c +++ /dev/null @@ -1,906 +0,0 @@ -/* nuklear - v1.05 - public domain */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define NK_INCLUDE_FIXED_TYPES -#define NK_INCLUDE_STANDARD_IO -#define NK_INCLUDE_DEFAULT_ALLOCATOR -#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT -#define NK_INCLUDE_FONT_BAKING -#define NK_INCLUDE_DEFAULT_FONT -#define NK_IMPLEMENTATION -#include "../nuklear.h" - -#define STB_IMAGE_IMPLEMENTATION -#include "stb_image.h" - -/* macros */ -#define WINDOW_WIDTH 1200 -#define WINDOW_HEIGHT 800 - -#define MAX_VERTEX_MEMORY 512 * 1024 -#define MAX_ELEMENT_MEMORY 128 * 1024 - -#define UNUSED(a) (void)a -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) < (b) ? (b) : (a)) -#define LEN(a) (sizeof(a)/sizeof(a)[0]) - -#ifdef __APPLE__ - #define NK_SHADER_VERSION "#version 150\n" -#else - #define NK_SHADER_VERSION "#version 300 es\n" -#endif - -struct media { - struct nk_font *font_14; - struct nk_font *font_18; - struct nk_font *font_20; - struct nk_font *font_22; - - struct nk_image unchecked; - struct nk_image checked; - struct nk_image rocket; - struct nk_image cloud; - struct nk_image pen; - struct nk_image play; - struct nk_image pause; - struct nk_image stop; - struct nk_image prev; - struct nk_image next; - struct nk_image tools; - struct nk_image dir; - struct nk_image copy; - struct nk_image convert; - struct nk_image del; - struct nk_image edit; - struct nk_image images[9]; - struct nk_image menu[6]; -}; - -/* =============================================================== - * - * CUSTOM WIDGET - * - * ===============================================================*/ -static int -ui_piemenu(struct nk_context *ctx, struct nk_vec2 pos, float radius, - struct nk_image *icons, int item_count) -{ - int ret = -1; - struct nk_rect total_space; - struct nk_rect bounds; - int active_item = 0; - - /* pie menu popup */ - struct nk_color border = ctx->style.window.border_color; - struct nk_style_item background = ctx->style.window.fixed_background; - ctx->style.window.fixed_background = nk_style_item_hide(); - ctx->style.window.border_color = nk_rgba(0,0,0,0); - - total_space = nk_window_get_content_region(ctx); - ctx->style.window.spacing = nk_vec2(0,0); - ctx->style.window.padding = nk_vec2(0,0); - - if (nk_popup_begin(ctx, NK_POPUP_STATIC, "piemenu", NK_WINDOW_NO_SCROLLBAR, - nk_rect(pos.x - total_space.x - radius, pos.y - radius - total_space.y, - 2*radius,2*radius))) - { - int i = 0; - struct nk_command_buffer* out = nk_window_get_canvas(ctx); - const struct nk_input *in = &ctx->input; - - total_space = nk_window_get_content_region(ctx); - ctx->style.window.spacing = nk_vec2(4,4); - ctx->style.window.padding = nk_vec2(8,8); - nk_layout_row_dynamic(ctx, total_space.h, 1); - nk_widget(&bounds, ctx); - - /* outer circle */ - nk_fill_circle(out, bounds, nk_rgb(50,50,50)); - { - /* circle buttons */ - float step = (2 * 3.141592654f) / (float)(MAX(1,item_count)); - float a_min = 0; float a_max = step; - - struct nk_vec2 center = nk_vec2(bounds.x + bounds.w / 2.0f, bounds.y + bounds.h / 2.0f); - struct nk_vec2 drag = nk_vec2(in->mouse.pos.x - center.x, in->mouse.pos.y - center.y); - float angle = (float)atan2(drag.y, drag.x); - if (angle < -0.0f) angle += 2.0f * 3.141592654f; - active_item = (int)(angle/step); - - for (i = 0; i < item_count; ++i) { - struct nk_rect content; - float rx, ry, dx, dy, a; - nk_fill_arc(out, center.x, center.y, (bounds.w/2.0f), - a_min, a_max, (active_item == i) ? nk_rgb(45,100,255): nk_rgb(60,60,60)); - - /* separator line */ - rx = bounds.w/2.0f; ry = 0; - dx = rx * (float)cos(a_min) - ry * (float)sin(a_min); - dy = rx * (float)sin(a_min) + ry * (float)cos(a_min); - nk_stroke_line(out, center.x, center.y, - center.x + dx, center.y + dy, 1.0f, nk_rgb(50,50,50)); - - /* button content */ - a = a_min + (a_max - a_min)/2.0f; - rx = bounds.w/2.5f; ry = 0; - content.w = 30; content.h = 30; - content.x = center.x + ((rx * (float)cos(a) - ry * (float)sin(a)) - content.w/2.0f); - content.y = center.y + (rx * (float)sin(a) + ry * (float)cos(a) - content.h/2.0f); - nk_draw_image(out, content, &icons[i], nk_rgb(255,255,255)); - a_min = a_max; a_max += step; - } - } - { - /* inner circle */ - struct nk_rect inner; - inner.x = bounds.x + bounds.w/2 - bounds.w/4; - inner.y = bounds.y + bounds.h/2 - bounds.h/4; - inner.w = bounds.w/2; inner.h = bounds.h/2; - nk_fill_circle(out, inner, nk_rgb(45,45,45)); - - /* active icon content */ - bounds.w = inner.w / 2.0f; - bounds.h = inner.h / 2.0f; - bounds.x = inner.x + inner.w/2 - bounds.w/2; - bounds.y = inner.y + inner.h/2 - bounds.h/2; - nk_draw_image(out, bounds, &icons[active_item], nk_rgb(255,255,255)); - } - nk_layout_space_end(ctx); - if (!nk_input_is_mouse_down(&ctx->input, NK_BUTTON_RIGHT)) { - nk_popup_close(ctx); - ret = active_item; - } - } else ret = -2; - ctx->style.window.spacing = nk_vec2(4,4); - ctx->style.window.padding = nk_vec2(8,8); - nk_popup_end(ctx); - - ctx->style.window.fixed_background = background; - ctx->style.window.border_color = border; - return ret; -} - -/* =============================================================== - * - * GRID - * - * ===============================================================*/ -static void -grid_demo(struct nk_context *ctx, struct media *media) -{ - static char text[3][64]; - static int text_len[3]; - static const char *items[] = {"Item 0","item 1","item 2"}; - static int selected_item = 0; - static int check = 1; - - int i; - nk_style_set_font(ctx, &media->font_20->handle); - if (nk_begin(ctx, "Grid Demo", nk_rect(600, 350, 275, 250), - NK_WINDOW_TITLE|NK_WINDOW_BORDER|NK_WINDOW_MOVABLE| - NK_WINDOW_NO_SCROLLBAR)) - { - nk_style_set_font(ctx, &media->font_18->handle); - nk_layout_row_dynamic(ctx, 30, 2); - nk_label(ctx, "Floating point:", NK_TEXT_RIGHT); - nk_edit_string(ctx, NK_EDIT_FIELD, text[0], &text_len[0], 64, nk_filter_float); - nk_label(ctx, "Hexadecimal:", NK_TEXT_RIGHT); - nk_edit_string(ctx, NK_EDIT_FIELD, text[1], &text_len[1], 64, nk_filter_hex); - nk_label(ctx, "Binary:", NK_TEXT_RIGHT); - nk_edit_string(ctx, NK_EDIT_FIELD, text[2], &text_len[2], 64, nk_filter_binary); - nk_label(ctx, "Checkbox:", NK_TEXT_RIGHT); - nk_checkbox_label(ctx, "Check me", &check); - nk_label(ctx, "Combobox:", NK_TEXT_RIGHT); - if (nk_combo_begin_label(ctx, items[selected_item], nk_vec2(nk_widget_width(ctx), 200))) { - nk_layout_row_dynamic(ctx, 25, 1); - for (i = 0; i < 3; ++i) - if (nk_combo_item_label(ctx, items[i], NK_TEXT_LEFT)) - selected_item = i; - nk_combo_end(ctx); - } - } - nk_end(ctx); - nk_style_set_font(ctx, &media->font_14->handle); -} - -/* =============================================================== - * - * BUTTON DEMO - * - * ===============================================================*/ -static void -ui_header(struct nk_context *ctx, struct media *media, const char *title) -{ - nk_style_set_font(ctx, &media->font_18->handle); - nk_layout_row_dynamic(ctx, 20, 1); - nk_label(ctx, title, NK_TEXT_LEFT); -} - -static void -ui_widget(struct nk_context *ctx, struct media *media, float height) -{ - static const float ratio[] = {0.15f, 0.85f}; - nk_style_set_font(ctx, &media->font_22->handle); - nk_layout_row(ctx, NK_DYNAMIC, height, 2, ratio); - nk_spacing(ctx, 1); -} - -static void -ui_widget_centered(struct nk_context *ctx, struct media *media, float height) -{ - static const float ratio[] = {0.15f, 0.50f, 0.35f}; - nk_style_set_font(ctx, &media->font_22->handle); - nk_layout_row(ctx, NK_DYNAMIC, height, 3, ratio); - nk_spacing(ctx, 1); -} - -static void -button_demo(struct nk_context *ctx, struct media *media) -{ - static int option = 1; - static int toggle0 = 1; - static int toggle1 = 0; - static int toggle2 = 1; - - nk_style_set_font(ctx, &media->font_20->handle); - nk_begin(ctx, "Button Demo", nk_rect(50,50,255,610), - NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_TITLE); - - /*------------------------------------------------ - * MENU - *------------------------------------------------*/ - nk_menubar_begin(ctx); - { - /* toolbar */ - nk_layout_row_static(ctx, 40, 40, 4); - if (nk_menu_begin_image(ctx, "Music", media->play, nk_vec2(110,120))) - { - /* settings */ - nk_layout_row_dynamic(ctx, 25, 1); - nk_menu_item_image_label(ctx, media->play, "Play", NK_TEXT_RIGHT); - nk_menu_item_image_label(ctx, media->stop, "Stop", NK_TEXT_RIGHT); - nk_menu_item_image_label(ctx, media->pause, "Pause", NK_TEXT_RIGHT); - nk_menu_item_image_label(ctx, media->next, "Next", NK_TEXT_RIGHT); - nk_menu_item_image_label(ctx, media->prev, "Prev", NK_TEXT_RIGHT); - nk_menu_end(ctx); - } - nk_button_image(ctx, media->tools); - nk_button_image(ctx, media->cloud); - nk_button_image(ctx, media->pen); - } - nk_menubar_end(ctx); - - /*------------------------------------------------ - * BUTTON - *------------------------------------------------*/ - ui_header(ctx, media, "Push buttons"); - ui_widget(ctx, media, 35); - if (nk_button_label(ctx, "Push me")) - fprintf(stdout, "pushed!\n"); - ui_widget(ctx, media, 35); - if (nk_button_image_label(ctx, media->rocket, "Styled", NK_TEXT_CENTERED)) - fprintf(stdout, "rocket!\n"); - - /*------------------------------------------------ - * REPEATER - *------------------------------------------------*/ - ui_header(ctx, media, "Repeater"); - ui_widget(ctx, media, 35); - if (nk_button_label(ctx, "Press me")) - fprintf(stdout, "pressed!\n"); - - /*------------------------------------------------ - * TOGGLE - *------------------------------------------------*/ - ui_header(ctx, media, "Toggle buttons"); - ui_widget(ctx, media, 35); - if (nk_button_image_label(ctx, (toggle0) ? media->checked: media->unchecked, "Toggle", NK_TEXT_LEFT)) - toggle0 = !toggle0; - - ui_widget(ctx, media, 35); - if (nk_button_image_label(ctx, (toggle1) ? media->checked: media->unchecked, "Toggle", NK_TEXT_LEFT)) - toggle1 = !toggle1; - - ui_widget(ctx, media, 35); - if (nk_button_image_label(ctx, (toggle2) ? media->checked: media->unchecked, "Toggle", NK_TEXT_LEFT)) - toggle2 = !toggle2; - - /*------------------------------------------------ - * RADIO - *------------------------------------------------*/ - ui_header(ctx, media, "Radio buttons"); - ui_widget(ctx, media, 35); - if (nk_button_symbol_label(ctx, (option == 0)?NK_SYMBOL_CIRCLE_OUTLINE:NK_SYMBOL_CIRCLE_SOLID, "Select", NK_TEXT_LEFT)) - option = 0; - ui_widget(ctx, media, 35); - if (nk_button_symbol_label(ctx, (option == 1)?NK_SYMBOL_CIRCLE_OUTLINE:NK_SYMBOL_CIRCLE_SOLID, "Select", NK_TEXT_LEFT)) - option = 1; - ui_widget(ctx, media, 35); - if (nk_button_symbol_label(ctx, (option == 2)?NK_SYMBOL_CIRCLE_OUTLINE:NK_SYMBOL_CIRCLE_SOLID, "Select", NK_TEXT_LEFT)) - option = 2; - - /*------------------------------------------------ - * CONTEXTUAL - *------------------------------------------------*/ - nk_style_set_font(ctx, &media->font_18->handle); - if (nk_contextual_begin(ctx, NK_WINDOW_NO_SCROLLBAR, nk_vec2(150, 300), nk_window_get_bounds(ctx))) { - nk_layout_row_dynamic(ctx, 30, 1); - if (nk_contextual_item_image_label(ctx, media->copy, "Clone", NK_TEXT_RIGHT)) - fprintf(stdout, "pressed clone!\n"); - if (nk_contextual_item_image_label(ctx, media->del, "Delete", NK_TEXT_RIGHT)) - fprintf(stdout, "pressed delete!\n"); - if (nk_contextual_item_image_label(ctx, media->convert, "Convert", NK_TEXT_RIGHT)) - fprintf(stdout, "pressed convert!\n"); - if (nk_contextual_item_image_label(ctx, media->edit, "Edit", NK_TEXT_RIGHT)) - fprintf(stdout, "pressed edit!\n"); - nk_contextual_end(ctx); - } - nk_style_set_font(ctx, &media->font_14->handle); - nk_end(ctx); -} - -/* =============================================================== - * - * BASIC DEMO - * - * ===============================================================*/ -static void -basic_demo(struct nk_context *ctx, struct media *media) -{ - static int image_active; - static int check0 = 1; - static int check1 = 0; - static size_t prog = 80; - static int selected_item = 0; - static int selected_image = 3; - static int selected_icon = 0; - static const char *items[] = {"Item 0","item 1","item 2"}; - static int piemenu_active = 0; - static struct nk_vec2 piemenu_pos; - - int i = 0; - nk_style_set_font(ctx, &media->font_20->handle); - nk_begin(ctx, "Basic Demo", nk_rect(320, 50, 275, 610), - NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_TITLE); - - /*------------------------------------------------ - * POPUP BUTTON - *------------------------------------------------*/ - ui_header(ctx, media, "Popup & Scrollbar & Images"); - ui_widget(ctx, media, 35); - if (nk_button_image_label(ctx, media->dir, "Images", NK_TEXT_CENTERED)) - image_active = !image_active; - - /*------------------------------------------------ - * SELECTED IMAGE - *------------------------------------------------*/ - ui_header(ctx, media, "Selected Image"); - ui_widget_centered(ctx, media, 100); - nk_image(ctx, media->images[selected_image]); - - /*------------------------------------------------ - * IMAGE POPUP - *------------------------------------------------*/ - if (image_active) { - struct nk_panel popup; - if (nk_popup_begin(ctx, NK_POPUP_STATIC, "Image Popup", 0, nk_rect(265, 0, 320, 220))) { - nk_layout_row_static(ctx, 82, 82, 3); - for (i = 0; i < 9; ++i) { - if (nk_button_image(ctx, media->images[i])) { - selected_image = i; - image_active = 0; - nk_popup_close(ctx); - } - } - nk_popup_end(ctx); - } - } - /*------------------------------------------------ - * COMBOBOX - *------------------------------------------------*/ - ui_header(ctx, media, "Combo box"); - ui_widget(ctx, media, 40); - if (nk_combo_begin_label(ctx, items[selected_item], nk_vec2(nk_widget_width(ctx), 200))) { - nk_layout_row_dynamic(ctx, 35, 1); - for (i = 0; i < 3; ++i) - if (nk_combo_item_label(ctx, items[i], NK_TEXT_LEFT)) - selected_item = i; - nk_combo_end(ctx); - } - - ui_widget(ctx, media, 40); - if (nk_combo_begin_image_label(ctx, items[selected_icon], media->images[selected_icon], nk_vec2(nk_widget_width(ctx), 200))) { - nk_layout_row_dynamic(ctx, 35, 1); - for (i = 0; i < 3; ++i) - if (nk_combo_item_image_label(ctx, media->images[i], items[i], NK_TEXT_RIGHT)) - selected_icon = i; - nk_combo_end(ctx); - } - - /*------------------------------------------------ - * CHECKBOX - *------------------------------------------------*/ - ui_header(ctx, media, "Checkbox"); - ui_widget(ctx, media, 30); - nk_checkbox_label(ctx, "Flag 1", &check0); - ui_widget(ctx, media, 30); - nk_checkbox_label(ctx, "Flag 2", &check1); - - /*------------------------------------------------ - * PROGRESSBAR - *------------------------------------------------*/ - ui_header(ctx, media, "Progressbar"); - ui_widget(ctx, media, 35); - nk_progress(ctx, &prog, 100, nk_true); - - /*------------------------------------------------ - * PIEMENU - *------------------------------------------------*/ - if (nk_input_is_mouse_click_down_in_rect(&ctx->input, NK_BUTTON_RIGHT, - nk_window_get_bounds(ctx),nk_true)){ - piemenu_pos = ctx->input.mouse.pos; - piemenu_active = 1; - } - - if (piemenu_active) { - int ret = ui_piemenu(ctx, piemenu_pos, 140, &media->menu[0], 6); - if (ret == -2) piemenu_active = 0; - if (ret != -1) { - fprintf(stdout, "piemenu selected: %d\n", ret); - piemenu_active = 0; - } - } - nk_style_set_font(ctx, &media->font_14->handle); - nk_end(ctx); -} - -/* =============================================================== - * - * DEVICE - * - * ===============================================================*/ -struct nk_glfw_vertex { - float position[2]; - float uv[2]; - nk_byte col[4]; -}; - -struct device { - struct nk_buffer cmds; - struct nk_draw_null_texture null; - GLuint vbo, vao, ebo; - GLuint prog; - GLuint vert_shdr; - GLuint frag_shdr; - GLint attrib_pos; - GLint attrib_uv; - GLint attrib_col; - GLint uniform_tex; - GLint uniform_proj; - GLuint font_tex; -}; - -static void -die(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fputs("\n", stderr); - exit(EXIT_FAILURE); -} - -static struct nk_image -icon_load(const char *filename) -{ - int x,y,n; - GLuint tex; - unsigned char *data = stbi_load(filename, &x, &y, &n, 0); - if (!data) die("[SDL]: failed to load image: %s", filename); - - glGenTextures(1, &tex); - glBindTexture(GL_TEXTURE_2D, tex); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - glGenerateMipmap(GL_TEXTURE_2D); - stbi_image_free(data); - return nk_image_id((int)tex); -} - -static void -device_init(struct device *dev) -{ - GLint status; - static const GLchar *vertex_shader = - NK_SHADER_VERSION - "uniform mat4 ProjMtx;\n" - "in vec2 Position;\n" - "in vec2 TexCoord;\n" - "in vec4 Color;\n" - "out vec2 Frag_UV;\n" - "out vec4 Frag_Color;\n" - "void main() {\n" - " Frag_UV = TexCoord;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy, 0, 1);\n" - "}\n"; - static const GLchar *fragment_shader = - NK_SHADER_VERSION - "precision mediump float;\n" - "uniform sampler2D Texture;\n" - "in vec2 Frag_UV;\n" - "in vec4 Frag_Color;\n" - "out vec4 Out_Color;\n" - "void main(){\n" - " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" - "}\n"; - - nk_buffer_init_default(&dev->cmds); - dev->prog = glCreateProgram(); - dev->vert_shdr = glCreateShader(GL_VERTEX_SHADER); - dev->frag_shdr = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(dev->vert_shdr, 1, &vertex_shader, 0); - glShaderSource(dev->frag_shdr, 1, &fragment_shader, 0); - glCompileShader(dev->vert_shdr); - glCompileShader(dev->frag_shdr); - glGetShaderiv(dev->vert_shdr, GL_COMPILE_STATUS, &status); - assert(status == GL_TRUE); - glGetShaderiv(dev->frag_shdr, GL_COMPILE_STATUS, &status); - assert(status == GL_TRUE); - glAttachShader(dev->prog, dev->vert_shdr); - glAttachShader(dev->prog, dev->frag_shdr); - glLinkProgram(dev->prog); - glGetProgramiv(dev->prog, GL_LINK_STATUS, &status); - assert(status == GL_TRUE); - - dev->uniform_tex = glGetUniformLocation(dev->prog, "Texture"); - dev->uniform_proj = glGetUniformLocation(dev->prog, "ProjMtx"); - dev->attrib_pos = glGetAttribLocation(dev->prog, "Position"); - dev->attrib_uv = glGetAttribLocation(dev->prog, "TexCoord"); - dev->attrib_col = glGetAttribLocation(dev->prog, "Color"); - - { - /* buffer setup */ - GLsizei vs = sizeof(struct nk_glfw_vertex); - size_t vp = offsetof(struct nk_glfw_vertex, position); - size_t vt = offsetof(struct nk_glfw_vertex, uv); - size_t vc = offsetof(struct nk_glfw_vertex, col); - - glGenBuffers(1, &dev->vbo); - glGenBuffers(1, &dev->ebo); - glGenVertexArrays(1, &dev->vao); - - glBindVertexArray(dev->vao); - glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); - - glEnableVertexAttribArray((GLuint)dev->attrib_pos); - glEnableVertexAttribArray((GLuint)dev->attrib_uv); - glEnableVertexAttribArray((GLuint)dev->attrib_col); - - glVertexAttribPointer((GLuint)dev->attrib_pos, 2, GL_FLOAT, GL_FALSE, vs, (void*)vp); - glVertexAttribPointer((GLuint)dev->attrib_uv, 2, GL_FLOAT, GL_FALSE, vs, (void*)vt); - glVertexAttribPointer((GLuint)dev->attrib_col, 4, GL_UNSIGNED_BYTE, GL_TRUE, vs, (void*)vc); - } - - glBindTexture(GL_TEXTURE_2D, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindVertexArray(0); -} - -static void -device_upload_atlas(struct device *dev, const void *image, int width, int height) -{ - glGenTextures(1, &dev->font_tex); - glBindTexture(GL_TEXTURE_2D, dev->font_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, image); -} - -static void -device_shutdown(struct device *dev) -{ - glDetachShader(dev->prog, dev->vert_shdr); - glDetachShader(dev->prog, dev->frag_shdr); - glDeleteShader(dev->vert_shdr); - glDeleteShader(dev->frag_shdr); - glDeleteProgram(dev->prog); - glDeleteTextures(1, &dev->font_tex); - glDeleteBuffers(1, &dev->vbo); - glDeleteBuffers(1, &dev->ebo); - nk_buffer_free(&dev->cmds); -} - -static void -device_draw(struct device *dev, struct nk_context *ctx, int width, int height, - struct nk_vec2 scale, enum nk_anti_aliasing AA) -{ - GLfloat ortho[4][4] = { - {2.0f, 0.0f, 0.0f, 0.0f}, - {0.0f,-2.0f, 0.0f, 0.0f}, - {0.0f, 0.0f,-1.0f, 0.0f}, - {-1.0f,1.0f, 0.0f, 1.0f}, - }; - ortho[0][0] /= (GLfloat)width; - ortho[1][1] /= (GLfloat)height; - - /* setup global state */ - glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glActiveTexture(GL_TEXTURE0); - - /* setup program */ - glUseProgram(dev->prog); - glUniform1i(dev->uniform_tex, 0); - glUniformMatrix4fv(dev->uniform_proj, 1, GL_FALSE, &ortho[0][0]); - { - /* convert from command queue into draw list and draw to screen */ - const struct nk_draw_command *cmd; - void *vertices, *elements; - const nk_draw_index *offset = NULL; - - /* allocate vertex and element buffer */ - glBindVertexArray(dev->vao); - glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); - - glBufferData(GL_ARRAY_BUFFER, MAX_VERTEX_MEMORY, NULL, GL_STREAM_DRAW); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_ELEMENT_MEMORY, NULL, GL_STREAM_DRAW); - - /* load draw vertices & elements directly into vertex + element buffer */ - vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - elements = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); - { - /* fill convert configuration */ - struct nk_convert_config config; - static const struct nk_draw_vertex_layout_element vertex_layout[] = { - {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, position)}, - {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, uv)}, - {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_glfw_vertex, col)}, - {NK_VERTEX_LAYOUT_END} - }; - NK_MEMSET(&config, 0, sizeof(config)); - config.vertex_layout = vertex_layout; - config.vertex_size = sizeof(struct nk_glfw_vertex); - config.vertex_alignment = NK_ALIGNOF(struct nk_glfw_vertex); - config.null = dev->null; - config.circle_segment_count = 22; - config.curve_segment_count = 22; - config.arc_segment_count = 22; - config.global_alpha = 1.0f; - config.shape_AA = AA; - config.line_AA = AA; - - /* setup buffers to load vertices and elements */ - {struct nk_buffer vbuf, ebuf; - nk_buffer_init_fixed(&vbuf, vertices, MAX_VERTEX_MEMORY); - nk_buffer_init_fixed(&ebuf, elements, MAX_ELEMENT_MEMORY); - nk_convert(ctx, &dev->cmds, &vbuf, &ebuf, &config);} - } - glUnmapBuffer(GL_ARRAY_BUFFER); - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - - /* iterate over and execute each draw command */ - nk_draw_foreach(cmd, ctx, &dev->cmds) - { - if (!cmd->elem_count) continue; - glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id); - glScissor( - (GLint)(cmd->clip_rect.x * scale.x), - (GLint)((height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * scale.y), - (GLint)(cmd->clip_rect.w * scale.x), - (GLint)(cmd->clip_rect.h * scale.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset); - offset += cmd->elem_count; - } - nk_clear(ctx); - } - - /* default OpenGL state */ - glUseProgram(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindVertexArray(0); - glDisable(GL_BLEND); - glDisable(GL_SCISSOR_TEST); -} - -/* glfw callbacks (I don't know if there is a easier way to access text and scroll )*/ -static void error_callback(int e, const char *d){printf("Error %d: %s\n", e, d);} -static void text_input(GLFWwindow *win, unsigned int codepoint) -{nk_input_unicode((struct nk_context*)glfwGetWindowUserPointer(win), codepoint);} -static void scroll_input(GLFWwindow *win, double _, double yoff) -{UNUSED(_);nk_input_scroll((struct nk_context*)glfwGetWindowUserPointer(win), (float)yoff);} - -int main(int argc, char *argv[]) -{ - /* Platform */ - static GLFWwindow *win; - int width = 0, height = 0; - int display_width=0, display_height=0; - - /* GUI */ - struct device device; - struct nk_font_atlas atlas; - struct media media; - struct nk_context ctx; - - /* GLFW */ - glfwSetErrorCallback(error_callback); - if (!glfwInit()) { - fprintf(stdout, "[GFLW] failed to init!\n"); - exit(1); - } - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); -#ifdef __APPLE__ - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); -#endif - win = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Demo", NULL, NULL); - glfwMakeContextCurrent(win); - glfwSetWindowUserPointer(win, &ctx); - glfwSetCharCallback(win, text_input); - glfwSetScrollCallback(win, scroll_input); - glfwGetWindowSize(win, &width, &height); - glfwGetFramebufferSize(win, &display_width, &display_height); - - /* OpenGL */ - glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); - glewExperimental = 1; - if (glewInit() != GLEW_OK) { - fprintf(stderr, "Failed to setup GLEW\n"); - exit(1); - } - - {/* GUI */ - device_init(&device); - {const void *image; int w, h; - struct nk_font_config cfg = nk_font_config(0); - cfg.oversample_h = 3; cfg.oversample_v = 2; - /* Loading one font with different heights is only required if you want higher - * quality text otherwise you can just set the font height directly - * e.g.: ctx->style.font.height = 20. */ - nk_font_atlas_init_default(&atlas); - nk_font_atlas_begin(&atlas); - media.font_14 = nk_font_atlas_add_from_file(&atlas, "../../extra_font/Roboto-Regular.ttf", 14.0f, &cfg); - media.font_18 = nk_font_atlas_add_from_file(&atlas, "../../extra_font/Roboto-Regular.ttf", 18.0f, &cfg); - media.font_20 = nk_font_atlas_add_from_file(&atlas, "../../extra_font/Roboto-Regular.ttf", 20.0f, &cfg); - media.font_22 = nk_font_atlas_add_from_file(&atlas, "../../extra_font/Roboto-Regular.ttf", 22.0f, &cfg); - image = nk_font_atlas_bake(&atlas, &w, &h, NK_FONT_ATLAS_RGBA32); - device_upload_atlas(&device, image, w, h); - nk_font_atlas_end(&atlas, nk_handle_id((int)device.font_tex), &device.null);} - nk_init_default(&ctx, &media.font_14->handle);} - - /* icons */ - glEnable(GL_TEXTURE_2D); - media.unchecked = icon_load("../icon/unchecked.png"); - media.checked = icon_load("../icon/checked.png"); - media.rocket = icon_load("../icon/rocket.png"); - media.cloud = icon_load("../icon/cloud.png"); - media.pen = icon_load("../icon/pen.png"); - media.play = icon_load("../icon/play.png"); - media.pause = icon_load("../icon/pause.png"); - media.stop = icon_load("../icon/stop.png"); - media.next = icon_load("../icon/next.png"); - media.prev = icon_load("../icon/prev.png"); - media.tools = icon_load("../icon/tools.png"); - media.dir = icon_load("../icon/directory.png"); - media.copy = icon_load("../icon/copy.png"); - media.convert = icon_load("../icon/export.png"); - media.del = icon_load("../icon/delete.png"); - media.edit = icon_load("../icon/edit.png"); - media.menu[0] = icon_load("../icon/home.png"); - media.menu[1] = icon_load("../icon/phone.png"); - media.menu[2] = icon_load("../icon/plane.png"); - media.menu[3] = icon_load("../icon/wifi.png"); - media.menu[4] = icon_load("../icon/settings.png"); - media.menu[5] = icon_load("../icon/volume.png"); - - {int i; - for (i = 0; i < 9; ++i) { - char buffer[256]; - sprintf(buffer, "../images/image%d.png", (i+1)); - media.images[i] = icon_load(buffer); - }} - - while (!glfwWindowShouldClose(win)) - { - /* High DPI displays */ - struct nk_vec2 scale; - glfwGetWindowSize(win, &width, &height); - glfwGetFramebufferSize(win, &display_width, &display_height); - scale.x = (float)display_width/(float)width; - scale.y = (float)display_height/(float)height; - - /* Input */ - {double x, y; - nk_input_begin(&ctx); - glfwPollEvents(); - nk_input_key(&ctx, NK_KEY_DEL, glfwGetKey(win, GLFW_KEY_DELETE) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_ENTER, glfwGetKey(win, GLFW_KEY_ENTER) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_TAB, glfwGetKey(win, GLFW_KEY_TAB) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_BACKSPACE, glfwGetKey(win, GLFW_KEY_BACKSPACE) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_UP, glfwGetKey(win, GLFW_KEY_UP) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_DOWN, glfwGetKey(win, GLFW_KEY_DOWN) == GLFW_PRESS); - if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS || - glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS) { - nk_input_key(&ctx, NK_KEY_COPY, glfwGetKey(win, GLFW_KEY_C) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_PASTE, glfwGetKey(win, GLFW_KEY_P) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_X) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_E) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_SHIFT, 1); - } else { - nk_input_key(&ctx, NK_KEY_COPY, 0); - nk_input_key(&ctx, NK_KEY_PASTE, 0); - nk_input_key(&ctx, NK_KEY_CUT, 0); - nk_input_key(&ctx, NK_KEY_SHIFT, 0); - } - glfwGetCursorPos(win, &x, &y); - nk_input_motion(&ctx, (int)x, (int)y); - nk_input_button(&ctx, NK_BUTTON_LEFT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS); - nk_input_button(&ctx, NK_BUTTON_MIDDLE, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS); - nk_input_button(&ctx, NK_BUTTON_RIGHT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS); - nk_input_end(&ctx);} - - /* GUI */ - basic_demo(&ctx, &media); - button_demo(&ctx, &media); - grid_demo(&ctx, &media); - - /* Draw */ - glViewport(0, 0, display_width, display_height); - glClear(GL_COLOR_BUFFER_BIT); - glClearColor(0.3f, 0.3f, 0.3f, 1.0f); - device_draw(&device, &ctx, width, height, scale, NK_ANTI_ALIASING_ON); - glfwSwapBuffers(win); - } - - glDeleteTextures(1,(const GLuint*)&media.unchecked.handle.id); - glDeleteTextures(1,(const GLuint*)&media.checked.handle.id); - glDeleteTextures(1,(const GLuint*)&media.rocket.handle.id); - glDeleteTextures(1,(const GLuint*)&media.cloud.handle.id); - glDeleteTextures(1,(const GLuint*)&media.pen.handle.id); - glDeleteTextures(1,(const GLuint*)&media.play.handle.id); - glDeleteTextures(1,(const GLuint*)&media.pause.handle.id); - glDeleteTextures(1,(const GLuint*)&media.stop.handle.id); - glDeleteTextures(1,(const GLuint*)&media.next.handle.id); - glDeleteTextures(1,(const GLuint*)&media.prev.handle.id); - glDeleteTextures(1,(const GLuint*)&media.tools.handle.id); - glDeleteTextures(1,(const GLuint*)&media.dir.handle.id); - glDeleteTextures(1,(const GLuint*)&media.del.handle.id); - - nk_font_atlas_clear(&atlas); - nk_free(&ctx); - - device_shutdown(&device); - glfwTerminate(); - return 0; -} - diff --git a/deps/nuklear/example/file_browser.c b/deps/nuklear/example/file_browser.c deleted file mode 100644 index ece4cb83..00000000 --- a/deps/nuklear/example/file_browser.c +++ /dev/null @@ -1,910 +0,0 @@ -/* nuklear - v1.05 - public domain */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define NK_INCLUDE_FIXED_TYPES -#define NK_INCLUDE_STANDARD_IO -#define NK_INCLUDE_DEFAULT_ALLOCATOR -#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT -#define NK_INCLUDE_FONT_BAKING -#define NK_INCLUDE_DEFAULT_FONT -#define NK_IMPLEMENTATION -#include "../nuklear.h" - -#define STB_IMAGE_IMPLEMENTATION -#include "stb_image.h" - -/* macros */ -#define WINDOW_WIDTH 1200 -#define WINDOW_HEIGHT 800 - -#define MAX_VERTEX_MEMORY 512 * 1024 -#define MAX_ELEMENT_MEMORY 128 * 1024 - -#define UNUSED(a) (void)a -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) < (b) ? (b) : (a)) -#define LEN(a) (sizeof(a)/sizeof(a)[0]) - -#ifdef __APPLE__ - #define NK_SHADER_VERSION "#version 150\n" -#else - #define NK_SHADER_VERSION "#version 300 es\n" -#endif - -/* =============================================================== - * - * GUI - * - * ===============================================================*/ -struct icons { - struct nk_image desktop; - struct nk_image home; - struct nk_image computer; - struct nk_image directory; - - struct nk_image default_file; - struct nk_image text_file; - struct nk_image music_file; - struct nk_image font_file; - struct nk_image img_file; - struct nk_image movie_file; -}; - -enum file_groups { - FILE_GROUP_DEFAULT, - FILE_GROUP_TEXT, - FILE_GROUP_MUSIC, - FILE_GROUP_FONT, - FILE_GROUP_IMAGE, - FILE_GROUP_MOVIE, - FILE_GROUP_MAX -}; - -enum file_types { - FILE_DEFAULT, - FILE_TEXT, - FILE_C_SOURCE, - FILE_CPP_SOURCE, - FILE_HEADER, - FILE_CPP_HEADER, - FILE_MP3, - FILE_WAV, - FILE_OGG, - FILE_TTF, - FILE_BMP, - FILE_PNG, - FILE_JPEG, - FILE_PCX, - FILE_TGA, - FILE_GIF, - FILE_MAX -}; - -struct file_group { - enum file_groups group; - const char *name; - struct nk_image *icon; -}; - -struct file { - enum file_types type; - const char *suffix; - enum file_groups group; -}; - -struct media { - int font; - int icon_sheet; - struct icons icons; - struct file_group group[FILE_GROUP_MAX]; - struct file files[FILE_MAX]; -}; - -#define MAX_PATH_LEN 512 -struct file_browser { - /* path */ - char file[MAX_PATH_LEN]; - char home[MAX_PATH_LEN]; - char desktop[MAX_PATH_LEN]; - char directory[MAX_PATH_LEN]; - - /* directory content */ - char **files; - char **directories; - size_t file_count; - size_t dir_count; - struct media *media; -}; - -#ifdef __unix__ -#include -#include -#endif - -#ifndef _WIN32 -# include -#endif - -static void -die(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fputs("\n", stderr); - exit(EXIT_FAILURE); -} - -static char* -file_load(const char* path, size_t* siz) -{ - char *buf; - FILE *fd = fopen(path, "rb"); - if (!fd) die("Failed to open file: %s\n", path); - fseek(fd, 0, SEEK_END); - *siz = (size_t)ftell(fd); - fseek(fd, 0, SEEK_SET); - buf = (char*)calloc(*siz, 1); - fread(buf, *siz, 1, fd); - fclose(fd); - return buf; -} - -static char* -str_duplicate(const char *src) -{ - char *ret; - size_t len = strlen(src); - if (!len) return 0; - ret = (char*)malloc(len+1); - if (!ret) return 0; - memcpy(ret, src, len); - ret[len] = '\0'; - return ret; -} - -static void -dir_free_list(char **list, size_t size) -{ - size_t i; - for (i = 0; i < size; ++i) - free(list[i]); - free(list); -} - -static char** -dir_list(const char *dir, int return_subdirs, size_t *count) -{ - size_t n = 0; - char buffer[MAX_PATH_LEN]; - char **results = NULL; - const DIR *none = NULL; - size_t capacity = 32; - size_t size; - DIR *z; - - assert(dir); - assert(count); - strncpy(buffer, dir, MAX_PATH_LEN); - n = strlen(buffer); - - if (n > 0 && (buffer[n-1] != '/')) - buffer[n++] = '/'; - - size = 0; - - z = opendir(dir); - if (z != none) { - int nonempty = 1; - struct dirent *data = readdir(z); - nonempty = (data != NULL); - if (!nonempty) return NULL; - - do { - DIR *y; - char *p; - int is_subdir; - if (data->d_name[0] == '.') - continue; - - strncpy(buffer + n, data->d_name, MAX_PATH_LEN-n); - y = opendir(buffer); - is_subdir = (y != NULL); - if (y != NULL) closedir(y); - - if ((return_subdirs && is_subdir) || (!is_subdir && !return_subdirs)){ - if (!size) { - results = (char**)calloc(sizeof(char*), capacity); - } else if (size >= capacity) { - void *old = results; - capacity = capacity * 2; - results = (char**)realloc(results, capacity * sizeof(char*)); - assert(results); - if (!results) free(old); - } - p = str_duplicate(data->d_name); - results[size++] = p; - } - } while ((data = readdir(z)) != NULL); - } - - if (z) closedir(z); - *count = size; - return results; -} - -static struct file_group -FILE_GROUP(enum file_groups group, const char *name, struct nk_image *icon) -{ - struct file_group fg; - fg.group = group; - fg.name = name; - fg.icon = icon; - return fg; -} - -static struct file -FILE_DEF(enum file_types type, const char *suffix, enum file_groups group) -{ - struct file fd; - fd.type = type; - fd.suffix = suffix; - fd.group = group; - return fd; -} - -static struct nk_image* -media_icon_for_file(struct media *media, const char *file) -{ - int i = 0; - const char *s = file; - char suffix[4]; - int found = 0; - memset(suffix, 0, sizeof(suffix)); - - /* extract suffix .xxx from file */ - while (*s++ != '\0') { - if (found && i < 3) - suffix[i++] = *s; - - if (*s == '.') { - if (found){ - found = 0; - break; - } - found = 1; - } - } - - /* check for all file definition of all groups for fitting suffix*/ - for (i = 0; i < FILE_MAX && found; ++i) { - struct file *d = &media->files[i]; - { - const char *f = d->suffix; - s = suffix; - while (f && *f && *s && *s == *f) { - s++; f++; - } - - /* found correct file definition so */ - if (f && *s == '\0' && *f == '\0') - return media->group[d->group].icon; - } - } - return &media->icons.default_file; -} - -static void -media_init(struct media *media) -{ - /* file groups */ - struct icons *icons = &media->icons; - media->group[FILE_GROUP_DEFAULT] = FILE_GROUP(FILE_GROUP_DEFAULT,"default",&icons->default_file); - media->group[FILE_GROUP_TEXT] = FILE_GROUP(FILE_GROUP_TEXT, "textual", &icons->text_file); - media->group[FILE_GROUP_MUSIC] = FILE_GROUP(FILE_GROUP_MUSIC, "music", &icons->music_file); - media->group[FILE_GROUP_FONT] = FILE_GROUP(FILE_GROUP_FONT, "font", &icons->font_file); - media->group[FILE_GROUP_IMAGE] = FILE_GROUP(FILE_GROUP_IMAGE, "image", &icons->img_file); - media->group[FILE_GROUP_MOVIE] = FILE_GROUP(FILE_GROUP_MOVIE, "movie", &icons->movie_file); - - /* files */ - media->files[FILE_DEFAULT] = FILE_DEF(FILE_DEFAULT, NULL, FILE_GROUP_DEFAULT); - media->files[FILE_TEXT] = FILE_DEF(FILE_TEXT, "txt", FILE_GROUP_TEXT); - media->files[FILE_C_SOURCE] = FILE_DEF(FILE_C_SOURCE, "c", FILE_GROUP_TEXT); - media->files[FILE_CPP_SOURCE] = FILE_DEF(FILE_CPP_SOURCE, "cpp", FILE_GROUP_TEXT); - media->files[FILE_HEADER] = FILE_DEF(FILE_HEADER, "h", FILE_GROUP_TEXT); - media->files[FILE_CPP_HEADER] = FILE_DEF(FILE_HEADER, "hpp", FILE_GROUP_TEXT); - media->files[FILE_MP3] = FILE_DEF(FILE_MP3, "mp3", FILE_GROUP_MUSIC); - media->files[FILE_WAV] = FILE_DEF(FILE_WAV, "wav", FILE_GROUP_MUSIC); - media->files[FILE_OGG] = FILE_DEF(FILE_OGG, "ogg", FILE_GROUP_MUSIC); - media->files[FILE_TTF] = FILE_DEF(FILE_TTF, "ttf", FILE_GROUP_FONT); - media->files[FILE_BMP] = FILE_DEF(FILE_BMP, "bmp", FILE_GROUP_IMAGE); - media->files[FILE_PNG] = FILE_DEF(FILE_PNG, "png", FILE_GROUP_IMAGE); - media->files[FILE_JPEG] = FILE_DEF(FILE_JPEG, "jpg", FILE_GROUP_IMAGE); - media->files[FILE_PCX] = FILE_DEF(FILE_PCX, "pcx", FILE_GROUP_IMAGE); - media->files[FILE_TGA] = FILE_DEF(FILE_TGA, "tga", FILE_GROUP_IMAGE); - media->files[FILE_GIF] = FILE_DEF(FILE_GIF, "gif", FILE_GROUP_IMAGE); -} - -static void -file_browser_reload_directory_content(struct file_browser *browser, const char *path) -{ - strncpy(browser->directory, path, MAX_PATH_LEN); - dir_free_list(browser->files, browser->file_count); - dir_free_list(browser->directories, browser->dir_count); - browser->files = dir_list(path, 0, &browser->file_count); - browser->directories = dir_list(path, 1, &browser->dir_count); -} - -static void -file_browser_init(struct file_browser *browser, struct media *media) -{ - memset(browser, 0, sizeof(*browser)); - browser->media = media; - { - /* load files and sub-directory list */ - const char *home = getenv("HOME"); -#ifdef _WIN32 - if (!home) home = getenv("USERPROFILE"); -#else - if (!home) home = getpwuid(getuid())->pw_dir; - { - size_t l; - strncpy(browser->home, home, MAX_PATH_LEN); - l = strlen(browser->home); - strcpy(browser->home + l, "/"); - strcpy(browser->directory, browser->home); - } -#endif - { - size_t l; - strcpy(browser->desktop, browser->home); - l = strlen(browser->desktop); - strcpy(browser->desktop + l, "desktop/"); - } - browser->files = dir_list(browser->directory, 0, &browser->file_count); - browser->directories = dir_list(browser->directory, 1, &browser->dir_count); - } -} - -static void -file_browser_free(struct file_browser *browser) -{ - if (browser->files) - dir_free_list(browser->files, browser->file_count); - if (browser->directories) - dir_free_list(browser->directories, browser->dir_count); - browser->files = NULL; - browser->directories = NULL; - memset(browser, 0, sizeof(*browser)); -} - -static int -file_browser_run(struct file_browser *browser, struct nk_context *ctx) -{ - int ret = 0; - struct media *media = browser->media; - struct nk_rect total_space; - - if (nk_begin(ctx, "File Browser", nk_rect(50, 50, 800, 600), - NK_WINDOW_BORDER|NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_MOVABLE)) - { - static float ratio[] = {0.25f, NK_UNDEFINED}; - float spacing_x = ctx->style.window.spacing.x; - - /* output path directory selector in the menubar */ - ctx->style.window.spacing.x = 0; - nk_menubar_begin(ctx); - { - char *d = browser->directory; - char *begin = d + 1; - nk_layout_row_dynamic(ctx, 25, 6); - while (*d++) { - if (*d == '/') { - *d = '\0'; - if (nk_button_label(ctx, begin)) { - *d++ = '/'; *d = '\0'; - file_browser_reload_directory_content(browser, browser->directory); - break; - } - *d = '/'; - begin = d + 1; - } - } - } - nk_menubar_end(ctx); - ctx->style.window.spacing.x = spacing_x; - - /* window layout */ - total_space = nk_window_get_content_region(ctx); - nk_layout_row(ctx, NK_DYNAMIC, total_space.h, 2, ratio); - nk_group_begin(ctx, "Special", NK_WINDOW_NO_SCROLLBAR); - { - struct nk_image home = media->icons.home; - struct nk_image desktop = media->icons.desktop; - struct nk_image computer = media->icons.computer; - - nk_layout_row_dynamic(ctx, 40, 1); - if (nk_button_image_label(ctx, home, "home", NK_TEXT_CENTERED)) - file_browser_reload_directory_content(browser, browser->home); - if (nk_button_image_label(ctx,desktop,"desktop",NK_TEXT_CENTERED)) - file_browser_reload_directory_content(browser, browser->desktop); - if (nk_button_image_label(ctx,computer,"computer",NK_TEXT_CENTERED)) - file_browser_reload_directory_content(browser, "/"); - nk_group_end(ctx); - } - - /* output directory content window */ - nk_group_begin(ctx, "Content", 0); - { - int index = -1; - size_t i = 0, j = 0, k = 0; - size_t rows = 0, cols = 0; - size_t count = browser->dir_count + browser->file_count; - - cols = 4; - rows = count / cols; - for (i = 0; i <= rows; i += 1) { - {size_t n = j + cols; - nk_layout_row_dynamic(ctx, 135, (int)cols); - for (; j < count && j < n; ++j) { - /* draw one row of icons */ - if (j < browser->dir_count) { - /* draw and execute directory buttons */ - if (nk_button_image(ctx,media->icons.directory)) - index = (int)j; - } else { - /* draw and execute files buttons */ - struct nk_image *icon; - size_t fileIndex = ((size_t)j - browser->dir_count); - icon = media_icon_for_file(media,browser->files[fileIndex]); - if (nk_button_image(ctx, *icon)) { - strncpy(browser->file, browser->directory, MAX_PATH_LEN); - n = strlen(browser->file); - strncpy(browser->file + n, browser->files[fileIndex], MAX_PATH_LEN - n); - ret = 1; - } - } - }} - {size_t n = k + cols; - nk_layout_row_dynamic(ctx, 20, (int)cols); - for (; k < count && k < n; k++) { - /* draw one row of labels */ - if (k < browser->dir_count) { - nk_label(ctx, browser->directories[k], NK_TEXT_CENTERED); - } else { - size_t t = k-browser->dir_count; - nk_label(ctx,browser->files[t],NK_TEXT_CENTERED); - } - }} - } - - if (index != -1) { - size_t n = strlen(browser->directory); - strncpy(browser->directory + n, browser->directories[index], MAX_PATH_LEN - n); - n = strlen(browser->directory); - if (n < MAX_PATH_LEN - 1) { - browser->directory[n] = '/'; - browser->directory[n+1] = '\0'; - } - file_browser_reload_directory_content(browser, browser->directory); - } - nk_group_end(ctx); - } - } - nk_end(ctx); - return ret; -} - -/* =============================================================== - * - * DEVICE - * - * ===============================================================*/ -struct nk_glfw_vertex { - float position[2]; - float uv[2]; - nk_byte col[4]; -}; - -struct device { - struct nk_buffer cmds; - struct nk_draw_null_texture null; - GLuint vbo, vao, ebo; - GLuint prog; - GLuint vert_shdr; - GLuint frag_shdr; - GLint attrib_pos; - GLint attrib_uv; - GLint attrib_col; - GLint uniform_tex; - GLint uniform_proj; - GLuint font_tex; -}; -static struct nk_image -icon_load(const char *filename) -{ - int x,y,n; - GLuint tex; - unsigned char *data = stbi_load(filename, &x, &y, &n, 0); - if (!data) die("[SDL]: failed to load image: %s", filename); - - glGenTextures(1, &tex); - glBindTexture(GL_TEXTURE_2D, tex); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - glGenerateMipmap(GL_TEXTURE_2D); - stbi_image_free(data); - return nk_image_id((int)tex); -} - -static void -device_init(struct device *dev) -{ - GLint status; - static const GLchar *vertex_shader = - NK_SHADER_VERSION - "uniform mat4 ProjMtx;\n" - "in vec2 Position;\n" - "in vec2 TexCoord;\n" - "in vec4 Color;\n" - "out vec2 Frag_UV;\n" - "out vec4 Frag_Color;\n" - "void main() {\n" - " Frag_UV = TexCoord;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy, 0, 1);\n" - "}\n"; - static const GLchar *fragment_shader = - NK_SHADER_VERSION - "precision mediump float;\n" - "uniform sampler2D Texture;\n" - "in vec2 Frag_UV;\n" - "in vec4 Frag_Color;\n" - "out vec4 Out_Color;\n" - "void main(){\n" - " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" - "}\n"; - - nk_buffer_init_default(&dev->cmds); - dev->prog = glCreateProgram(); - dev->vert_shdr = glCreateShader(GL_VERTEX_SHADER); - dev->frag_shdr = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(dev->vert_shdr, 1, &vertex_shader, 0); - glShaderSource(dev->frag_shdr, 1, &fragment_shader, 0); - glCompileShader(dev->vert_shdr); - glCompileShader(dev->frag_shdr); - glGetShaderiv(dev->vert_shdr, GL_COMPILE_STATUS, &status); - assert(status == GL_TRUE); - glGetShaderiv(dev->frag_shdr, GL_COMPILE_STATUS, &status); - assert(status == GL_TRUE); - glAttachShader(dev->prog, dev->vert_shdr); - glAttachShader(dev->prog, dev->frag_shdr); - glLinkProgram(dev->prog); - glGetProgramiv(dev->prog, GL_LINK_STATUS, &status); - assert(status == GL_TRUE); - - dev->uniform_tex = glGetUniformLocation(dev->prog, "Texture"); - dev->uniform_proj = glGetUniformLocation(dev->prog, "ProjMtx"); - dev->attrib_pos = glGetAttribLocation(dev->prog, "Position"); - dev->attrib_uv = glGetAttribLocation(dev->prog, "TexCoord"); - dev->attrib_col = glGetAttribLocation(dev->prog, "Color"); - - { - /* buffer setup */ - GLsizei vs = sizeof(struct nk_glfw_vertex); - size_t vp = offsetof(struct nk_glfw_vertex, position); - size_t vt = offsetof(struct nk_glfw_vertex, uv); - size_t vc = offsetof(struct nk_glfw_vertex, col); - - glGenBuffers(1, &dev->vbo); - glGenBuffers(1, &dev->ebo); - glGenVertexArrays(1, &dev->vao); - - glBindVertexArray(dev->vao); - glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); - - glEnableVertexAttribArray((GLuint)dev->attrib_pos); - glEnableVertexAttribArray((GLuint)dev->attrib_uv); - glEnableVertexAttribArray((GLuint)dev->attrib_col); - - glVertexAttribPointer((GLuint)dev->attrib_pos, 2, GL_FLOAT, GL_FALSE, vs, (void*)vp); - glVertexAttribPointer((GLuint)dev->attrib_uv, 2, GL_FLOAT, GL_FALSE, vs, (void*)vt); - glVertexAttribPointer((GLuint)dev->attrib_col, 4, GL_UNSIGNED_BYTE, GL_TRUE, vs, (void*)vc); - } - - glBindTexture(GL_TEXTURE_2D, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindVertexArray(0); -} - -static void -device_upload_atlas(struct device *dev, const void *image, int width, int height) -{ - glGenTextures(1, &dev->font_tex); - glBindTexture(GL_TEXTURE_2D, dev->font_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, image); -} - -static void -device_shutdown(struct device *dev) -{ - glDetachShader(dev->prog, dev->vert_shdr); - glDetachShader(dev->prog, dev->frag_shdr); - glDeleteShader(dev->vert_shdr); - glDeleteShader(dev->frag_shdr); - glDeleteProgram(dev->prog); - glDeleteTextures(1, &dev->font_tex); - glDeleteBuffers(1, &dev->vbo); - glDeleteBuffers(1, &dev->ebo); - nk_buffer_free(&dev->cmds); -} - -static void -device_draw(struct device *dev, struct nk_context *ctx, int width, int height, - struct nk_vec2 scale, enum nk_anti_aliasing AA) -{ - GLfloat ortho[4][4] = { - {2.0f, 0.0f, 0.0f, 0.0f}, - {0.0f,-2.0f, 0.0f, 0.0f}, - {0.0f, 0.0f,-1.0f, 0.0f}, - {-1.0f,1.0f, 0.0f, 1.0f}, - }; - ortho[0][0] /= (GLfloat)width; - ortho[1][1] /= (GLfloat)height; - - /* setup global state */ - glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glActiveTexture(GL_TEXTURE0); - - /* setup program */ - glUseProgram(dev->prog); - glUniform1i(dev->uniform_tex, 0); - glUniformMatrix4fv(dev->uniform_proj, 1, GL_FALSE, &ortho[0][0]); - { - /* convert from command queue into draw list and draw to screen */ - const struct nk_draw_command *cmd; - void *vertices, *elements; - const nk_draw_index *offset = NULL; - - /* allocate vertex and element buffer */ - glBindVertexArray(dev->vao); - glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); - - glBufferData(GL_ARRAY_BUFFER, MAX_VERTEX_MEMORY, NULL, GL_STREAM_DRAW); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_ELEMENT_MEMORY, NULL, GL_STREAM_DRAW); - - /* load draw vertices & elements directly into vertex + element buffer */ - vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - elements = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); - { - /* fill convert configuration */ - struct nk_convert_config config; - static const struct nk_draw_vertex_layout_element vertex_layout[] = { - {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, position)}, - {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, uv)}, - {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_glfw_vertex, col)}, - {NK_VERTEX_LAYOUT_END} - }; - NK_MEMSET(&config, 0, sizeof(config)); - config.vertex_layout = vertex_layout; - config.vertex_size = sizeof(struct nk_glfw_vertex); - config.vertex_alignment = NK_ALIGNOF(struct nk_glfw_vertex); - config.null = dev->null; - config.circle_segment_count = 22; - config.curve_segment_count = 22; - config.arc_segment_count = 22; - config.global_alpha = 1.0f; - config.shape_AA = AA; - config.line_AA = AA; - - /* setup buffers to load vertices and elements */ - {struct nk_buffer vbuf, ebuf; - nk_buffer_init_fixed(&vbuf, vertices, MAX_VERTEX_MEMORY); - nk_buffer_init_fixed(&ebuf, elements, MAX_ELEMENT_MEMORY); - nk_convert(ctx, &dev->cmds, &vbuf, &ebuf, &config);} - } - glUnmapBuffer(GL_ARRAY_BUFFER); - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - - /* iterate over and execute each draw command */ - nk_draw_foreach(cmd, ctx, &dev->cmds) { - if (!cmd->elem_count) continue; - glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id); - glScissor( - (GLint)(cmd->clip_rect.x * scale.x), - (GLint)((height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * scale.y), - (GLint)(cmd->clip_rect.w * scale.x), - (GLint)(cmd->clip_rect.h * scale.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset); - offset += cmd->elem_count; - } - nk_clear(ctx); - } - - /* default OpenGL state */ - glUseProgram(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindVertexArray(0); - glDisable(GL_BLEND); - glDisable(GL_SCISSOR_TEST); -} - - -/* glfw callbacks (I don't know if there is a easier way to access text and scroll )*/ -static void error_callback(int e, const char *d){printf("Error %d: %s\n", e, d);} -static void text_input(GLFWwindow *win, unsigned int codepoint) -{nk_input_unicode((struct nk_context*)glfwGetWindowUserPointer(win), codepoint);} -static void scroll_input(GLFWwindow *win, double _, double yoff) -{UNUSED(_);nk_input_scroll((struct nk_context*)glfwGetWindowUserPointer(win), (float)yoff);} - -int main(int argc, char *argv[]) -{ - /* Platform */ - static GLFWwindow *win; - int width = 0, height = 0; - int display_width = 0, display_height = 0; - - /* GUI */ - struct device device; - struct nk_context ctx; - struct nk_font *font; - struct nk_font_atlas atlas; - struct file_browser browser; - struct media media; - - /* GLFW */ - glfwSetErrorCallback(error_callback); - if (!glfwInit()) { - fprintf(stdout, "[GFLW] failed to init!\n"); - exit(1); - } - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); -#ifdef __APPLE__ - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); -#endif - win = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Demo", NULL, NULL); - glfwMakeContextCurrent(win); - glfwSetWindowUserPointer(win, &ctx); - glfwSetCharCallback(win, text_input); - glfwSetScrollCallback(win, scroll_input); - - /* OpenGL */ - glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); - glewExperimental = 1; - if (glewInit() != GLEW_OK) { - fprintf(stderr, "Failed to setup GLEW\n"); - exit(1); - } - - {/* GUI */ - device_init(&device); - {const void *image; int w, h; - const char *font_path = (argc > 1) ? argv[1]: 0; - nk_font_atlas_init_default(&atlas); - nk_font_atlas_begin(&atlas); - if (font_path) font = nk_font_atlas_add_from_file(&atlas, font_path, 13.0f, NULL); - else font = nk_font_atlas_add_default(&atlas, 13.0f, NULL); - image = nk_font_atlas_bake(&atlas, &w, &h, NK_FONT_ATLAS_RGBA32); - device_upload_atlas(&device, image, w, h); - nk_font_atlas_end(&atlas, nk_handle_id((int)device.font_tex), &device.null);} - nk_init_default(&ctx, &font->handle);} - - /* icons */ - glEnable(GL_TEXTURE_2D); - media.icons.home = icon_load("../icon/home.png"); - media.icons.directory = icon_load("../icon/directory.png"); - media.icons.computer = icon_load("../icon/computer.png"); - media.icons.desktop = icon_load("../icon/desktop.png"); - media.icons.default_file = icon_load("../icon/default.png"); - media.icons.text_file = icon_load("../icon/text.png"); - media.icons.music_file = icon_load("../icon/music.png"); - media.icons.font_file = icon_load("../icon/font.png"); - media.icons.img_file = icon_load("../icon/img.png"); - media.icons.movie_file = icon_load("../icon/movie.png"); - media_init(&media); - - file_browser_init(&browser, &media); - while (!glfwWindowShouldClose(win)) - { - /* High DPI displays */ - struct nk_vec2 scale; - glfwGetWindowSize(win, &width, &height); - glfwGetFramebufferSize(win, &display_width, &display_height); - scale.x = (float)display_width/(float)width; - scale.y = (float)display_height/(float)height; - - /* Input */ - {double x, y; - nk_input_begin(&ctx); - glfwPollEvents(); - nk_input_key(&ctx, NK_KEY_DEL, glfwGetKey(win, GLFW_KEY_DELETE) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_ENTER, glfwGetKey(win, GLFW_KEY_ENTER) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_TAB, glfwGetKey(win, GLFW_KEY_TAB) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_BACKSPACE, glfwGetKey(win, GLFW_KEY_BACKSPACE) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_UP, glfwGetKey(win, GLFW_KEY_UP) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_DOWN, glfwGetKey(win, GLFW_KEY_DOWN) == GLFW_PRESS); - if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS || - glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS) { - nk_input_key(&ctx, NK_KEY_COPY, glfwGetKey(win, GLFW_KEY_C) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_PASTE, glfwGetKey(win, GLFW_KEY_P) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_X) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_E) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_SHIFT, 1); - } else { - nk_input_key(&ctx, NK_KEY_COPY, 0); - nk_input_key(&ctx, NK_KEY_PASTE, 0); - nk_input_key(&ctx, NK_KEY_CUT, 0); - nk_input_key(&ctx, NK_KEY_SHIFT, 0); - } - glfwGetCursorPos(win, &x, &y); - nk_input_motion(&ctx, (int)x, (int)y); - nk_input_button(&ctx, NK_BUTTON_LEFT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS); - nk_input_button(&ctx, NK_BUTTON_MIDDLE, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS); - nk_input_button(&ctx, NK_BUTTON_RIGHT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS); - nk_input_end(&ctx);} - - /* GUI */ - file_browser_run(&browser, &ctx); - - /* Draw */ - glViewport(0, 0, display_width, display_height); - glClear(GL_COLOR_BUFFER_BIT); - glClearColor(0.2f, 0.2f, 0.2f, 1.0f); - device_draw(&device, &ctx, width, height, scale, NK_ANTI_ALIASING_ON); - glfwSwapBuffers(win); - } - - glDeleteTextures(1,(const GLuint*)&media.icons.home.handle.id); - glDeleteTextures(1,(const GLuint*)&media.icons.directory.handle.id); - glDeleteTextures(1,(const GLuint*)&media.icons.computer.handle.id); - glDeleteTextures(1,(const GLuint*)&media.icons.desktop.handle.id); - glDeleteTextures(1,(const GLuint*)&media.icons.default_file.handle.id); - glDeleteTextures(1,(const GLuint*)&media.icons.text_file.handle.id); - glDeleteTextures(1,(const GLuint*)&media.icons.music_file.handle.id); - glDeleteTextures(1,(const GLuint*)&media.icons.font_file.handle.id); - glDeleteTextures(1,(const GLuint*)&media.icons.img_file.handle.id); - glDeleteTextures(1,(const GLuint*)&media.icons.movie_file.handle.id); - - file_browser_free(&browser); - nk_font_atlas_clear(&atlas); - nk_free(&ctx); - device_shutdown(&device); - glfwTerminate(); - return 0; -} - - diff --git a/deps/nuklear/example/icon/checked.png b/deps/nuklear/example/icon/checked.png deleted file mode 100644 index e4e05b29fb20e2e32363896950ca4cfea31f8542..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1813 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 diff --git a/deps/nuklear/example/icon/default.png b/deps/nuklear/example/icon/default.png deleted file mode 100644 index c11145a007eacd369dc85b41b4c9aa006d098fd6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 460 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 diff --git a/deps/nuklear/example/icon/export.png b/deps/nuklear/example/icon/export.png deleted file mode 100644 index ff6b5aa4acf440c4de50f709cd7bfc477344af9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13336 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 a2tchy{5>J5&Rg;Y9sGf#_7#8mUj9G(d|q+@ diff --git a/deps/nuklear/example/icon/font.png b/deps/nuklear/example/icon/font.png deleted file mode 100644 index 918e9bfe1ea44c569be31bf73f6af53b301c3edf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 561 zcmV-10?z%3P)FwDX-&%Eb7XN0nx!k!fNT3xAtIlwhQ0}6Yl6y9k2d>T0z@MA8M6_9RJIE|*dT*MP5-ipS%zF~*oM49#Y!P(Txl$RR?)7?& z`Fx)KY`5DvfQ8s^*LBm2!+k`*gcq8jVKDSr+^^U;_LS5&Hc;gTVl; zHE%zEsrd1bqp&92H>vCCu~W}8q1zCQbM_|vmDXG^oX zeex85TQ{$B|K6R0-*O7HnOS{3dj`P#^t{%gDmoOAN{3c;?kY1>O659wS(P$WN}-g( zbzL0Cxim1>|4yf4tgE`w$ZEISu~;mG|3<$7k0ygyH7*Qe00000NkvXXu0mjfN^t?l diff --git a/deps/nuklear/example/icon/home.png b/deps/nuklear/example/icon/home.png deleted file mode 100644 index 85606267225863537d186d63ebb2ed7014c9e4ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 819 zcmV-31I+x1P)DW` zK~y-))s)Rk8+jPVKflb3^Frfhou&!xCQPQuB1mvSij7Ed!HanI5;P|d{ssOMUiRe4 z9`>?(2v)qgu$hZ^$jNQNlp^#cjOY>rotVTO>*TkGWkW%?EqmI1ZVx=qhv)SR|8)~z z5EC08ACE3CFHu#MSSy6(p zW?2@BqTE{H5a@XxJKNht-7epcKV)kD2^T@YZ;dxJn@tuM7ZF0BCk zcso1HJR&h5HZE^m{$NYW3;$dg!{2 zuIs3(O1s@=VqyYSRdHSSx#Ku^o+oYqGuZ-<9)AbG-Me?_cKiHs;j>?_p=lb2hliY; zoM78FD=RAi1VO<1`ufeYky3ImnLwqDN}F!r6NTrD*>})&o&EiN`u#rTa+xp;sn_dl zZf@fH{_U@qN~I*g=;$bhVQ_waPCA`N2*KRk9Hml;g@px7)1+7|GB!3wCX*rl)6e{9 z=!9V?Zu{lY+1c6P^z;@B7qhH423S&1MtN^T_3L)a&)Hf%jjkHo06b_u95?DwPV2MuWY* xJv2?@`1m*j`2SYsikVDCX0urdOz^+9KLMDz1_tX?-dO+u002ovPDHLkV1nUi5sZRGrF2`gX~#oqZIdO5p8Ue_nBnoA@63DeE9i&piJhJ} z5YlHafn$IL=)e}RIV!2}AvWT-PNUjbfT+pQ2*1=&Miy5#UoMlac9UlBX*x0Gyec;(9)h9S#u= zS^KKM(haWNxl5^3qTOx_zXDj3lan%+%TcLR4sJXPuy0T@zZ2Lgo6U{@KSb~RAL6(WSdwr%WCi1_$8N-3nSV;GXX z9T2->{|{krceuiXrhTxy%p>_9|hmOcMGwxu{|2$Z&!Kv=r;d~!}f*aILgma i2BFjG9I>zeAHM*|L6h|(d1^HP0000mI)V diff --git a/deps/nuklear/example/icon/movie.png b/deps/nuklear/example/icon/movie.png deleted file mode 100644 index 5227883e6c4d28773043acce6ededc1fe34ded22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 626 zcmV-&0*(ENP)T{#D-;S&%1S2+M3;h&CNB|?Xn2J@MjBouU8Fn!Jt9)lf)J5N z?utl}k|tUMo6Xu+Tv+j+hrS}K(a z#u$plBA(}=l%m`1(r7feyu9S}^mGGIe)<@gODU<wdVf*o?frV$;k=h@i^_p z^*%gwQ&PauXoT-rtCIF5HdU;n550eUjt_y-pF9RL6T M07*qoM6N<$f_*?A&j0`b diff --git a/deps/nuklear/example/icon/music.png b/deps/nuklear/example/icon/music.png deleted file mode 100644 index 0f1415c8756311c4852151f1a0f4055e08b26b97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 610 zcmV-o0-gPdP)I`orN2EPQ-(&Md=rc&3|7-y16j#sR2} zVjD0z1Y|idTPZd6Jg*!C0T^RR0odwM6q(6nV&%aL04{URr@dZ}h=_dOr^RAHT5DRZ zR;0D2<#L%S&+{k?iR~nSlWw=`4u?YkK)>Hdr_+J!x+s-OP)b2c2`MFn5Rg*lTE)OZ zqtUoJ8jX^V<#IU%5JF)1=4pCnjO79W0Q31AzVBl&7{GO1)a!NFww*G2^!Q;4aEVoO zfd)Xx7(=VoLc86DloG{a5su@)w(SH60B0Y9#JX0i?KJ!y>&I7BN~H{i5CD*zv)9cU z{yi82$8nOOXBPorCoF4d7-Jx!1dv@w4BQ3VT1srFlu8UgoqWXc``0-AJjT~=X9s`1 zLf#XIZC<>6h99#jlvJ4h{EpKvV|Z7tT^txEwtIQ}9KV8daK$b^vLfjn~6dME_I22d}m^c_!)PC=b zm*Z={ym!9; zr=IE@nC9GR!1pKJ$18j7?|_%w^?mMtpRhC4|LwVztRZ;J_id(y;Jy1(wr|eL*Kpy; zW%zy2;(3AP=6$~(b_(2La8Y0oMLNQwB4Lv5pnWa8YRZ+rV(E0d5Yaz8zvv1Aq(%CZ-7u3@;TK7+V;ekbU36 z@F`#N>C`F~jyC^>f*-r@PQHHp^!Fxp2aAeuh96Q2k~WNo4hk#C?2%=t;hn%UkKy5i zSjGq04JjX3IM{(YK9n(hFm*7hU}|aZ7gvz2`NGFgm%+>+uf_0TArpiA9_9x5TMP%< zxfp6bh+>s7J7D7b^!CI44>i^8ix>}VXJ+tcc%U5Icl{GO7%dUxFNcuMknA8|N MUHx3vIVCg!0CE}m3jhEB diff --git a/deps/nuklear/example/icon/pause.png b/deps/nuklear/example/icon/pause.png deleted file mode 100644 index 7d6367e1ab0943e76984dfa115111f2cdea3983e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1338 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSY)RhkE)0?&_*lPgGf;%Hz$3Dl zfq`2Xgc%uT&5-~KvX^-Jy0YKrVdoK2UtIszj)8&YxTlL_NX4zUGj97!yNk4+cX0HG zaq6hhU`k$)*{CLX0IIqv^lKqB>Ra5tvO>|=I-FbAvB9BG}w}1l@ahKGS zxi$%8{JPNeX+qe_z1F*L-2a}DnO0x??DLzMp$8KJ6zVk>uy8QIVC6CPIPN7|#gYv*Lmml@>iudtPES_nXVJPLC%##hH;W&u%x?Ui!+<_`F-X?Zlt4 z8s_#aZ3;(HGF-^vf27dMj{*@ zfq@h6-MxEtnbH2Zm@A!cU9Qa(?rb@i%~<#Eqx#*tx3hGMuU@-$>QDaXK5>(j$X{8} zv$t&7mSQ{o{PW2(UrNrM&J=NQfn42}3)d{I?Osoq{#jpE`^Dsf2!2+kZRaX~pUbT@ z{O;D*^npPYRiCpNVNmaT zR{!|*!^EG(_4cnTAAQ`h@eKd|N|lv+_udg*uyW0gn1BAcmtpqnS0T%iU%!4GdopIaYub6P51z%Fix$sFO-+^T z|NG)os%UhlzN(>A}ptTfraWyiPo=6Ves9oKGsV|AbJzI6Nc zaLbvNDaF(61UpYm|NegWuAl2T7EBQm4BX$>f7|H(r%RLWyxOyL&N&+qjvL>&qGKWo zzLijMzz}Nck-5h4d(4e3sn-BK9vwzu}vz*?fGSlbSol}42OAGL@9Zh~Q^=Yc-(r@SM zc9g92vRktLYxv0$`fECVp asvjJlZhq71=yzZ#$KdJe=d#Wzp$P!D%r+4K diff --git a/deps/nuklear/example/icon/pen.png b/deps/nuklear/example/icon/pen.png deleted file mode 100644 index 10c851c120a04bccb59284c56fb5f9ee63a64c8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5949 zcmZ8lcRW@9|9@Y5WUo@Wga|3KjPAW6BQh%4d#}hU>)sn5Wsh5u)in}PMrNU#N|BLK z5#bgxua%W`fA8D(zu&`y6E25bBK`MF&Wh93dY4s>%0c5@ZI=@slLs%LP?)K%V%834fo10Aiaw}vUB5wpi`CIq;%lXXob)KBdm56$s_1$9HcfORdVdy}wct~;f?`~=mM^LchOej(Fq!iaC>ycLg zXj;GY&S;Gx#(7fr_h#t8ve!ZDk%l&(Sg%d+IP9C6IR*mM|wZi z3UCOYjnftaZ}2aIxFa_=hFMVF>ixpbx{z(thonO>S{M*zP4bEn zjUlO~0Z_}$BhaB9TE*+PlMaCL{aivF zai`slUyMtfot?d+o~T6!O7HZFP@WsSP1lCU6J6t{r{`AHU~x3(Hy7qUF(!V{{2>)r z*rH|;I9uLk*f@M(TMPldIQBHZY<@Ob9{!KVIu~ zB`->f7wB8Vs5V8E=r2>cdS2=v(Efd%kC83_eC6&8+LPQASnI}-zJ)Ej8~_sK3ucF+ z6hjiU9KJt~Ki-|)ALsN=Eh-8v1JZI=69QLPvrf*CD}`qVJ(i2;K!=${nb+9vXNGfq zdV}J7uqAO;_0BKziSy$^O+@U*NLQWb*jv$&cXlA{K*6cG8}fUa6qX-7D!xO#jw3pZ zfFQaSkAfCVss#yp%utRY@O_5H27+tC``aS3dO|=#R%4owA2Z(ni4Y#V)Vfj^^@E9_ z$lTJh-Fc&p<%J*YCRY!Sk3P%d@JZg)1k{f6=9R0K5`(X!B2t#>9S?w{lr)PqwM^`z z*VNw{F)3^CMpsz5+iQP54>23RV;rn+l5A5R8OY(goRbFLl*-w@i2J@df2uK5A*H=L zxy;WP`2u2x)U7!6DE^70&GkgOo-?aDnV%X_-Xj9-siHRcw+ zJysNZx}PfZkcFY}K~_e`{?=YW{&4N7P;_kUr;t~{LcHJ&`|9eSq2%bp(cV`+%__&B zdt>B*ehPQypHD9dhVz5F64_*_w|0PAOiX^dZEzq`ABdii$w+99Y|fhZ6l$$CDBavj zhxV4reyt7Ya8|7%#W)T>P8Jm2NGjINJIsnLw zVSmFG0vFx1YNvWekFDlW-W{5+{s5i2|Mu#%0*ON(u_;Khz+Ojz#WK&iF3l zwVLaH&a6nV4cCv(9N!W};Panbwh-25zvc|8+O~Izl9F?h0;9P;08Evt--gT4vFo3G z4r7~w5>e}Uod$ch@ChwH2q?p~suOh_CXXK6ySu}{=|Rs54oJ%#%T@7tyL9VhJHpJRwTvcm-(bOvryRL7d2TCq7mGqU9T%N3pL?pj zF3^e79U!awEK^`gK(da3&<@&wkee7DtV}mbsh87IySHMw!R!C`xV$%>d zg2kAMUTA+Oai&fP#z|gD_TFA-OT6%IQ{{}FU1cFfa)0ztWz z8Hcq;`Hzqu<{6YfsC@58ymMOMpw8i48pM$tPSWfK$S5qTbASE}`%L0zl-@s2iXFPh z>nQ3d!8w~Un@on}q^%LOC2N#fAQvQ6I;`2cjEP zmA$_48{UHLTyTOvp)_mk(X$diuCd|X)et^m1>dvLFbW4|=f0MAMfLx;f_$0uQ)R0f zOWb$j=HAz3k=;DDWro1t&NwGir1t0cF_=z__hpk}g~96Uz7LD|Dk+|0g=*1AJ8*i^ zoLaIzf9vQ>1Zpeqj=C7_xq^!A9v54l-BMtR(5IA?Z34bl{vJ>0v8M7;PNTikrU96O9xAGc`XPnw&`Co_{wxxuJm=8Tk2}Lc|FP>4W|Ykkp>u-!cEi`)l^2Ia((t zE9>RNvjTR&E4@jao}Vyefz8`{yPvt(J~0#9hHbLaACNK;h>W1#vej(~A1)Y&Zg|=( z>Mf3S?*wg!+)z}>Qmq)l)A(z+z3Y?f#PP;NnXMSt*2dAhY@l{!`KR_j!65SWdHLeG zSNAfC1$goLWG~F^c(p3xjU@e~*2;>j;#+-;;L_yOv;ve#2c`O>R2KDN;N+( ze-h1`%2#tHSqj}V(Zsl!9sk$wSalh}sTw6C`2?vAJ8L^SU(>awGKktu2~15YeasArs4Sn{h_VUbX4>y%Osk-2 zG;j zQioJp8YMjbCzP`u;{c?Ie)+5;#b{o9E&sTzJ1KYn!YUdMt8gM?Y=%z%^MmII0{ZWu zzo6)rWW{a%o7M%UI_tF*u~|MOH^07uSp*N1hx(Q5RbDm7`Q^|E1L7^YB@V&@opi=U zLijS$5Otf(>~#%5Zv9?UB4a=dW@f(YsidTIb9YxOPyiG8R?C36JSa@kWx=Mo(%srx z7Kg za$4YxP_0=ms%Tadxcq24(F~Us$(WW&OzlTv%2@NOsAeD7LfDbUg+6hEg%UYi zV>7387A%Hwd6U8Pc>JC%>9>^kP?Z?=JDy=#^F;GPp+U_P%b(0?plkr@(W0fz)Pt%= zTDcC=ml`Mj?oJLJ-*~?uX{9e6jWk6xC&979Y|+B@yr!RRgP8ErA9@MAh38;>p4sBy z+f#y$Wv4_DU)~Q756^7Ob~nhi4-X3$qiIL=Imu=elNeo&rw+u|&>Xtbse?f1SmvR& z*Y|%|^vm?^oKvazOH7_TsO_5A@MVV0pZGr zG#2(h(^hv@Kh9RS$yMW}V7Cofh`kip%gvW`J={noOC5W$G)N>|Ay6Ou3}3IEND(pN z?cS#(j+#I!=Gn!wk;C9P6T5i7`dekr>(wRKpMk@ChuY4euNcE>D=sch7TQKVGP?An z4*l%saxgNV?pDuV_UZ49tcxm4Xr8_=@%LuQtueUHKzDcd#pgygtl>x;bwUhA6w%71 z56lx15{BMNCep-$*WCM#y8R#9mk!UiAzHQQnQuT1!~TLaUhE^3t?DMjvP z*+x&e_}428ZfRUxlr3w)iNHCIHn}}4-@Z=9p&#h8ZIP!5m=YVSim4J#qNfN5Bn zMx26?E0T3SBb@QHKbqT{8QB5&Q4TMTnKU;i|nM6T?D*%RfrPRJCbaDBDrQo zx=xQplCtef=stdEOV}pES>A0c9^S+RAsv>YLoM@f=zyY<5?lqO0p;|p49U6jk|kf{ z+fG%$iqY;k(NTC#n#U}C^4CIAIczu2N8qwfgz2@D4)Om!mX(&qT_S3l-)Ek@Zg8W{ zU}5+0$hnDu1X4$mx=4ARqB)4rCKQ1mAY56xK6nx#)hMNqb>?IWG@#fFa1qZjly zs@3fz{+s#SrY0zFiPsB32mpsE+`OuLEjjU&!^{1a#2WSn@3xDC*v^pQ-#y>*SZQsb z9-vsaxJk`X_PI#EaMarzn?rKy@mn81e}i>J-K!D;+v3EBqBZ7VL~RBf;jZ)lC=J5l z{@l3~!ue*X(em2UiZ8Fa{cn1jK#c=OE*ao=6dhLBL(HPg7WdWbCJVR03DM{47%V;- z^t`d4;)+Pf5K6y!5qRcMiQ*7BtzW(|=kwDHbV!0r?o=x)Ywx;ChO*sg9GsHfcM-h! zir4!0T1mf8)<#S`hkL7J^t{Fhvj+^_mJBsMj-QQkja??nw5)F$N_D4hG_Zp&@}Nd( zhH7S5c~+`mVFIn29nF$E1CVOj?T<9CdDkY(+clX^-_)ROdCKVY zjf}n+XuoP1%%H)mxE`NXh+XuL&X>OXnM9u>yR3SgVq1t{JH*+P0O##nMN1X!0dQyc z*rvh%ikVsZx0(&>28HrHQY7P@rAmyllax5}=NSSf zJqx8nd3|>2XU-yA-QDJjmnwZ|WcHy_DlhUH-!#SQd zMy$^dWWq_aHH)!Vk4`$ubS{IC%iDhQT>~R?`ao}i@|&^S;nb!xpCW;_1im*Oj0-V{b_MOvtXY?%IFit8cC@AoV=6~Cyaisquf~vnw$q*LatpN*5C*!gt$)ld-yj?I4F<=#g`4@ zU`cAxVtlu?~zvypOj`ehd;=Np{>nBffS&P)r= zYH;gjNl)(aGlL4jinC{vE6}YBTp8AVJawy3zsD>l7}Z#{H#Dy=D4?HbSDu zjuBps4DVA(c5npWyfM*HpTj{X^5!8Q#+-L+rKC<7nkRfNkl%d@p??Aa@H!vihME;X f@cMrjjL|;VS-kN)MtPUEC7M2r+ diff --git a/deps/nuklear/example/icon/phone.png b/deps/nuklear/example/icon/phone.png deleted file mode 100644 index 5e6f6133d76019c8814a310ae138a12e0e516b65..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15778 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 RNWOApZ{uuTbu{45{{^G)Zw>$e diff --git a/deps/nuklear/example/icon/play.png b/deps/nuklear/example/icon/play.png deleted file mode 100644 index 9c9e8f0a4e853acd8a5e6f370bbc8ecfd994af8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 566 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSY)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP~w+J^s3-|UzTYy5cnIRD+&iT2ysd*(pE(3#eQEFmI zYKlU6W=V#EyQgnJie4%^0|VnMPZ!6Kid%2*UhHi)5Md1zUh1f|^vDHA7nLUp=VuDd zxcOV>Y4UNf5fI{mT;Jm#Ke)~({NDbh_P)8482^J)@p}ZscpqHfDSjv>?jF0?gN;sW z9c>sCS^OI|CoryQWN1-fP^@6CkdI)<2C^&|&o!}bU}F+!5`LhAM@VTK!!-v6rvj!q ztlSB_ED9`)90#Qj{64@G!3<<^7KrIIm^WVyG;}BS)*5C*(7pdc-Oq z{+@*Z>wYZ5qs5E@@^*|*+{GJyWH20Q_hF(L)?yQeHq3~sF2w-Nzp}-=*#KG9Y;KXq9 zMC$q3dE0OA{kHq{S1ZeFkAssp9ZmjqcJYJs1M^#XY8UK3v}jAy|LfmRRiEGX?N=7_ z9_e{zFPQ7P4?8nP-QB73f_>kyL{*2^x6}?wB$qr4=$m)*ThqpKuO7`XKDgeFRi-jf zH^6@S;`7HQ9|-tx`m5J^>mcr)LcX$wfDbGj?EVbO=Y=xvztlN!Q~aRZ?Y)8z`plUQ zTxU2S%uvC^kk8H#&&=S@@PLzHk1RtCFM|zZ16caygT<^2b|DN8n#&nJI7>792w-gB z7iIYIK$hXp1vapZGf+VVJA?fesEi;(T?R9QycWZUgUSql5*QEgivdkUgo7e1SWfI@ z{a{)o)xhG$!1;zDUP$1ekO#|rrXE(N3}z;QMg|v!hQAFAw;Dijs$y!1~ZAkhRyaVKlzn18VUqC z1nyO^aO5*HwR8tmg--r|Qrek?S74XC&UJ0ue+=dSEpity9&*)izd!Tczm4azW<9U` zdN?fpDciq)dnTVO=i_J1P-Og(-0@+ub7(`D_>?*&o20-fCYJg+e;0iFb(XE-s@;X- tSuMJ9yICfDK2pp8jeDq{Crqee(n$!Ju=$t7Bw#{g@O1TaS?83{1ON?E{p0`u diff --git a/deps/nuklear/example/icon/rocket.png b/deps/nuklear/example/icon/rocket.png deleted file mode 100644 index ea8e187c9f0e50de6dcd87fe823cd2761a510c83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1121 zcmV-n1fKheP)WFU8GbZ8()Nlj2>E@cM*00YHIL_t(|+U=dolG-p3 zMJ2-zYT*qZ=#3Zp!NAO7pfW`PW6OH>J-tdQmBiz7`XN~u?+B%sVvN_vZ$bzs&pojb zF~+ZyzlQ(=#yrob%jNPf$G?RDhO-+10RAyT2>#6N)`I>V2p|X@0RWEx>fjMT82ay+ zK%@(w3Lp#~0mQ-60)X$FV<%7+dsQ|*6j{rOF zkyZE%fudPY1pqz*e2RIVPgZ}n-vb~5yop>VZm9s2egpu1-@!(Z5d7!G~$%H(#1HWuPR0 zubo{RETy!Co*86=_t^f>X4Al3wY?U;a%0KhjGTieqF{PgJcR;u0Pyp|A4&k= z=Z8Pi5Xfg3f8b|-&@~N`{WtJC=bXFAWfrBsOz9t@0s#MKN3rDLQx7D)tj{I@@W+OK zNC4oE4?lSZu>2Y|CHTn|fb6#cKS==K+kwAZ0N~q#ze@n%+k>Ax1QIsjZ>|7jzfJg? z1OR?^@Q2RuRTTjEHnV<{0Km5opCM2j{@V&b_G`d@DFEp2WP56fdc#e6VPfB06W&wUy0bcDf#2Bx@*IfnN0N;PG6DSP7 zXbZ49BwB(`1rUc{tO8ifev9x+4}pNE1pr^J1z0Kn3h=1_;_wlGKmY_t?DISg6cykv z@JjttPJn0lQ~@CY_Q0kJ7!%+f{7;~fz=!}T@R7iX06BVmiPxJFjhBHtGn*skBMQ*N zH(C*m1o-qCxKx-(FpvPHj&~!$00NZW+zBCg2E##zz>FDuqZ;%nK-H&%N9GACNdW;` ze3EC61P|~mG4n+ihe97vU(Fx1ib?|f^#<@7Ab{Pl1&sR1UZknG3Lp@GuqZ&wlRdqi zFTB6Xl~q73_|Ly?+0zy0iOE9N=K!ZVOrBe1d`}RRR}$ye&|5-a30XjZl+q6T0R$*D zsRO@l_?Ans+#oj07+rl^hx9VAb{3NLod`h57u^R~mgNk5(HWp7gdTPj5#XNj>$+aK n#bPr6nI|Ryzy$;VvfcOwuWa|S&Zx)400000NkvXXu0mjffwSmT diff --git a/deps/nuklear/example/icon/settings.png b/deps/nuklear/example/icon/settings.png deleted file mode 100644 index e6e13f8564624244f56dbd51b10f4655a9014c27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15671 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 diff --git a/deps/nuklear/example/icon/stop.png b/deps/nuklear/example/icon/stop.png deleted file mode 100644 index 6742baf9aa961f5381beda98bf3fe79aa5ae9a70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 520 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSY)RhkE)0?&_*lPgGf;%Hz$3Dl zfq`2Xgc%uT&5-~KvX^-Jy0YKrVdoLy+VD&4ECU1MR8JSjkcwMxZ(J;7R^)MTOt{3N z8zk`7N|EH<*pXt)$d&^v*j2Wm>d{57#I~8SQ;1t`u@%P$5ec7y5Sz_ zms??@y3sINZ;eXvxsr-R-59_lkDaQ_hGaJ+DN z{}-+Xg?k^S|7UAZxc0$YbLqEx+iP}OK0n>@PWI2Y|4cc}66Z^Avu)r_l3Ah5;IN~- uTaK0CNbU7!iy6Mu#IZ7iLlo*M)tB-K*K*4nlP`NS0D-5gpUXO@geCwHd!8!* diff --git a/deps/nuklear/example/icon/text.png b/deps/nuklear/example/icon/text.png deleted file mode 100644 index 136e534a50c2fd4319d63324d09d83933e7f28f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 601 zcmV-f0;c_mP)|W zK~y-))s(%;;y@IJ-x-}5R{Vij7(}d0Bgk4g^9{M~N1e=Zga0synw49#W}hG8I|&qD|S&N(>eV2put{~5KOeT|;&qjq`D;A4z z90x)OWHK2DA>N`(5&{5%AV4mc!(cGLdcD3Q3(u8G1>^DfC7~vSKx+-oIr{zn-9*Fu zi0s*>AP52oA>cR;R;yKv?CS%6hcLR#7{hQlyrZL({_`$JhP_@7p6A8Lo>4tjsZ>(? z{a$Z28+|w&w3JdSrSvP6%Vm|^-}pjP8kP90Oxw0$+xGW_rfI71XW;w3en&~dSPy;Q nm$h2$$JYUUr`zo&@n7i!nhp9}Dig&U00000NkvXXu0mjfhOhtA diff --git a/deps/nuklear/example/icon/tools.png b/deps/nuklear/example/icon/tools.png deleted file mode 100644 index 412ff85367fb30e6a6cfa298cb08f6d1578ea379..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24483 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 oPhZ3!@B4q_UQp{I*uNX4zUcP@q=HV|-i z^pxEtv1))1r#?*X9c4#8C67-R#c|7AJECcK;xjRXL1@KPWRjly10h;LKvf zWRc>c@WwDfqHY6YgRX)hL-|_GcmEQY8(!!peErU__);R18N&xX2T-J3<7{|d4^;M@ zfr){GL4l!xfg}cr%84@Hn~!}9wWEi#1G z{`>R)qC11&fxGn&8EO`V@yQ;R-^FNAGpTL=pBJ9!T@ zCVpT&a4_)$^SX!oUUliQh14t&Vc-b;xa_KSh$zp0+cr~~qPbE9vl-r0F8=cTfPmGX z<>n003~zpR*i5q1`EZ{1fEvT^y8{2eD!KsOu#2&Sq0Rn>paYA+A0`DRi5f-$CZ7Ea zK*4y17KUbh2Bn6F{`?IB2_IM;I1GL;DX@W*F!StX=wND#V-Rp_=3_ty7wQ;JwZv>Z SBD6mPB<1Pq=d#Wzp$PzHUm*(s diff --git a/deps/nuklear/example/icon/volume.png b/deps/nuklear/example/icon/volume.png deleted file mode 100644 index 8e86fa992953cdb490433a92d087b4a8907a343a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25438 zcmeEt`9G9j`1d_y-}1V0qhw#QWy=z>GfJ`yX3CbG5{Y4y zEMaUh7&G&oKF{<0AD$ncmlwnRa;|f(>ps`HmiPN4-@RkZM9)VL005JziGd{mfXTmt z0a|ME$KQyVGx7(u`z>PwfcM|mFS*!O@)Np1lY7Acz;NN;HwY+t#Y28b6Jly+NVCky zz$s4yEi9QLKN9e=whz${@bi1 zfv$DLkL{B1f(JI!ByF_TEhC)@S`%9XN)Q_-RckHmc|i=@k!Qqsg}cERol9%MfV8_r z@Pr6`5~VI1MT!agm1iwq(Mauyx*f#$7%ls~5;wIzn+%nT^2aMCJ!chc8u4^y zI;T|=Jb7IxlgG-MI`+rkoN0aRKNUy!5K;UcEPEjsHWW4Ivy0S7#ZR7!j~VYvBlGq& zFg>VbNSGC|R7UZuyCm1si5K<*=sC&{)E}<=Mm91v8jgf^(sj^x@SM~XI`xRWmAL}M z+cWkptG1RR;CVfSbug|r;%86Fdh67r$2sX6ZJ!WK^?~rzs5RK<2!OHv!tW ztf@cVwLIYhC4z@uD4ZtZeh%faiVIlQ9%-TEAz}Kl<__SBjP-cw7rRW|&)>_aNE_MN z{*~<4J^EI6zK{x21(#iGeN%*F2lUduY-Pp}qd);o(%x^^mt;4xyExw-7-MJ^HNK&1 zV9k2GDHqJML1k zyJps!f+sGD2;S$`1B->=YBV7Zm5ef~lBu>Rji@uC)JsB6k7Ypa>IPRB{xj#{;aU4| z0;wfsXwe_j%9(6$h02T@DxBwJ2f1^mkuJmFfX}M>*Lzi`_*liLQiFeE8h-toG$*bd zRBRR70d2m$Zul36`Up7=PX^wCMYfSbn@LNNoLSukBFE1l$J?gd|CZX=HHYM^dzA6^ z{Kjb&s|aQir3*P0PX^?_D(18gg!NowK+D4n(c$1B-Nyd!kd^Zl-}9Ow*NpcE=OxsoJJ?;%Q+N9mfL7T5 z_fY^{H-E(6_(+0O3gs&b&Cg@94+E=i-Bw{cgUat^j5zWRo#LGpqds0S0+Tmu0eUO5 zhuCMD99w)%J&MrKl|;N4QCmpJpVw$l9xiA4`}p4SS5saRLB35@9-67#T3OI?`RV=s zc%FkZbWct(W^oCPq>iTVka>2ky|fs_b_XqV0-NQukpC;^8n_5oUOU9S!4mI_`AXel z1B4;RXJy$v#Prpp$z*%AG9QSLj%i#DmJnd}=UV45PZUWv^w#b}$nkN?wY!u$NpuHi z?Ljy>P#K_-JBJ+c8GeiH^%PW1pI?n6Wj;8SX$>MxWFZbz!l7Kh3R^FME*YdJAeD1h zNbk4XE)K3jP9{CscCsTsAScmtt}mQq#1c(_Ht>4DYIF1yy6hUAhz?licH^A6zj09y z5e^c{nbVf5c!ueLaoa9k$k8nh`5VCRS_byJZPO^Yi)HceqMZVZi%p-{^$f$H_u3(QXOoo7koP+# z;(7LV%#(C+sWx~gY32nES-@RuBU_TE3lU%>={w{9^O>Z9M^7v@d6KmrVrE4!q4Jor zCQcNU#g~yR%nqmurO@U|gRA45;wFFh&-Nlz#ctL!tJ$YZg88KZ z*FeoZ!78rr#&;k2r{;D@Ol)}uHbbMrNn(MTb>8{pL2Ix1o+h&aSs@EEGG%q$OPcfO z%rOht&x_tNxfNG_xiqceZe!X}m#3VebQS;%fxutSofffe>;+B~1COVo%&t&QEG!a) zISM!=K$mV7){H8gqY3<|MA*XTEjjO!&I>KSUP!Qxvjh9Dh~8jIop?eGEc3T)l3^ah zY{k{V`CkDx6G!1_0&f)`k>+&|@k`PV#_)WgfVNjnSVb%w+z!66iM8UembC}#q&4ir zZ4VjXq(0PHZLrHQ*j0!QmfSIk6!V*IliXF#GokMm+N*Yy?Vw$#PrRE}GFK*4YOhpE z)m^ANy7XbqFDw2L{(0e!%RQ(ycX=W8+hX(ei{|`tvrU-_axa0g41RHZS~1qr!PvNe{7h1M&}W zPLkbpMAn~Krw?7qp}m7G5rMf?aUNv|ff5&B5Dzl@noxl=(HE~BuADMIR*WTcts9V*R1v``<9FV*eM zCu|M3La?LbQGvLP#deE<2-646rE@~h4T#j5b7Q^5?RK+(KQ&Q#)h1tzM-(tptVY*M zgy6bPsCsYJBaw0~bkC*^|1!dFY+4UapnjRsA=W$b$=FyIYVjx6^D2wmQen{oUr{+Q zm+9?ZknmpF7M4c3y6+0;lI`%G9oH+TI3duk(fZl?*3nRysgN4i_o1=a>>-5EQVFZR zNH;^{E;itj@`8HNjMv-z^eA7^fv_(#jPMoBIRDsEA*S;&G;#|Y^_$dCav5653hKEy z+`$zgy~kZt!oxFnWE<}C%5?-&Q3{y~t=diOvVa0dwk??*fN>9p=BAQ!IeBALC+p{i=ydUgScl>gzSLCN@?F zS@TdFz7<7BK3Ejavlfj-XGqt=NrHP;7?3pdy?HR?sGG=o2MNY{LExgEcBB6c(fd&x zG&%^CPq}Jlqd6PUiPtig27lUux`i1OMJinSpzdsUPmXJK$y>h6v2U4I;r!MjVIL(I z7m$;2H1NQ;GLRJALoANV2jLW36<3c^ZR{)YSfUDsZXP3h??I-r0cs8%Q^uA8yWzFv z;gu12o(CyqOp-@WqRXtGn1gj@usi0RQBqMQPOetrP-ZXfv%{*G-cm;Bjx*^7diiw;cdzgsd9!TtUD```Q2T;+P@BEb03 zUk$7v7@nWW?Ds13fIz9n8xg5O%rcYCgc2ESXt&D1xX-4y32Jw){*to|@{8rXy6+#! zIJb4}c%kay(69I@iQe^puTa0rF-c5}YOtec3f=w?ltCp4p3*c&QiVv-#oU5XEE0lH zmrdF}441~n?>zXszI$Z6x~lzTnwV60M7GYiBWg53_Fk3Z;N&BopBh;oCC)K-lHbAz#boEL*|R1+X!A(zBmU$Pg%6*_6ArHhT141KSHnAO%hY_9!rQ^C#hn znl=LK4MSVIFS5mP!_GHvIU@@ag@Fi_I?U|f0_~b0gFrdVVW+S~0OfM0`3Ox1*9o*r z%t)XpkA>BJtq$9JSX&9C0J)n2?|C1*klO;k+&UC8`7yU#sSs2@zj1K9g*$^^vAK!2 z$NG!GUB-q^!qG7dm??Q2(UTp-LVd%?`_EUtgT*cOMY8Fu5y;%N-xLNx<)Lx;z$DL` z6D!K{G`i`!h^^_3$}Q|x2Oe~qG__fEb{+s6KVZE>FDe^=Tr!lvj;h9Kjcr%1LarX1 z88Z1CJcEtjs}hqxL&Ilq~4(4DdFc^TzIs4)j)0>hVsb1eWvVDKxZU23rR z2Zdnxa%qTl0IAz#@%2FfK98!h39n%ZCn;bg6!9Uwa%8zB7accn8SYwgK{#l^JYMQk zIo6ZSvJMlK6)BQ-Gf>)=!_^G)rb=b}GUA?lR??ba-rQq1!g=`Ys374Pj3!$T@57`; zE5DyNfV}2RN=6-yZ@)W_;{40jCUcJMl?|L5i4u)$iNR>yql^xw6uEQ&BL2coiYgm< zTgEHS?i(ZUh_P*JqZjs9K`ndK$ojicojs7F-Nv%?bI|+7@Gjg@SVTNLI$i-94sCcZH@puHctI1@KE6-{LSP?S+QdqeW; z)8IU>S17+neolI6!tr*V_T&{p$Q44GP*(_ze7nymm{U^S^Jv0W$Fa}jF$d;-S0%s> zjA};&6EvD$m$^xQ`i%2rr^fa^R5?bhCP#+5dRh*y-=-F#F2RMsxrVlov=OC+G2`e3 z^6?06(SIl)QCQ0s=!wa}#0np2$j$v&vJ6hyJAga$aQGczS+UIdZ;tCC z{7M@|?z<#6l*8Ee!_#~9QBvhOx2TXMGa(IEshX3#Lp-2LKh!ki-Lb`&JVWmu&-A%Fv{{-+QKSwu4v%%ZI&4Aot4b|IVfmP zS`i=D9s8EHaiL|aaAb1M0vlUh7!!Av1Ma)jn_-=b@mKPYx>N!90Fxq|iQeCycogX& z6t1D&Jj!ymR7RIhROami3Ym_n=N|KlSU$+)VWFL*}pOF|f$ytL0+(lYJRmmDKu*B?R zdy$3c&#uT`W_Kyf5H|MW-o>J~oU9)0!gW>n>CoijpOiWi?{;7CE&cte6}}AWP~Gf4 z??r{RE}q-Km&bT?Cc z6wbeLLc4EVfb6@}zg*OJD;GKSAubq3F}6*GI$AlJi@t4|Wb<3D0h5+%WKAFa0ihj4 zDH!QX9=9lH$YG$rL*y)G_++dnomulqCVL`Y;pfL|uZ7)KBQ`J5UF^ zKTeLM7YCw#kGVY|xW5tsxTjyWZcDw>*cGrCLdZ_3v`%JU51AEsXumCi`nnjyB;fQfdYcMQEjPk35Pf4e28MRI;-Yk2p$)ECm;f#-vSr6w4rO)qu>YC;`W`pswt+F=t^dAV zF1~=$ogecUGnyCLQr920yM$^ma?N+&z5#lbZ+DXB$5=}eT;HOg<6m~pq) zpoi*dh1!&P9NfBs`3?Irls+Qlch5dMpuVbYSpT#A!k!|=i}Aj$Mqvz# zS_0&Gv)zN4S#g^P0nPxpS}Ebv5Cg^n+soXL#i(WpVoi@4^ZkKl5qo&DTau2<_)90; zf71YlXdmA`LKz=)siQGl>Cyya1mbOU1NQXGs0GX_PR?dYDzBEYgCdah?d|5}3&8wI zd+R=wZ7-Bsm~>TZPLEbz{OpNVjID~J88_%7|6+{apC%^O?nK?Cd&3s66Ktl76O}yu zujPb?&tr%z5#pobXLQ2x1r(53`1!dIMuUkP^!D3ZslCOU56UMbPys-I2?t>L5Vg>n z^5jAr1I+gvuQQ6))*snO8!^23_d>%#IlVCTAkq(_N|8wws{j%KFay|L%V@R)Mirn(p(QuaR0^x&2e~5FYmH@6p6Wu$!FpMxqVlm zakgmfNeR+So{{A#%5r>SPgGx*Nx#lLuTqyh*)@Nn{m%XTdBLbY?@EJ8ox*B5AD1vh z$$1Vis()h{zVa$46|AY%{tSL-@2XZMWN!n1k~Xy2i;YdR2`cyI9lLnE`#U}zp6z`q zm$%OyT>fLbj^ey9cj~b==B16zd%d*pQUb9uFKNk+n>W9O*BGx2(stl*rH?qJ9c0Bs zp@wr~`V|JfoG@$+?hETOz~eA)?Xn|nP(+{#@z#6iBz2zHgP)-I2JR=6K{}@j2e*K}j!U(l&st%fySL2%Pmq1l65|(DdrLWP;9L2GyJnCky zAIr>BkYmx}C%r5rpDsnX+0@x7a#Yp3V4QDiHWJyF zT8n^FkpZ1T(zY08@H{+GyN2R#0?C(B#C2rsPAKj&k9EhEs)=S|_yWlJrQdBQAN|E* zc-Dx_u1V*q@i#x1U+Xo;x=XJDl6p%r&w6q=K71=BPuVvsq;M`owd4WeHqNOX>5~Cn z;`*_Ndz_=N7~|n;?&{*IieW|>&7UL!9lYdhK~BuisRT@h$O0f=PlK;>>dMnslRHB7 z2yLMVxudYJ{50-PYM;?U4pt3xf9kZ zL^+UiJpFmnJQFlDlXM?5j%tP+D`2v_O+Fm_l_988t zj$&XXH zX#Z==e{jY6hgB`h@oaI(F51*>&Fm0--KlUi$e_*TG!%ZYj=m`HJ;!>K=o=0dV$~}b zF#KZVdkLz0c!xUPEj9_EophEmVyO39+k|dAG$r+Ubr)01limzlG`QTX-aKaLB7~On zO}xxBTsk*P^GMZFwN;~VULG|-F1OyMYd_l=MYn!Dmkyj0zPvnz11_@_h_1!C#$S3><6e#%Z z{?4}(mYaoWGK}2mCZLYUb26rp-o1b>DQZ)7*co;t=(;#1 zR@<;KuTDB;S~C-(u)R!`3zaMZ$6!nyqe!6Hye&iD`Q7m4%rlWmwDd%5);a|fPix}D z@9Vaqdp~zcLV=l$k8KuQmSUxg<{)knK%kr=o?~zM^LG9Ucj|3xNhdN^uj5UtXe0kQ z6#lR&rJ#UX&_o&TF!{e+fDx7sxysSPKV5ihf8q0@z#n`(R1yB;W&F6Giq9Eftj)Ob z&?mMXOjFJSAo4$X#Cfi<*nU}Fjl_Suwn2s3f|1`Q8_M)avo#Yk8{c2S2ethBSnEqr z=aBq{g@U&@Sv$UBisdj|qGFeo6}o$Tp9^C=lOwNv2gioF8;+DZ5?Dyx55jnlEKzSz zEaW`4uzj??&~RY=oCE(8&z3#!psx{Fr*x1WWp^Ig4)RiPO67ro8j3V;?hezxM~YJm=eCjtNt2 zk?jM$#UC3ii6?U64?o|C=U9V!+)=6*yKPp<)$6XAZn*rfI$-%_QKw{py06Y2C}fml z&Upm7L37bO_ybsEA;!v*ceN`mw9!SIYNBTG%ZNNzR0sY;qib=MR(@O!Y3>%dq;2Va55+~jNHLc;nz*H@y#;a^ z9bz+HaeNMnQV$d!SLfpi+eqr(u{Y)@FRK)rqgZw<#5uxregNNN48sswiKg^>H!Z0e zy+T&urbbAYu#qT16u~DA9RHEzonF>ipy_G|cJ*fd^F)q%n2Vl}@3Yrn z7E%8iFBMmo^}{`Od5oy8M04NTyNbc007ufUdQcmL?qb{xrLnw&(jVKt{znVBEc$yr zdK#V1p%U=P)<11BCr)VgqP#k%TCr|Wt>tqR`fzfyaBap>_79KcrxbS5NR*npwl+5O zy;P5g)S~zc$-e^B(VG0EKg(80F1ddQLlzzDO`j?FF0)-@TD)+wIu$xI-e7Wcy(m!f z()L{6p>w#vbWT#i?VLO678`0dhrowozZ-3K*My_6L{>}aO4lFR)M@s%(L{Z`ljSjy zCQcuw0jY#OEp*Cis0=-r{NqV$@!svT;9WYwMeA5Bb0|*rE)<$q%YI__#Y>iNFKsAn zH362cqZCu=&Vr}PFuPKORb2RfyXgw!!IwX)(_IQ-g0axg-`k~92lG&!DD!vOT2l9O zKfTMY^$XAZ6RmJkVLC}&<*qIIB+%+qJ-Q7+Mq0(K<8_@x085$tAqvFZun5G62Q1ve z{PY)3&GMRZh~3C`_yt^;HYPQg6A-XG*g9 z1B7=rM>kT%*bSj7ZZCjuvfFry=+Ed$a`UZj_ry8A9ZuE=T;_u!WGMT&gf9<`-D%PV z`qe_wgs6K!u0*c8EV{}4@=N~WWBQrNU**Rfsz`9{|+qpst#Vx_-yy3*Vorzc&!*Gt|fkj2S@(==Yr3Ia%hRCMmQ%1KD3c zsFt#Tbx|$j661}MCqFp_f4pML1xkvX$6wnJyRr*))5H^B)C0f;n z???aYmOS;=x&$gbaeaD5TKHLwU2Yy9F>Ua()&8Hvbb<`Z5LH-poV%WtQFZQ-@Z-!X zk8Yu+m!Kzn6Y`wuF8!q<8m+Hrs6WJ|ytfIa#&u#9PErWuc__r-yWX~Yrz(d-yH5Ao z(IF3d1FKEJTr>9BE2N~`mnUc?U$h8>R{A(dS)l?3aZcDb5*A`1kO> z8zg|7M371bG#(9O7~bkl`V~_<-fHCCeT=gj+YXpIR-A5b(_AN zM}4DvPd%i4L~UFG5ZMl)ZIREhIYerw<}Vcuq&~879{c#UU_y`}ih5Xe+`0ZxpJa~t z>F6F_P4^vg`l6TqfL0#wJ~tUNr7Ecj))`1eUySfn@eieclTldm2P>ZK{WMpQ3Q(Iu z&ndMQ*9Gun)~m2JK2}R!u#;vo%6Wgj&QV3yN}oPOlTB=3BayqO%TG6|Dv%I5pM&f^ z=u$%x3w!XRFdw@q!FI)Gmn^D#SsNzqql%b1U((`*eqzlPTQjY8>j0A>u+S)`J1V*2 zYVTo2l^?9kVp0WwgvBAsK#QpdcLoMJd_lftB@+&GFcac}7K^iuh4Qz(b}7|&H0PID zCa6$vP~%noh&QL9w|>v50(R?jZKsp|)c*J5;)c);oz<~6g~xHdH+SeQ_yFn4oCupb@KC%rul-hCsq9EVkm0aS#>Xajl9|PL z-%W06f!#a6k|)G-eD7Kahnj>qj$X_o{FTZ;gj~7tPf9A%NI3aJ&Da;FCMI65kM5v)jBa=l1kms zp)=%|1Zxd8i5)>#j{80MCO59#0LM;AF%o>~;`NdY_d*`4_G}eJ#-QZYzu4Qwl?PI4 ztE9GCWxp;KGkm-2RH?Y2&^l`JChqFg$5i?6^XPnQs@q2qKWg{84Gh>9PihjRzbAe?fLD_qiXb-rLc%+KjdA=YztqtTFKuNYclv&D~Yd`5_nzGn)e|NJ7LeMcz)OZTBJ>uo$ z{RR}VlWNUc<@`q(cg5+eFH>77*KjJRR&vnm?>c#YzIAmZt+c0Fa^7ddTzs3kO+<+hho>OFMUN0v>lw~cLES~gMAzcQDn z*02?yny3Qnh|34b$@Y!EIO z7d5;3c>qZ=`uK}|u7x5`Yq#hIeypg1K6T*O#;`T?HMf<_^od(js9qB1o-Zc4s8EQb zVr^fUx2uH;32v?#^MidqEOieY>yZWR)f8z5yq*^!ZGYgsLYZrH`}5ZW11eD>ov?q; zo%iG0^p`Nt^VsgVD(^L7%;pftEpRNR zcaC+CD1^%UC#4O5rT-KQu-~X+c}6;X%306q?zWMg4ThSI6d>aie7fLcYFh8sj`miI zCP4@_4IppQ^$0v-NL^LN?Lkj}~x%L$0UEE|C{6sXK zr{rIsBg#ZPsc2T_?~9@|E8kY)hr1r!6|{fgVNq^zVXY%Cg@K!QN)Z)eHsbLG(w~ZB z*fu#VE@aRo$amEs;G^g5pr?uq&Yt@3eO(UMovdpQ=Y_Zc9}dkGxSVw%y)YM4*tdAz z45fG#*BzDjy=J-e<2>$^XUAC-JoRQ<6IPPgT*nLwwE8F#l#_iK2x3zu)2TS-lU)oF&KV!LxyGJGg%^ z>4c6^Tq~ntEenr*{flj`_r}p*%B1@M;S&`qfy{tRN+!2etE@ocpt6yGd_JlqcR7b^ zCeg*XARTJaxLa+!TNW->nAMsmTLq-=2%aO4r?V9j1$8t6r`d3_A5N8w{4G zv`Fgg8d+*jpw#jD1!@s%$s&{L^cc^m&Os;VFN9@m#kMTuF5;AcR@%~Bg+yA6$ z5t517AjdA$Oo2DG=sO;oEo&1A(1aUEC6#}?=OhRI)JY`_ zpGtj1Pv|R33H42;KMUZbE#y0e52Cgd-Rb{?N()f|C!oy&yP7Epo#=HZ@4uF$dmTfF zpmFfpO;@kDUsHCJI<&$N=Zj>rGu2+sQ>`UdAiVzLBU~a`W$6Yg4Ax?zBV)gVtK$u( zvzhjv_H0`}Rrv#D9KK1o-`s_@%Wj@WIY~d9%B(h+&HuNq!k%@PoQ&SQ2tHS}{iY1R zv{435U_WMVLZrOercII;UTJr1} z09P5;5!CFvx)?TV5E zVW=VCFYz~au*acca1z|niBa#Z{%5|i-p{0_yOrF6-o?6W_-+xPlg~9-c=r#^$@1{z zr8K|+BJ0Z;DD$jn_YGeUlg~+G3#Te)toB^}W^e+PPO>_1i%fTAb>|w}HnJ4&W~b8e z^%zqH-zBtveZKsqD;x08yeUgLll6biX1@y0okOHK&%;Spsy zHfC3h7ItU6Y)@B${AHu1 z|F8r98ShanW%Hiiskb0i2hlJ7=yiw+BQl>}Ngr;_857^j& z$(zDlT3afT495}N1&MS0E%LAB>jn>oga0r-^1Szzxqr0pL0|cHd6TB>i{|;Kl?Zd zxNAIU`n2nbW`ij+yyD+S2fX}elKJ#?G1MScEXn)oFCTB7)LsM})acN`!de#lVUV`n$t$_EE zVAm48%YZzW>g<(-KpfXmD0l9^x#SP{K*tj2c$bgmh11bjmC2<99^MM?V|VQVQ(3tD zr+rPaIk0${)H~C5@RKinsq48h;13C;FVCn?vH_L$W3pfS6tOJKY-q_*s}{^F zD?9fUF^Y(YK5qKYi_IfC5;?Zf1K~sma`z(iHBK>&(59UHnr9(hqE+GNyEE4R_I@{R zIT*JS7d1;3GZ+fIvU)bOz(*z|jN~cvPo?wbf@LkPkXesp#6ucOL&5(dgOtZZ4EViE z%;%%jIbV>WN4DpG^KA@p==(0ab`fdxPiblfk2$mkDu@1f`_m;S+ViMVBgw%BDUWZ7 z$lXe6oQEX<8=PvBx(@#i(KLG&7RuuhhNxtp2Rz;6VAnPi40g4`FjJ*g)C09!_yF5S zl;k9b^Z%??9M}Dn`&iPGiLUsx#qc=dmUQyPW!yoLc6jU4^}+Z5G{17aDnXTnTJRN< zQ(ezeAEw0m*$XnJVD-A9Hd08gX_HS+VyXG=q!1<&6Zy|wc%=Wp`OadJ8KR4=kB>8z z>0wUvLit;~GX@)T*9Nbdq)5MI-1~+yBQGGy)KfBwlu3gvPIs(Zf=chL%h!VL4$;9% z=!G(UcvpcjJJzG%ibr*(SugGz{PQ@mBCcyY*kVwCFX|{hNMm5E>)z)v93`p<<$u~^ z={NWWV(TdcJBk};$N(I@Agb+GTgM+>h?Hj#<|^C!>q6sOHrFSnW~5zfdQtbs)>7Tw z09D@s7a#U(K?Da&h-W`fCUnSk(Q@yK3yW~Py;k)*9F%8IdgRV|}dudPi~pXC3Wl!>k{uFHgnKjqdl6L$R&~KWPVsQ(i3+(cQhMh`8qR zD?0o5Q_GJ0-&0YxxjkHw_U`eiXZzIt$y^|1xeLZ{@%7^i_sPz*IGahnK>~_S$sI?> zD_@!23t(=_X}HDHj`;TXNvgac+jQM!;df`d?J^Nq{Tpo4Vh<@^MzU#i;3IQgTJ&k( z2KpE`3JFnS^(9ljTs`kPtCC44ftMRTemDGpKdY)wa+ABcYDDb-^zaSxx~}UPS_E1w zPBoCN<*VO0d{r;$xr=JW!ZLqc4MZ-y9yG_bg$o$peihwxC?DpwjjI@Ys`^d-RQ$*W zB<%#eFJ=cNy+Fr4Z?F>X|1>2m;G>aZy;rjUOqK~x9`on%yXVv0-6&d}yk`fKvSepe%-Sa*Q4137)04goQSl_?jVrXa z`S#{Q_O&$*ZC=p&VbjL7Qa?*fM}LH)GbcdK48IJGFD|3QJ??_7XoVBBNMz(eI`HDN zN(Zxf6-Ez|mZC;kaqfACziR@>wec`@WBgKfj?@zc~9|S>%HP@zW(dvib0g zMK0PAAnHy;z^7ezojdwY*LgBkyr2)fKC+MrUO+@=1=%xrHRnAJD$w!2V*BDP@M(ok z=Kj7)%gV|^qy;27#T&$scU8uzIPmF`+|P{X3q^>uO(omrf}?j?I`D(1ALndgtUm`(>_zuvlxBP63g!);#KC=-+Mkwust>wRSG|=q zxggjf^YGXZ7D5?#&tdgiHdOW;Vr(mc1h%lD)m%|(2!Dv&+$g*^AUyoQ><$~E+Je$(q6s#c)lm2 zI4V-#`f(DB3>oG@W~r|KU}kl%NQ2IiZ*&Q&gO*4dMti53QZu6hYcnZMwU^}|(|>Qf z>#5#MYW#!Cr1=H@5`;RP%@m|@*T9gwJ+_L)Vw`Pv-OE|WYwq{;{!Nf+Wt-n98(o45 zM3J(TI%W2z5@>76W+WtqZGi6JmEb>%ZlEdo)`nW7{U`TGKp5=2hApF-CExNwn0wvQ zNlLzS{kyWvxr+=Q-^@3+eeF0CJX^C^HJp^;$n?tT>q)=b_8m!0yZd0*u|mPUxjzNg zoJ*N}e_y;mxKcn}O8aURi&%d|2ADP2!FozX2-O)pi#bV65g%i=1WmP;?4&q1U-`x5 z5!75rD2c52AY96r8p57Ry|Uwkz;l08WrB9MqvZR58t{&v~5=}_yE5W)x8 zkRyBCL{;yLVKp}TCu9N|>K>M;=h`Pt8A-;=4VbDACL`KBBia(2^^yj}Z<3nH{eT~9 z-iu4VkbFf_J+#mHP?4{NXxuy}w{Y(vRWXM5b`Gv-m0lksJo@Nc8s`#`NE@DjaT_Zqn;fZ=5P04kc5 zZ?Ka8*-k;^j^GOHB=-`}ORYKg6);AaGilnFw$5Kq30psVF6wSHt-kiP8H^GG3CGta zDjzmnWrLacB6uTAGaP4wu*mB-%spRdqOV500%F}EsxwMP@;C4{l!k~Fc{)V!M9VX6 zh6CsIZ}DY-!rarmOoHXlcFbnT&z zAWidZdMc+|T^Zd0wpElMqUpC7PI3yJ)Xx*G^e-@Bq)^jUG4HF5K#)}WF{KD8{>8%B z50WD8GOj~pU~ejd^c5}lxdPMJI3)`ZImJ04tkQ%OS2jIHtxQN*3BqOh#a6P1uiS{+ z4)f6tflTJ4!R(P|4buDRsjmC3`O9Z5ONZ4qdQOv-&m>t=Z0D(>H1Gow){B60tG!pK z&AI7Q3T19z+6}Ow{3LL&1shpLQlF$E%9zioPcHA#C?dih>Dje2U!je+kNsC=`m9VE zHX`Bjtz~nM&KrE@QejLI$n;3Z$+^U}kI_RymI3i!hJODo^qrlNhMxA_18NguwN%U7 zp3=<u1)pu zmot(()rFhYM+yFzox`n_(;g`_!S{>voLt=UIIHl+n1}+Io^;0xwhq0zS!Kyn)>Zba zGA@+AWpF5h@O@0SvUd-vx`1kuP!yLHnSef=qG~~kfLN75U0C8u^!{~Z@1EdoPioyM zIPFt26Sq2AGp9AII7pj1miheK*h^8}-~LH50hKh>59^z(Zb8SmU9vZ1(5lf6PqR5=^8 zJ1almZOhQ%kol97A%BBjEyH?zza2{y4A-7Q2Nb8r%8}9{DSs@nnN`ueAKR82V?Vwa zTtPS4Fuq;PI8r#La${aN!Y|H4vDno+Cxvw0Qtgv+j1<5KUuNZGkV%WxSWq70dWtQW zmqBST*lL?`QGRUqwtr-~}Y1s)E_x1A4+mIuY;1xsH2k z4iyQ8icz;>Wox!B=10FesZ;WdQk{LfyLufL`u80jqC>Ui)<^KA=3m^cbd_~^jDP5= z6f44OPD4RAxvBcZuZ!e%PzBn@I;~@oqIuCoP~gN=P~Riox};2r!h)|ZAZN4dUW(WS zz+!tn1XFl9u=`U3I_*8qTz~ekBS9_$)5_AkSZtX|A~2~1d^mkyak$Gy72)@h{*k4Z zohDxJ*~p_U3LM3fEq8XNlT_B%GUoWD+p)=N-{*5T=GW~}b`S3fFbUzi1jH+!F zt}Z~1OD^igDqUy0`%W*zlx;drv??VNv2M8XD!NSIq_WV=ju^vGBF6fgmj=f2f*!s7 zDZ)tp@-xC8-*b{~&pM&+#2kSqGTz}-audir+6Y!h)@1~xZj*X=XR;*b+0Hf{)B92) zDC*Sj2;imM_iNXf`+q8yEH4N|T)w)0$c-gxhA(%q>uw;T#Ki|`EpBpPu76PhJUYS# zKJ+W?T~Wjf9ElU28zaQ79?ZSo&IlVtyI5{6!)GF(9*&LGNuS)=w*JEHlvJcH06pid z1i^@y6$%l5t?32E$dts_Wg?=qJ^8shCw}4Di)hu6Q}7QF);FvcWAL@p#n($!UDvzq zVB*E|?RD_s$=eAS&iRI&FKIob7X9VV7CBwlNoMOmwG$cXp0W?EIZ`vhARK^I!=Bsj z=Vy=2-*ZkG$WIlml)_mq(rTtz`(Uv1jvT)Ltn6P@Ef zfW_jNM{&FxS>8;V&#Yti=CH)*@MVPx@IA)czwadIrG0h(uF^^ZXNn#f2t9x6l(%~! z;WriJc$zJyjNI~mX)W}CZk(22Cy-lKG;ccNAjXRcBBOwH(NNhGPuURDou}q*fs*A7 zZ4X66D87BAw9s}9z-U#;JpC1iUo{N7XRWh9;XcM_B%YtF6+e>_C2ydUw8T=gv#v&txHI`E3Hh1FV}W%R;LJ`N8()l?Yr;m7|e@2dZr`oI5*krO5Y zQlcP=fC$o(64D`!G)PNH=QeW)f=DPMC8a^SWGJGvAe|FQNvQ#2+vmQ&|HgNZ{kYfN zz2~0SIrp6Bc|LE1mnQ6hV~v`4cyuG2w?bh?<$Z7Wra!^cI!Ir7N%`Kvk}bRk6&&wW zZu%0^=xUr)GrIP}+U>~5;w^Vg=__&g(p14n9B;}6xmdGCI%n`)@~Gw>aXUt|IzRpJ z(?yT`Or(S|Kf%Q0HSw0DP>i&&dr`#5iZj8J}z^PFmBXt4!Q4`dKHcFpLL<@+-br_rFnpz)^4|<)-Zc}cC zcBrT(&}q|QH3jZCuMCELf2*5C%}n37v-sA$ZmFTMG-R8WRS3l}?x#(D%tO><9uiHs6keIRx&4w!3nul@`GY1p{aYHy?I_sMfq=pPD^M)f&fO>{u+2EW126o@ zUJ`50Uyu&>)l%5L&k59%Ds*9zeL2Z~I3o35=GXfZ_YbNuiL^3Bn>Uk7u7H2$Y^Ye- zX|f|k5$LanUrnAYp z3HUaA6TZpth;jBsU3;*Aza2Y03Pu6_r;_n~)q;sCWTdA#vM`S?=6vKNwSLi;4kyAX z62^8ltqX!#$ai!swKpxyuTzS zD}v-q`Blqbuy}xnATgR=_h19U5Ba;IUZXOdfmuiKfw{-8KlK138#3eTVM&u-i}52!^vSCu-NM33S%=p@7`HzhY(NiWgYe{M#Vi97pA z*Lr{4nMGv;!Gd-~bMHAZazxBMyL;TxC=9(XJN7t(+3lyS;|DL_xKFXsmIG{8(qt(< z|FO$kG43+6$69Lhe%eV1VO56qKQ4c$UfM*VfAv2q96+(Ff$+JrE5Ycb>HGHve9RFS z0@)yH*fxt*QwBeXz3RTvgXcaGcJtdG_h(Tf$ytG>TXApf6ItQl=AFW6*{?;y;i|{;Y*%`z*M4zjjLE4 z9abijmvBuI7`XEzd>3_Kx~HZ}Cs8s_HO0)VKL6Z9q96w;jJvoi%#C6aW6p2PCcW`t z;Ipp&nD4o?nw*eaept&AZrm+|YxnX9rQbmiupH|qxk|^YR+)Yt1*A}NMua-`_qvL* zLb}1EF1^HY`pICTW{#EmFd9I!K%4Y!*c5{C)~7-q@RhEsVN@b`TU&C5WD(odZS+3f zl$s6%IS1yju{Zxjr$~Oud4grOr=goLRcS6`BxE9EsueQ_WTb#@iIm@Ud62xK=N8z2 zrKA)0WFsxjHL4%eW8PDNuinm!eJk!PTcB#%N=Um6fPW$m61RLTnH(BbmdlzPgtmOjPlc9eI9R)ilb`dfca z!!l{?IksJ8&|tCeW}GGK;n`~rFGveNvw9d1(fX(^0>K8FYqQ81yu8t2voARxOoZy( zOx9C5l6_RAVi8L>x`%Nwpu^}|el!$|*>#nSG+~F*Lcc>gXnbFFymRnLGrF2NSXCd1B-uE?P?xO_>b)%EJ-R#=hZC5)hpbHT|wZP(TtcvrUs^>y)xl*4{G(t z!w!WZ&YJvcYI!`!pENRH<=@*2u!aG(+zJo0l}3ZdZvFG&h}iTjO`vT6bjBGr(s}Vi8bT|CBXHe4<%TjBYjy(6s9O8>IuA{dO8GOd9s>z(*7C~taGI?_$9nS zy02=L-{h3dY52kGA(s4NQ)EaYXnTFTO1w64C7gA}@O-fI6^@f&u88PgQ!9XXD8HSU zUguKjFt~FRDm$`XQ+ip*PO2WW09vS=eBZ+clEh-Re`;V~mgF=tR)Pmze#&7smn+o& zGS$PYEn+IbqTq3!hzgoVpjq}wA!>xANquF-9?5&~_WEgR&!s$7`<2CCm5RpPV7>sN zI%X9&<*=Wos`9Ry-T8`DD`w&XiQ*0#swj^QKA%HO*zA`sM5){f1A&DV;R-&V^lj#rd7tJS*ih1Awl}ij~gL4k_Q9t`5 zUcs?6OC5;T?7yF>rhA{M!oL=F(q@6Er&2lT5D2i&*MI-q_h$Y7oSkRZVK zS|%oGkN3_0Mw|pA{rBFePQsc@W46w1CeeIxQzzy+G&i4zF&dTSRZc+XnR)(h4@uPS zUqG-hF0Ie~#BX?khe|g|6TGK8EhI7g1|Z4dY1novRJ%NQv*-XnaJ(@l!84Y#^~z*p znV;kOvL*J(%-cQW5&TF%u>4UY)p7_RVaSb)=OqMl7cv`?-uB#hWqSgU71rR~+%L`Xu z-<2})dD>w?$$G_m(^twdtE~xm@QSoBWcY}FbCCwc`&dX`S!)<>2|^tbk;IZmej+u$_6-JSgn*6q)R2@JD|qu;z#9M$0`kR-FF zJeT;qc@Ml2I(Zg&n5hAnXn9~~7$fCd0eSC`^VyJ|z+1{7EL-BM^!PH~u$45A_vT(1 zeLVyJ>2n1h z=#QQW!5GtvQZQj3UhibX+lrn2gT>u0-s*$i9AVLyir3*&wWUPVnb7lGrmip*?J*^) zMK*y~(gv3gt-2zJ+@^1PVkYE#<0-?-EAW(h`>IvsSl=DI1ior6dVvSwaf9o!7r{IA z#3GM%UrLh1d1!fRbM5Uc+0o=%hyB;gsf%BMi)y(aP6hBv*&A+UQOC3d=50!diNiA} z<~t%9ptXMjjxZye}rwu6O+mFUbGeu9jJE<&eN*-i;C? z15wfk^M@;fs(|15Sh8Hj4?^UR@RWGFMTaITt$j|<@^;$+ZEJdEopG56l}z7hR)Cl* zmkgr~T`@5d{w=Kwmct+k<_`-JwKiy@_-WASkDwTK;8yMQ?tk|Ev%v3q)`(_K60Q#6 z_WC~W>n58xLb8PA%0J1qH2*OrZm^oi?cPkPDcIk9nOr*SV{C2ZJY;wub3(t4g>OR6 zy5<(3Jb*x&WmkHGb62SbSeagtc@puXB7> z&3r&~Fpq_tafkK2*8+bzM$v?Mg{=!rp5l7DsYwL_sKQ5a{PgO4YVU2%2g&x3{J;*kYxyK`c{=AotfKIi=6Ih?JtBs0 znF|^T-hooS?uA3nL-rHlK^Q7c%*HmerIc!UuVQca!4zI-aAd;i%m{L>Po8lL`6%#P zIJI6!Yf+{!oJ1KGU5A^zPNHF!$MqfNjWGXB}=N`St??f||+5ayK#f5aFCu-{}Z zAbv^;xkXw;7F3`YYNHtEzRj01{y}m1`zx2qltxp-l;^cdv0Obb4EVdZ)ZIdk)EJa* zDkrz&gZBAZ?_=}^HqG&N=zQ%gM46hZJfw^dfxX&U3pb z&&3^zzWArY8>UgYCoB9%MRS@V+%v{EugxD2rMg~K??M z|EL-v}L3ASjm7EH<1xrZBc_dNv&(O{? zfqEW3;D7DVxZtFpQsq?L6i~n_$_m;NMXoUmLNWxLc@1WM-#Uj-R%W-dl?Li(#v6rt z7;-t><5DVm-y>vq*4$334=JZBvbWB2HZ&+nU5;5%Nj8~gZhE!?8bz;QZ_ zt_crA!kxI4-795aJyQe#;M~`}0akI~mEMdlmG8`dP)9PvZD&uINgkF6a|$JHoErTz zhs1aStk+84LE`aU(J?CsR6ItOgoam}vhW511DZ6=RWM$+*m`W6bKdpyJ#M=JLC_fH@sw=x%d zM$n`b-F*rD4y_vMSyHR&G{CQ-83h(8kIAXupY#=E?h*qCu<78ook2IM5&^K2WVvJV zbym>LpxyAt#@aV3z~fLp$hf%BOnCIoD74UBDg%Lx{MVitcF6B+qq`o2%f}jk+BjA- zrISn|+_LZT;X00r<*6=4j=`z=zR*jBp0|U%EBS4qwkmaSk7lEKQ4xw!p0)eWhD%fh zMv6lmR<`osa0gUTnEAZzLKE7pCU*>7SOL#Gk3^-L2rCU=4=6G_k0yCs3Q+WgR4>)8 zDXT9prHpvtz7<76BbTm5iwsm|58&Gs=y&t~${IhRwtAjZ!3|7kaJ!f`QyM{4y#}Z> zZ;3*Bv_%0|HP>1;oKDS3bYmOIep2$D6o83wRCG~Q$NlkgmK9Wudk6w&jX3dYF7GJUu|u- z-W7Ir7l9LSCT8Fxn;ZnC;pFA$oJPx?eKR&fLe9Oo)8xzHy)CAmN#O2G*YrmMU>fbAdluUu>0^P%W){+mnH}y$rhbU zqI`#3Yvt$991v0TlW`$3rzNQmi9`I0DxCSIyau4U%rW$oEutyiEp8+Nm-^iT%5I5x zKT2wdnzt!+acPIQaGW`SZ4Dz^&&GO7sotK0QfP@%U<%s9Yz!Tvk%?$Kf6N?G<7}O^ z>z~^Hk^3)&;s81N&~8Wh`>au`c4qMzcCs7GOp*ZqY%+&_PAvmphZ-$;`zs8>T63ei ziFYVLV#h-TDfTH(skNR&duqfH^FS$e!@Bc@$~6#I@&B3ot79=nVO0Hro#gj`0EtLHkmqjYXoFP^HR-g$S6+(x=lXzFRm;uDCXW(g`? zzt_h9Gh{`Nixg6ydJNKifJ&kszm-JTvLHDmUks5A zKvI=s=o0LtYON{ZK^eFrlTC?k))hE$caTbVZeegn>MBKcDV8bzL=4z;4vcNjJ0<@$I4md;BnZdYuxAo8d+v~2ol^LLz@m$k z9jwm~+)8Iyd7HK6=JiMy6*;fro_W$WC-$~ywJ3D5z~T!<``2VES4eI^6+DVN3^8Dc z`5xedFA!c{;C?|V4@n;+ZttUIgRTyye0!bq8r$LcbLJtxvZ&{58MrpQ7=J~o*t1#2 z@ir7HWp}ytw#eq=JR+P>>_M%io;IUO!Va!)6{U1Ha~T_6oQ1WWvw9f~y{03-zD2_O zB+F=f-HoY-R@EpHQFO;!*sypB`DMS*T4~Qsa|IeV6J1)+D)gm<+<4t;t5id6!KF9+ zixu%F<3cxuvky#lBf+weq2jrhoiv2p9SX7-f6VWV`;(#xB^W% zJiZZibkidm0@@9fKW>!oP9am=jl6bc!9TBF1AkSZ0W?VE{iQ1r7qtp+*VgNT^hc(% zK#IkI74G_^vkcHjkukIZK1oV}Cg!2EV|mJD|7eX_9IYM)sA1+--En=Y zCaMwi-7cCaA>4&|Mf%!r1ZA!|PFB(E@pNVdx_9L>6q! zQ3hTpvgS4pMb>du-_|{$-X-j%!D+TUhSKc&zD4pcUb|K>l}L|nu|Ql7MJirs>h{9F z8hj7>%!LeH`PaRN3RNaHv=@0g+G*GhJ`+2Y1RK8tynHzGMm0MLUfva75`PPo+R?hz z#C^$oYGW$33SkOyARk|3gMpX&Yt6Kk~8W1M2lZLgEO$!Yf zW?uCl#GcSXI6zgEZiOL8+i6TKtt~I|rKQX39*fr0r|4|vN09NQp(w8>Rli#?0{n}u zb=6M`t(#k{5R)*TbD4B!;tP{A2xC3vnq&V|+mrbQhm-gnxG(Q%tBy$nNokaccZ-Q) z0eUEXxsU_A3f3Z|L-gbWPi-}L;zX#eZfw;`g+a*O%D)ls3$D7oD*7;K!@sEe;M3v) z1G)~_PZqd*y$Opk&;(pGYIhS%1Q(x#1hp{irqYw=`gW+TKFpMBpudmL8}D3rKcGNk z54Md{pkXiVKQMZYRd~NE=J{Y$8b}o#`h$ORl%KX!u4{FZ zs_&7sBc<1V{gy@-P52`T%wIQ}Tn;4h_8LWwUdJ)qEa09-=C7i5;EzVm%D`moG0a~) z1UZ}48OY|ZuuBnU`Pixh!k;ir2PEzv8Xuja6!{H@Iy+cX0j$u|S2`DnVGB2y zv#noMcSf$j9xL*O`Id$oiMgBVlAse{((SNrW#3Nfc|z8hM(#o(v(Ct18Q9ea?;|w> zn}8%PPNUDC^`T>)bUL(tgv`=p+S*C}VL!V?lOV#nC`N-40gY^1LeJ&O&ldHK0Y8nz zdm;naZ~CMFJw8|_^O-$c*!L^PRHfYn>?FiUueh<>#*Mk&!oMXrJ#66?DDf%^+ zEx&6Jx)g(}fFC9EJ3sAoFk*E%y-_$O)e4!f`=XYpNhXC@&M4{fNGvf5Z8FGs}(~OU#pR5eMZ!cUN}S# z;AaFDpQ;mmSFOQs(ki)BHTsKEvT4d`DWJ)G+_Ju|W^Q(>Prmi$@o%iqmdQ<$w**nQ zJ@=>?4=4Dj$GR)sjc$o7a>(x8 z22Jb1UNn!Gy?|u4q&hSgWgTXKv_)`q{prsOQjTcm&+#y}Wi|`;|DHNFna}^4`qJb! z84O6x+iT29*mmx+j?x)O%IQXgR<-ZRIi@A}?MQ;(bO-uJKDKzv`t<4J+x{1JokOCo zirbje6@~oyyk+TNs&Im8giJtCP+N8+vl(XLZArJF@))B#sTJ!Gya*IFp5-DCh5l+& zU2ilLEr6K--735hDYmS13MFvk&GD9)nX;UnT9Y1_>Ihvj=DJ>XaI;e30W1F23PUFb z9~h{%TProBHnCI{!7im<>*L4mf6Jd^cL9GB{~F(o4O?1|X}HP?(#fx27)`}Y*`2kH z;f3e6|M(qQJX7i0cpgB8{kaDMK02C)8kK5}PyPpVCLn_V diff --git a/deps/nuklear/example/icon/wifi.png b/deps/nuklear/example/icon/wifi.png deleted file mode 100644 index 270d55d767315891992c70b8d12d8b1f21f49667..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18857 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

*c)4>O8CxLPg6)1 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
a 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 bl?+z44X@Wq_TA!Ntb!m1AAj6U2i^MEhH2N z?$-9G*W=kd0L=9QZH{P>_GS7VBrno+5~@%zbT0tTByc$1a$)@3gXEPolrOojp8xOU zv=c|!Czt0g?bLJ#xeslbU#wxvK?})4H@A6&Sspy;)qfx*0oBK8$Ixj&j?~aH@F^{K zGcB=`DAYgJ4hqVBbfg_`wZ1&}ViF0N^ZV#bA?WfE z>2nn8&_mIHAX*H@#zDLM>Dk<-0qpqtL=|?uxs4iWRZOAnq$e22+r&xfwF!`cz(!#A zJS9c=8MTd}MDEZ7N}x~Swy4b2*EZzA#XnZisJdzik()pa{4 zYv>sb`rl)CLe^%=OPMYsnD5zp!i=7COF&^i!rX^9wQj%Tq~oVl$4$QtFW2H%&V&wx z==rxW1iOc2et6K~f7TY-f&I~vo?lxBWJd~g`uGWb^u^)jVRCNZ*i8fTi~=kB~K?LK+DJ2XKXieT+ym6VqKcV3zslmX=k z{oKMm z<{6tPZys01VB9~s(E!eLhYY7_Y$D9SggYLZBdvz`NoP`Z-Zl5fE8nlBnG~&dB zGBG7!e&#QNN!0a`!p7{I1MeAsGJA`pp3ZNEjq^#j~0NeI1K~xcTZn z?uF%5E_j`3pfj-$oJ_f>#CiVrD?CrjMT#)cp9v#E(vs`pT<+(R*zjIfQV1XYH!1gb-7*sN;dT;xroD_sf+xbyb(gO#pG?$*B13z=u;1}@DW%T4M&@BD6uj@@>DC(hUPzC)#D6L-cXA_CuKr6EJO16D3i{TV z!UU=~(JGjKOa?DzZ9+F8ZdzeqzGG+BUlMlzYD*rRdO(^%$C2y1bfUkR^&O~-ds6WS zr&6ph*djTtAn_S$M$pfp(5jwgf$iBQE!ebhSxP)zM3$GA@4~@m7Z{igfgwEBBTfx} zAmZoNS252OTo8ijwa!i8k_0YdFebpyL8Vqa* z9b`E7WRvFs;^)`C$Qv0P?f+mY{3%W~_pBFJhRwg<2~Y@tF()v`*gBW-&w=2;{!br) zFVw$wu;t6}LV{jIK~{y7j`KJ@Diyv!rVg7SyKoFXJw^LwOC0l<2UUdr-4q8gx_wLj zE)}9f98O$xX9aXjxzFd9L5x?JZyhV7dp!oyyfh83S|2l!Y^WKLjl#k!v~X*{)-GN$ z8j;~2XO!oiBED!eIPO#1 zP2^z6U9zhZ_j=F?wen(1CxJCpSa+A_3tVfr}Z32Mbo6!NC<3m>hMs4Q7l~GU%bq?cq%w<>}J5Eh@foj-D-`WOa`5h9I6nCK^9|K^6G;PPXINV4hjS=7z!5f^GbiGb7Z7o!Q-|T!g-bV8 zCtFSfC9vpxzQ3ZXTA-d`@eKNbVZN(heBV$hBpu6fk}DiRzc{SpF^Cq8kGGS5X*>SN zX~o-mjGj;-%7&Jv$f{~z9BC-G-(X#JK6HICWLjY;F7V5a9svlMSw}$n_uqmbG{Fz; z3K@xb{gf&qZnMRd`&RSpc5PY9$Az7`46YX{r)^vzOeT;0a^Tq@4G^J52}ojl5lfyf zn-9u*SUNDa!4@xgWc&I~|EMy09@T7&+y_GX3XXh@6*f}9iD+2Y?n!&VwJ zV#5BSrTBB(`)h(l#X4aJMuieugH$r+EUOdfXYQupQ?o|DHXqr}&CIMjCUR*_Plrqb z>JioZ86T6~mVt&CBXc$qZ#;+;wPI`7w~6w9{HK57_>-qz?L-k-R?e|Tt4~#0Qh{|^ zPEKQrmtgX}gGp5m*@;^@g(E67vDmO7>%PrY;8Tm3$jvjch{t_qM^0-H9Zc(xdz9%H zxHUQF+a30j95yIAQ$@Ils76FIH@1H5aU~^gwL<$Vno>%^9ZD!Eg6G<2{UbVJFnQx? z&lF{Ym_y+6;)ffyn+h#{Z^e1pf{pvpZPVP72>b`epBy$=adSovl zpvQ)hIy)py6FbFvN5!`1qw@|@B2hu}f*KH9w zz`#dyoBe(~1#?n5q>J6AKP8%qZADpRcladY;jCaIW6+6}H{C0k2Yj5|RBbl37h3HFb!7zN zW935-tI5ZMXXMiwqZKAxs_ed47JF`u4T$KV`O*o>y z&C=ACapFkUYu3L-zCENcDBd_=V^094t&7niasz8QM0tMt+uHjgZkqVsTeT0A;x;il zMO_7N`;A{#>XyA`-?V~$7EP#An^POOJ3`8LEx$^}-G?VxvqL#^*76IQ5yL>f*la>- zGuD=V@3fJd31IkNwDD_GKr6fYa;EAsBVaGuVg(+5=dpk1i;A!ck#G5`+e77_h9+jk z(Nvrs=&AK&p8e^<(d zDC}j|cN?Gh>uthH)aLB@Vq(8><~&Y+q`!iFyISxA9w{v}1)(!(5lLQJbOs_>|JCyo zPF-PtwN#m+vA{xeHmmC3zyDOx%KYPY)&dfta-I#4;9IZyt#?X7yssmT1PW9MPjB*wA)o3|KV67-u$Q7VFW zro8uGDS+JJ^4LMRw)gM3jQX?k)|}?5udl60M!1UFfbRzw!mXDm>vQno+Xqe;G08oe zn7UJeiwVa z(_Ut0;9h(O60by09|iq>R2liq%=&Lm^0SlvpsOP0yC&0qvz~}iV+_f5BdQ3ffuV<< za)uJx4>Y1wG;<$oxKi+`rUUkVDg6s%)V^!<&*f)(-eND)0h;G4m+G?D`Qt=AErsYL zM6d1#jrW|Th`UQ)y?PJctY&*tvKvh0{+E@TGro3Syuzy5_2E3k*!o!~*)>8hdqRc@ z_p|S05eR;HF#6u*osZdMig^_dZfbs4#H7HAFzp*JB6>6i%zJ?qFgg0XM7)-D+rYF; zA3Bg;{eQb=4&>;zYS|}?4c!lsQ#a1W&)P|-_?z>%6ql*B-jz_iXJLnE{QJFKum(Rm26)-$g0I7kHoYw?lWmK=xl8^xP&AFxewVRJRyaH|lc%~SenKcAH zKiq>XM@Mi{6rjfsxIO`Rp00iO(~ZVhAo!u?lz{m`l=SwM{BW;$$I*nzI>e!+Kn~=n zXy>U$5O~#tD?=DGJ7wCO!=Spi;0l*rcUSFvrEbe%vXG0{RWxt(>(km~l0M3#y)k9( zzyC}L*p<+ci?c2w^ka`2#+#SLU={U4Z&Yqz23QNNFS6uy#^Y1G4$U}a2RSMMf~-`aP{1vX&g`=@ znwn-;`K|X`&n1f5XTq4O@o?{Y+Whwk+nSP9-8c>F0}xaJp(zpnb{cyxG!HKV+0h^y zVil`LBYuN7T1+|bp4yhm?u)tB2S_a&(^3QHGh@-d5TH~TLhi3**UnS7qnJzR4By@O z2$p?ff}CiOYIo;Wbm&U8Hm6ZHO&$-nF8KFXup>&q`ljXPuSX%KZ)jQJu!HnO5aY1R z`C2A~ePd9IfO(S$l2Pobr3sNgIAX>fTah0?a3j1d1{M?c+~cjfp>Lp$=OnlfR$gWO z&Vq?A3BPPNE%1WnK5Ou*P;T?vgfo%cb5=cBo~0j#jX~Nl7JeY97lnP~W^o>TeH;v} ztstg$j{jfrS#-;h8w)}?%#I7%BO2cwm<#D!@Avt{uH@i}|Pwa5%N!?!bnlCX$ltG$UYD*RV z((RKD+7j{7U0nW_C!!p3eX74`xJ|s`g~jg{2bcCzb~nB-dqnPO-EZYbgLY|TmK`dD zY*ZBtK@y^qa+zIj4t+>w(mzN39jwO)z$*78c<)&svU~beGqKw72SySB4`Fzb3f`4b z7y~!)@vi%%SNAT5pdVr}o~kyVf*XA$KD^t54((Wu`n)SKK9mWXe=R70hwo~;y&-8= z>v{uU**-%lrs?G{mkjMMUxuoR3Z)1-TD05We|ti*l><2bu5t;0(A|jJ69!t)%`i&& zXoD~ddPO~$@#N6UUDnG@)@1suLmlDW(yXhD=1VCr>q|DB%Lw6`=ElaT zd~~N`S%_7Gkm&V8Kk5CzTnh9qz$9R&QM;lEMGyT3U#dZNxG7;2Z8rJRI=c~lHK=na zXHB(p;fW2Wt&+p8(FHFxl9;&O^)6}j3eKxi@w2q#9!>*BA@+dKNu}H%Qb8MItch5@ z$caD4U_Ng+;wn0>QA;zihW15<)fnz}(l+(kPybv~D!7|wT|Ldft0^H+tLv9U^`>R6 z2unpgA1*rfe}uyKu`~r~$Y7fJQJXXGi97Xbf6z0SZ1WR{r+&v%9uZcrsBlYu+a<=% zB#T@bJVhV1{hia@_+T-dmi5O=_J7nP^bZ%uCUpQ3-5J~V-fnggrYT5fAK0>CU{suj zFuZ<%2Hcu#CM*8E`*^yVsiaXfwS!7@NPsCs-J0(qYK0f{O6~>Ft%3I}m^zL^&WPjb zdFQo%$H5OtRB{jI2*a*&Qi;Z-OS0a zu8yiq*hKFueoA93#OY{h+330C>w*Lhk@DwiY24yX*hZdh9Y-Y~8WeylOH! zy&L(un0iC)yXBWYN{x8r1pknQPAE`!K%Vtw{l6<$O zhdFDBwfvf9a`>>#!*p^8vigJJ0MXBKAuw4_l=GekCvE}jiOULpR z@|hCoMS^ZN&Ww#=FqJ~nO}jOcI{9B{(QSeslyPK*{x21}8@Zoe?RGF#pLS^79Yz;O zfaTt99rU;2(zS32epx01)#W9?eW=aOXV? zzyaP4Rw;9?LyZh<`|TPpiEOIT!;6EV&q}BvgocL32!y801z%t8qe4al&bOPsXTO+N zh0xJbID#Y~Z}ncqN)=MB=U?#(=Rwi&ko`ej3LB!e9i!`TRita&{3 zSZXNg8b+}Vv#yY%^_JU+lUywIyGPx$t-}?|9fX87Zz}W(MKWTYRxHY-NK7VN^oN$T zKn@ttK#ZH{>Xzvv*{xJIG z8Vy*@$Xep61f{2@I+ds-jP?@BmoDY96q&Kzu!NZ;vI+03i9ftGuy(-TPePIp zyc75o$TK*IppXOX>K&+MU>>1a`WeOvk^0OkaMQe{e0q5_`5o+2e|w5U@6y;SOB4HN zu{*53rbeENiwnY>Z*y6{8Cr9+w~sInI<-4DgXn-nQgc!fom(Ul0Vn+Q;+~3{Sz_`H z#@n&~eMsUDbQ0t*o9WbjnQL%1{f!jaZy>7ywz=;y!Mx+FwewsOwJaK(E5@DPo(>J5 zrcTP&x1Per{m-q5`q};>F4gr@;^ef~@8;aHi0 zkuiHd`j!?z=SypGgXH{eBUZ>eH=LPim|XOyGVY^&>F(nxWq76IUZ3gPZqA{eY1(f;a5H(x6%x6DDXQ8?R4 zxGd(3asYnkFEPSwY5%t{o>2fbw(#~`>tw-=0d>C4i`qXrEilRHexvD$B`*guh@|>v ze`e@96d<-dSL$Rj>|!yDC`!|F;ay&C?c|nlm~3Kmr`{%)$^V{drZvI7mcU09e+{Xe z$k&F3hJ6Q8?;)^cZYL;pa&ofUys<>~NKEz14?wvds3R6v~!#;Rlpc-m8qZ+T}nRG5(C$2>AFzK;H5>dY_jWYUUCk z<4!gOGZE;*_fOkgdD_98zLp1l`=Zo`x*n{&7I7h6=R4j>#ljhn>WomQGS`1*(~Ior z!AWo0wmp*R4h4PS7WTWul~eEaOSSECl?_Y#H)RvAQ>On5hSW!X^o90szW+Y?ulbpG z{eaxA944Jh2kfD89(SGf58}^Yhzg!Y-7t@Xs@c`mb@~pPex|~ge;2?Lw zcDvmLBR67l?>MNFk7@_w0fb20i7GIv>NMguCVW|wX=fMhg7?yx_BOTtZmW3}<+6=W z4vr_IJSo+u2LO!)E~EmXO&mU67?eMr%`yGBg6|V1ULbgG-Ak0Wq8jy)x)pFM>p?wN z0A@=C1}N}hb}1j7$sATsdqhg4E1%s7pzsHD(uHfzBz+c{^k7dAF5N1x?IyhvFApZ^Fld{RNT24eshfpjTo z&Jx@9L?jUMtANL6OIqIC(cwlC1*JDsXYh=QKIiV~mO=+BxJ`c2`HUD-M77Jg$(RS+ zrrt88{(B7d6~;u*0gC2xS0Bty>X#Wqs2=mC0&U@GyE&+t(q{;VGg}iQG^H2h-T)C0 zX%c!TB0TXX7{Zc}%rv>@YP{#Q=uihlmENr7Io{jx+T@5f!ohJIPXvP8T2)bApEtsW zxYb>)IO(JV_0XX|7R?+?Q>x!N{}-@6dEYwk!T!@2nu!;5uLv2Ws963k)hs@SXlOxY zHO2kV@RKi*Wcy1*!6&f`E~G_mbB%Vji!kbKSHkNG_wI@d2`UYig=9GWGW|clQ!VVt zint#WNM9Ehv%$)+t)G~Fms5jJ2O+#v(*BrU^rp{q8Ev$cOXu&-<=5)Rd2jjVP~pf* z%B-GubfIZK`pWMju*&mu=Xks41N|_tW>XF|Za0Ncy~5|lPF9do!jaEIWBLnW4p6QE zLnB*ga$K5jK4ylNOC#W+vYzK_IN5bE_~Y7*xbgeksg!;aM!rkSf8L~bgsrc5n^qva zzi+X2&9~+)_KZT$y9nrSVaOuF@}ejKcUB_ACtjkdu^nM{N9+Qv811^tgAOkHpPNTM z|I4YsQA60qfOH~nvdS(yaN$)gYfRkkIqt3AyE@^fLfkRFP?`fL$@JsX?x44@FiA-u z8}W5sML{zQ@E0H+^egcbp4w+{F`B5ZTAUSIBneZtJ8KUfq|6|wxpOOA0^`{c5Cf}v zJN84xRip~U^u3voV6yW3(1#}H6E`8b}xKw25#{glLu+khVcbz%@&3`N_0|#v;6GE-v(RVw| zZ~HG_(`A&uvtwk8xGfFZqeDH}BfZ0hs=!!~yxiPkuQvKH37kJep^e5`ECKD~tJXQ* zmsSo|D=TYg%$A{Cj#=WarYd|?3rzehV)E5krr||57{rL67lNqE?PaUGpf~~sOvKiv z<|?yd74eTx{Gg8bVi~ral{Zwr^gEp1jeBwHExoIK57tKPu=Lc_RDy9uPvs``f27H~ zmZbNS3KUze%a{JZpPsp^7$pq>%!MxVdS8 zNx}5?(}Cg_5J?<*zzC37DA}rKY+~XTZ0rmeT?|}9!}{(DqOM%r+-9161~nJ{`)>s* zBB0hl@ywDqyzG4@F;Sohd-T^YW-SekY1@Lab<`yB>+92mhykFq9}h2$NkG2}CP=o22fjelR}6=tK~4h@!b_M?JJwdEa}?Nc`G4w=qb> z`KJAVEA{)^OCk+KdAFq;FzM_u0!ub}IIOO@43PbMjbFchb8s< z0CYe`0-=jup2d3-ZL7e~clgi?dUi8upq&7|BSl5v076UX^HJ$%HQ_jwZpp;qs^5a3 z`GT_Voe}pan1SahJ8&&`TUr)7c>SJtYG5~X?|&Av!(Abv#hwlnCkVKJfd$Z_P(Ubz z8|d?#4;skb_h&{Gr7ouxS=kFE*M-;;BcY*#egM5e zsp32G>Uw>wRLNgr>$yAg?SS2Gob8WHn6J#;*>d-VbXut5S=;Z|rofdmNQSJxgP4)_ zO?csehk9ETm6g!%mH_AuV`G>9MyRAUF~8Z@sX}>jyZ?p<&CM5^-wL!jzpP&EHSrU$ ziHrC^1F1&Vi-wOzYmkTV6Pl!G7ch_PKJe4Ef_{b=bETy+<;{4e7z14NfXvL;{M>!f zxj^}P8G$C35D~>N5TZ>{5DQY~ceC3)=%?VCM4RnL8e~b(& zvt3YD7I2s8_uFQJ0LZ|ivN4SwaZm(9TX-`nWXFd!scLK>Ab5VdZwJLW9Ixvqd&|#< zq>oMSwO-w0M+mO_eH=}5X@p1Cr{S6V6xVrz6}R5H-I~+p7M)CuSz6!jFFtxnL9a zikQ&S1oMdsZedbbDRP2S&Ms|et!!-FW%E>_4JSf1gB2T%sq5z-_xsd8yv%Miq{7(# z$PdQ$Um*TB9?R&`x2du54}gR99UUFp?(j$eQL%G$j6~UAK!9ZZFD=|4zK#=Sm@v)! z_g@ioG_xkaSz88PD6E;l z#DD&P!4C{KTs{f)-y^|W0K;tn(`M?P3{|?-*6)BsSg$}FA@)K7352q<=G=4fP2!Ki z*FnZcMtKhy1K*&s%l)oS*Vf}C|9*UnChMKco`3C933tpH+C#+8!J$W|Eo5eBM++#A z|LB_L%)75f&L?kVAXM3l9HC@fn9+O z_ZbgQu>>J6H#aV30(kEHerw{E4|b$5p+gBhpf`pG_2oDaI_S2Jj-0!bQInq>W(gfM zHx!gw8X72AsQymZafrNctgU5!_UzezE+S2;lbU{2s(Ng#9#><*aMFR-#e@Fl7n5G= z=}&T&SWlmd8kD(l0OigPLWg;@q>uEuN!kH%S7H%qRUGW|phK}T8?#GQx7q10t|69h zanO3;J4L;8?MOS!6LBcehFfMIjX)$QO*QZ^hGfpU&pWi>G=PzA`m~!eTUL3AB_<}P zFT4Q2tqrS;Ko#s=?wxFAX7>B^)VJAZkC_(N6w$vq6aY;+4dE-O*#0!mx)mO*4e0^; z#2JNRL1jCKbX~=-44!v2}0TQyfKL5u%asY7DWC}6=Lp_^ zi#aK*++n|Cp&H2tJ@>?{6x!5FGkd{4vwl*aCRJ>AH#gm;*e|Gd6hL*J_5dv# z#g%LzN$N#@BXva&oQM7$0#c(uUtk*Rm+^Or1#Q?RnCdGr35tniW(K}=A43W`3t)GA zgHsK5-lxtnCJ#)RtPfyhaYTD~?{^Ep_H2-`w&FW4vhYH~_Hzv!Dck;9FsOv|@_`Z` zs7h#Kv8Ass4m`oN9{y2^p#ujn;Aoty1LkS}=}G+#qSs2%+sDi6C<=`lPmUN9hHG

`ZyR$DGGFBGHAlm;Y0PklxGjPX!Y<6hz614=$(WX?3SRBJX zSanZE^7E7Qe9p1pCJ~kN$wp+?&^oY>>DJ zOd-C(iBxbzHvGCva}9b*!3KBH5VQEy5)WKq1!5(VONdQ%+j@BZiL#>$&a(OQ`QvYTTGC%pncy9h zi_d(IMhEiX+j8AUkV=o?6$q;)#?!wH_V%ZP)o}QyFkTl5U#J>en6ttIvwJo5#Bn4``A|WH@%!y6 zDnieFvHzVfdb4FVV3s4WgbV9g*5`Tw$!vn=O6TM_6Zdul2x$IGRexQ~7uZijMlbdh z3GHg&$!ErrPOvxs4Qpl;gGefY=DEyq^N@hCAnq6b`o|_Fg`UmoqI1ua12#<-th0tt zBMX#!LvHZlgJAuuwcx8)vcMqu_K>f=C_YsyN2-}?)>vZzOw973doqT5pc7~5aNd81 z;^aQ-PD-}A^L&(CXY#Ot;Sn_W)acbbeVK!|4Qe*kZ1X>;qi@*&3;{#?;ik?@*Os*$ zf7C8*YipCzY2YpME9KI56%JouquB7qe*;Yp@G1sjBvruG4*ZJ_ps#OV-=|Z-`7>u& z4Q~U^%0$Mqd`9bqV@F3vRS4|(f--lnV4+KT4SoW8FK4$$9psbFkxs|Z+MpoWLHlPW z$Tna_{~o&98ajc*tt7}=vYT`{0fOk{rVcUYPX}RL#)I9@LCYScyK~lA40Qw@KSr-Mp&gv$C#l}-jlvCt%=tp-{-DBu%}G6Ld6yi2LUeKe_xDiq z9gvKo4jLeBu|bQ`1tt$JDU3>}rGK!ou_1ze$@)m#zQn0P4LA@e)~N(Ns!#!Fq8}v* zehM7f!Uyr+ptSsRec5^4`%)nUH7*42l|o?TC1YC8@5Q~?g<8-~R|)?e9mOuxb_)4& zIcspH#+RLHsPTg`$`S9eP&6o0MxV%@KR*BRiox%7Y#TqY0nWxPE)8xoqptk_LCw|G zyKgOu9DhkkvKdIS8G&>p_}gi~ywkG99r4-zoPRu>z8vwZx*4~E@uO0)&SA4XL^NW( zNbkB>z}xR+kCX#c8`9mbEe9UMvD`CYrv38sM{F5{-?N#dS%=kd_~{1U@JQiS#x9)PM3E0vEl$5ZD#xGI z+<4X+QW*JK=A@elfAt#GYK_A8UthSsTtMLoI5N8-RN^~dDJ@o@^FoQ#UI70191=yT z{4eh_o@sBK`oP_`4mssl9i3AgSjRg@pG(Acu#b~i$&$1CDwC5g;ES0&M&~a}ifTZA zKK?X?v&-N%n#JYDBWmxuNvA@!Wl>N_$?mhrGWXv-Zs=H}>^xCA`&lZZlzX}L#FaEb zP(HCmTx+HcH318rW&GQD9rQmc-rv@p`8^@~&F$PeR?@#z9(*3bB^kzclM1NH(+ul3 zedyTuk86$v8xFI*$Qvogsht;g{{n+E=gM}@8eRby)iQ z{GHR_L_^t$<7i;2I-+*$Z3WyFv1$l*`ItvZSo7;Ot;$$1U4^7oJt$Qi!^ou>W$yU= zoo#Y>wIV&Bg9C7qC*TE#GTItf=keHi8v`gRgHoDlZIGXOtOn_nhraT4T&F{bxIFFw@`cr}!tTZ)j64 zef}>VqIlOOY0ZwdhVRD3G_ZxuhdlK}mV~W!%5l<9=EmK89<>7qf@<9q74@qoEk2B| z7a{p3&wPTr-cNCT8s9K2neOXJ8fyCfq#e7e`;o*GN8Bt;?Ak@ZkL)&&xSyoPFTc4y za3=T{@N(_pey3l%+mlL^k7Igvc5&xPbm!Eb_?>IJkigUw=^xZWv)8+#7pY95Q5*L; zaycBkzg=jOUQe%abUeEB_a*D-%_h!YX;up~|CQz9e>31M=2q_6bbZImE5Hj-4O!07 ZHCn=r=SOS`WUL7IrK+TLCCC diff --git a/deps/nuklear/example/images/image5.png b/deps/nuklear/example/images/image5.png deleted file mode 100644 index 852fd70ff011df703ab768aa21dbfe31aeab617c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98475 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Ώ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�r7tee#*+q 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 Jp)@bv{y#y7xVHcR diff --git a/deps/nuklear/example/images/image9.png b/deps/nuklear/example/images/image9.png deleted file mode 100644 index 516929ea6d6c9f734452ca3c675f5f6798d744c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30759 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 diff --git a/deps/nuklear/example/skinning.c b/deps/nuklear/example/skinning.c deleted file mode 100644 index 4634b090..00000000 --- a/deps/nuklear/example/skinning.c +++ /dev/null @@ -1,825 +0,0 @@ -/* nuklear - v1.05 - public domain */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define NK_INCLUDE_FIXED_TYPES -#define NK_INCLUDE_STANDARD_IO -#define NK_INCLUDE_DEFAULT_ALLOCATOR -#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT -#define NK_INCLUDE_FONT_BAKING -#define NK_INCLUDE_DEFAULT_FONT -#define NK_IMPLEMENTATION -#include "../nuklear.h" - -#define STB_IMAGE_IMPLEMENTATION -#include "stb_image.h" - -/* macros */ -#define WINDOW_WIDTH 1200 -#define WINDOW_HEIGHT 800 - -#define MAX_VERTEX_MEMORY 512 * 1024 -#define MAX_ELEMENT_MEMORY 128 * 1024 - -#define UNUSED(a) (void)a -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) < (b) ? (b) : (a)) -#define LEN(a) (sizeof(a)/sizeof(a)[0]) - -#ifdef __APPLE__ - #define NK_SHADER_VERSION "#version 150\n" -#else - #define NK_SHADER_VERSION "#version 300 es\n" -#endif - -struct media { - GLint skin; - struct nk_image menu; - struct nk_image check; - struct nk_image check_cursor; - struct nk_image option; - struct nk_image option_cursor; - struct nk_image header; - struct nk_image window; - struct nk_image scrollbar_inc_button; - struct nk_image scrollbar_inc_button_hover; - struct nk_image scrollbar_dec_button; - struct nk_image scrollbar_dec_button_hover; - struct nk_image button; - struct nk_image button_hover; - struct nk_image button_active; - struct nk_image tab_minimize; - struct nk_image tab_maximize; - struct nk_image slider; - struct nk_image slider_hover; - struct nk_image slider_active; -}; - - -/* =============================================================== - * - * DEVICE - * - * ===============================================================*/ -struct nk_glfw_vertex { - float position[2]; - float uv[2]; - nk_byte col[4]; -}; - -struct device { - struct nk_buffer cmds; - struct nk_draw_null_texture null; - GLuint vbo, vao, ebo; - GLuint prog; - GLuint vert_shdr; - GLuint frag_shdr; - GLint attrib_pos; - GLint attrib_uv; - GLint attrib_col; - GLint uniform_tex; - GLint uniform_proj; - GLuint font_tex; -}; - -static void -die(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fputs("\n", stderr); - exit(EXIT_FAILURE); -} - -static GLuint -image_load(const char *filename) -{ - int x,y,n; - GLuint tex; - unsigned char *data = stbi_load(filename, &x, &y, &n, 0); - if (!data) die("failed to load image: %s", filename); - - glGenTextures(1, &tex); - glBindTexture(GL_TEXTURE_2D, tex); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - glGenerateMipmap(GL_TEXTURE_2D); - stbi_image_free(data); - return tex; -} - -static void -device_init(struct device *dev) -{ - GLint status; - static const GLchar *vertex_shader = - NK_SHADER_VERSION - "uniform mat4 ProjMtx;\n" - "in vec2 Position;\n" - "in vec2 TexCoord;\n" - "in vec4 Color;\n" - "out vec2 Frag_UV;\n" - "out vec4 Frag_Color;\n" - "void main() {\n" - " Frag_UV = TexCoord;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy, 0, 1);\n" - "}\n"; - static const GLchar *fragment_shader = - NK_SHADER_VERSION - "precision mediump float;\n" - "uniform sampler2D Texture;\n" - "in vec2 Frag_UV;\n" - "in vec4 Frag_Color;\n" - "out vec4 Out_Color;\n" - "void main(){\n" - " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" - "}\n"; - - nk_buffer_init_default(&dev->cmds); - dev->prog = glCreateProgram(); - dev->vert_shdr = glCreateShader(GL_VERTEX_SHADER); - dev->frag_shdr = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(dev->vert_shdr, 1, &vertex_shader, 0); - glShaderSource(dev->frag_shdr, 1, &fragment_shader, 0); - glCompileShader(dev->vert_shdr); - glCompileShader(dev->frag_shdr); - glGetShaderiv(dev->vert_shdr, GL_COMPILE_STATUS, &status); - assert(status == GL_TRUE); - glGetShaderiv(dev->frag_shdr, GL_COMPILE_STATUS, &status); - assert(status == GL_TRUE); - glAttachShader(dev->prog, dev->vert_shdr); - glAttachShader(dev->prog, dev->frag_shdr); - glLinkProgram(dev->prog); - glGetProgramiv(dev->prog, GL_LINK_STATUS, &status); - assert(status == GL_TRUE); - - dev->uniform_tex = glGetUniformLocation(dev->prog, "Texture"); - dev->uniform_proj = glGetUniformLocation(dev->prog, "ProjMtx"); - dev->attrib_pos = glGetAttribLocation(dev->prog, "Position"); - dev->attrib_uv = glGetAttribLocation(dev->prog, "TexCoord"); - dev->attrib_col = glGetAttribLocation(dev->prog, "Color"); - - { - /* buffer setup */ - GLsizei vs = sizeof(struct nk_glfw_vertex); - size_t vp = offsetof(struct nk_glfw_vertex, position); - size_t vt = offsetof(struct nk_glfw_vertex, uv); - size_t vc = offsetof(struct nk_glfw_vertex, col); - - glGenBuffers(1, &dev->vbo); - glGenBuffers(1, &dev->ebo); - glGenVertexArrays(1, &dev->vao); - - glBindVertexArray(dev->vao); - glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); - - glEnableVertexAttribArray((GLuint)dev->attrib_pos); - glEnableVertexAttribArray((GLuint)dev->attrib_uv); - glEnableVertexAttribArray((GLuint)dev->attrib_col); - - glVertexAttribPointer((GLuint)dev->attrib_pos, 2, GL_FLOAT, GL_FALSE, vs, (void*)vp); - glVertexAttribPointer((GLuint)dev->attrib_uv, 2, GL_FLOAT, GL_FALSE, vs, (void*)vt); - glVertexAttribPointer((GLuint)dev->attrib_col, 4, GL_UNSIGNED_BYTE, GL_TRUE, vs, (void*)vc); - } - - glBindTexture(GL_TEXTURE_2D, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindVertexArray(0); -} - -static void -device_upload_atlas(struct device *dev, const void *image, int width, int height) -{ - glGenTextures(1, &dev->font_tex); - glBindTexture(GL_TEXTURE_2D, dev->font_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, image); -} - -static void -device_shutdown(struct device *dev) -{ - glDetachShader(dev->prog, dev->vert_shdr); - glDetachShader(dev->prog, dev->frag_shdr); - glDeleteShader(dev->vert_shdr); - glDeleteShader(dev->frag_shdr); - glDeleteProgram(dev->prog); - glDeleteTextures(1, &dev->font_tex); - glDeleteBuffers(1, &dev->vbo); - glDeleteBuffers(1, &dev->ebo); - nk_buffer_free(&dev->cmds); -} - -static void -device_draw(struct device *dev, struct nk_context *ctx, int width, int height, - struct nk_vec2 scale, enum nk_anti_aliasing AA) -{ - GLfloat ortho[4][4] = { - {2.0f, 0.0f, 0.0f, 0.0f}, - {0.0f,-2.0f, 0.0f, 0.0f}, - {0.0f, 0.0f,-1.0f, 0.0f}, - {-1.0f,1.0f, 0.0f, 1.0f}, - }; - ortho[0][0] /= (GLfloat)width; - ortho[1][1] /= (GLfloat)height; - - /* setup global state */ - glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glActiveTexture(GL_TEXTURE0); - - /* setup program */ - glUseProgram(dev->prog); - glUniform1i(dev->uniform_tex, 0); - glUniformMatrix4fv(dev->uniform_proj, 1, GL_FALSE, &ortho[0][0]); - { - /* convert from command queue into draw list and draw to screen */ - const struct nk_draw_command *cmd; - void *vertices, *elements; - const nk_draw_index *offset = NULL; - - /* allocate vertex and element buffer */ - glBindVertexArray(dev->vao); - glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); - - glBufferData(GL_ARRAY_BUFFER, MAX_VERTEX_MEMORY, NULL, GL_STREAM_DRAW); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_ELEMENT_MEMORY, NULL, GL_STREAM_DRAW); - - /* load draw vertices & elements directly into vertex + element buffer */ - vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - elements = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); - { - /* fill convert configuration */ - struct nk_convert_config config; - static const struct nk_draw_vertex_layout_element vertex_layout[] = { - {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, position)}, - {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, uv)}, - {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_glfw_vertex, col)}, - {NK_VERTEX_LAYOUT_END} - }; - NK_MEMSET(&config, 0, sizeof(config)); - config.vertex_layout = vertex_layout; - config.vertex_size = sizeof(struct nk_glfw_vertex); - config.vertex_alignment = NK_ALIGNOF(struct nk_glfw_vertex); - config.null = dev->null; - config.circle_segment_count = 22; - config.curve_segment_count = 22; - config.arc_segment_count = 22; - config.global_alpha = 1.0f; - config.shape_AA = AA; - config.line_AA = AA; - - /* setup buffers to load vertices and elements */ - {struct nk_buffer vbuf, ebuf; - nk_buffer_init_fixed(&vbuf, vertices, MAX_VERTEX_MEMORY); - nk_buffer_init_fixed(&ebuf, elements, MAX_ELEMENT_MEMORY); - nk_convert(ctx, &dev->cmds, &vbuf, &ebuf, &config);} - } - glUnmapBuffer(GL_ARRAY_BUFFER); - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - - /* iterate over and execute each draw command */ - nk_draw_foreach(cmd, ctx, &dev->cmds) - { - if (!cmd->elem_count) continue; - glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id); - glScissor( - (GLint)(cmd->clip_rect.x * scale.x), - (GLint)((height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * scale.y), - (GLint)(cmd->clip_rect.w * scale.x), - (GLint)(cmd->clip_rect.h * scale.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset); - offset += cmd->elem_count; - } - nk_clear(ctx); - } - - /* default OpenGL state */ - glUseProgram(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindVertexArray(0); - glDisable(GL_BLEND); - glDisable(GL_SCISSOR_TEST); -} - -/* glfw callbacks (I don't know if there is a easier way to access text and scroll )*/ -static void error_callback(int e, const char *d){printf("Error %d: %s\n", e, d);} -static void text_input(GLFWwindow *win, unsigned int codepoint) -{nk_input_unicode((struct nk_context*)glfwGetWindowUserPointer(win), codepoint);} -static void scroll_input(GLFWwindow *win, double _, double yoff) -{UNUSED(_);nk_input_scroll((struct nk_context*)glfwGetWindowUserPointer(win), (float)yoff);} - -int main(int argc, char *argv[]) -{ - /* Platform */ - static GLFWwindow *win; - int width = 0, height = 0; - int display_width=0, display_height=0; - - /* GUI */ - struct device device; - struct nk_font_atlas atlas; - struct media media; - struct nk_context ctx; - struct nk_font *font; - - /* GLFW */ - glfwSetErrorCallback(error_callback); - if (!glfwInit()) { - fprintf(stdout, "[GFLW] failed to init!\n"); - exit(1); - } - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); -#ifdef __APPLE__ - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); -#endif - win = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Demo", NULL, NULL); - glfwMakeContextCurrent(win); - glfwSetWindowUserPointer(win, &ctx); - glfwSetCharCallback(win, text_input); - glfwSetScrollCallback(win, scroll_input); - glfwGetWindowSize(win, &width, &height); - glfwGetFramebufferSize(win, &display_width, &display_height); - - /* OpenGL */ - glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); - glewExperimental = 1; - if (glewInit() != GLEW_OK) { - fprintf(stderr, "Failed to setup GLEW\n"); - exit(1); - } - - /* GUI */ - {device_init(&device); - {const void *image; int w, h; - const char *font_path = (argc > 1) ? argv[1]: 0; - nk_font_atlas_init_default(&atlas); - nk_font_atlas_begin(&atlas); - if (font_path) font = nk_font_atlas_add_from_file(&atlas, font_path, 13.0f, NULL); - else font = nk_font_atlas_add_default(&atlas, 13.0f, NULL); - image = nk_font_atlas_bake(&atlas, &w, &h, NK_FONT_ATLAS_RGBA32); - device_upload_atlas(&device, image, w, h); - nk_font_atlas_end(&atlas, nk_handle_id((int)device.font_tex), &device.null);} - nk_init_default(&ctx, &font->handle);} - - { /* skin */ - glEnable(GL_TEXTURE_2D); - media.skin = image_load("../skins/gwen.png"); - media.check = nk_subimage_id(media.skin, 512,512, nk_rect(464,32,15,15)); - media.check_cursor = nk_subimage_id(media.skin, 512,512, nk_rect(450,34,11,11)); - media.option = nk_subimage_id(media.skin, 512,512, nk_rect(464,64,15,15)); - media.option_cursor = nk_subimage_id(media.skin, 512,512, nk_rect(451,67,9,9)); - media.header = nk_subimage_id(media.skin, 512,512, nk_rect(128,0,127,24)); - media.window = nk_subimage_id(media.skin, 512,512, nk_rect(128,23,127,104)); - media.scrollbar_inc_button = nk_subimage_id(media.skin, 512,512, nk_rect(464,256,15,15)); - media.scrollbar_inc_button_hover = nk_subimage_id(media.skin, 512,512, nk_rect(464,320,15,15)); - media.scrollbar_dec_button = nk_subimage_id(media.skin, 512,512, nk_rect(464,224,15,15)); - media.scrollbar_dec_button_hover = nk_subimage_id(media.skin, 512,512, nk_rect(464,288,15,15)); - media.button = nk_subimage_id(media.skin, 512,512, nk_rect(384,336,127,31)); - media.button_hover = nk_subimage_id(media.skin, 512,512, nk_rect(384,368,127,31)); - media.button_active = nk_subimage_id(media.skin, 512,512, nk_rect(384,400,127,31)); - media.tab_minimize = nk_subimage_id(media.skin, 512,512, nk_rect(451, 99, 9, 9)); - media.tab_maximize = nk_subimage_id(media.skin, 512,512, nk_rect(467,99,9,9)); - media.slider = nk_subimage_id(media.skin, 512,512, nk_rect(418,33,11,14)); - media.slider_hover = nk_subimage_id(media.skin, 512,512, nk_rect(418,49,11,14)); - media.slider_active = nk_subimage_id(media.skin, 512,512, nk_rect(418,64,11,14)); - - /* window */ - ctx.style.window.background = nk_rgb(204,204,204); - ctx.style.window.fixed_background = nk_style_item_image(media.window); - ctx.style.window.border_color = nk_rgb(67,67,67); - ctx.style.window.combo_border_color = nk_rgb(67,67,67); - ctx.style.window.contextual_border_color = nk_rgb(67,67,67); - ctx.style.window.menu_border_color = nk_rgb(67,67,67); - ctx.style.window.group_border_color = nk_rgb(67,67,67); - ctx.style.window.tooltip_border_color = nk_rgb(67,67,67); - ctx.style.window.scrollbar_size = nk_vec2(16,16); - ctx.style.window.border_color = nk_rgba(0,0,0,0); - ctx.style.window.padding = nk_vec2(8,4); - ctx.style.window.border = 3; - - /* window header */ - ctx.style.window.header; - ctx.style.window.header.normal = nk_style_item_image(media.header); - ctx.style.window.header.hover = nk_style_item_image(media.header); - ctx.style.window.header.active = nk_style_item_image(media.header); - ctx.style.window.header.label_normal = nk_rgb(95,95,95); - ctx.style.window.header.label_hover = nk_rgb(95,95,95); - ctx.style.window.header.label_active = nk_rgb(95,95,95); - - /* scrollbar */ - ctx.style.scrollv.normal = nk_style_item_color(nk_rgb(184,184,184)); - ctx.style.scrollv.hover = nk_style_item_color(nk_rgb(184,184,184)); - ctx.style.scrollv.active = nk_style_item_color(nk_rgb(184,184,184)); - ctx.style.scrollv.cursor_normal = nk_style_item_color(nk_rgb(220,220,220)); - ctx.style.scrollv.cursor_hover = nk_style_item_color(nk_rgb(235,235,235)); - ctx.style.scrollv.cursor_active = nk_style_item_color(nk_rgb(99,202,255)); - ctx.style.scrollv.dec_symbol = NK_SYMBOL_NONE; - ctx.style.scrollv.inc_symbol = NK_SYMBOL_NONE; - ctx.style.scrollv.show_buttons = nk_true; - ctx.style.scrollv.border_color = nk_rgb(81,81,81); - ctx.style.scrollv.cursor_border_color = nk_rgb(81,81,81); - ctx.style.scrollv.border = 1; - ctx.style.scrollv.rounding = 0; - ctx.style.scrollv.border_cursor = 1; - ctx.style.scrollv.rounding_cursor = 2; - - /* scrollbar buttons */ - ctx.style.scrollv.inc_button.normal = nk_style_item_image(media.scrollbar_inc_button); - ctx.style.scrollv.inc_button.hover = nk_style_item_image(media.scrollbar_inc_button_hover); - ctx.style.scrollv.inc_button.active = nk_style_item_image(media.scrollbar_inc_button_hover); - ctx.style.scrollv.inc_button.border_color = nk_rgba(0,0,0,0); - ctx.style.scrollv.inc_button.text_background = nk_rgba(0,0,0,0); - ctx.style.scrollv.inc_button.text_normal = nk_rgba(0,0,0,0); - ctx.style.scrollv.inc_button.text_hover = nk_rgba(0,0,0,0); - ctx.style.scrollv.inc_button.text_active = nk_rgba(0,0,0,0); - ctx.style.scrollv.inc_button.border = 0.0f; - - ctx.style.scrollv.dec_button.normal = nk_style_item_image(media.scrollbar_dec_button); - ctx.style.scrollv.dec_button.hover = nk_style_item_image(media.scrollbar_dec_button_hover); - ctx.style.scrollv.dec_button.active = nk_style_item_image(media.scrollbar_dec_button_hover); - ctx.style.scrollv.dec_button.border_color = nk_rgba(0,0,0,0); - ctx.style.scrollv.dec_button.text_background = nk_rgba(0,0,0,0); - ctx.style.scrollv.dec_button.text_normal = nk_rgba(0,0,0,0); - ctx.style.scrollv.dec_button.text_hover = nk_rgba(0,0,0,0); - ctx.style.scrollv.dec_button.text_active = nk_rgba(0,0,0,0); - ctx.style.scrollv.dec_button.border = 0.0f; - - /* checkbox toggle */ - {struct nk_style_toggle *toggle; - toggle = &ctx.style.checkbox; - toggle->normal = nk_style_item_image(media.check); - toggle->hover = nk_style_item_image(media.check); - toggle->active = nk_style_item_image(media.check); - toggle->cursor_normal = nk_style_item_image(media.check_cursor); - toggle->cursor_hover = nk_style_item_image(media.check_cursor); - toggle->text_normal = nk_rgb(95,95,95); - toggle->text_hover = nk_rgb(95,95,95); - toggle->text_active = nk_rgb(95,95,95);} - - /* option toggle */ - {struct nk_style_toggle *toggle; - toggle = &ctx.style.option; - toggle->normal = nk_style_item_image(media.option); - toggle->hover = nk_style_item_image(media.option); - toggle->active = nk_style_item_image(media.option); - toggle->cursor_normal = nk_style_item_image(media.option_cursor); - toggle->cursor_hover = nk_style_item_image(media.option_cursor); - toggle->text_normal = nk_rgb(95,95,95); - toggle->text_hover = nk_rgb(95,95,95); - toggle->text_active = nk_rgb(95,95,95);} - - /* default button */ - ctx.style.button.normal = nk_style_item_image(media.button); - ctx.style.button.hover = nk_style_item_image(media.button_hover); - ctx.style.button.active = nk_style_item_image(media.button_active); - ctx.style.button.border_color = nk_rgba(0,0,0,0); - ctx.style.button.text_background = nk_rgba(0,0,0,0); - ctx.style.button.text_normal = nk_rgb(95,95,95); - ctx.style.button.text_hover = nk_rgb(95,95,95); - ctx.style.button.text_active = nk_rgb(95,95,95); - - /* default text */ - ctx.style.text.color = nk_rgb(95,95,95); - - /* contextual button */ - ctx.style.contextual_button.normal = nk_style_item_color(nk_rgb(206,206,206)); - ctx.style.contextual_button.hover = nk_style_item_color(nk_rgb(229,229,229)); - ctx.style.contextual_button.active = nk_style_item_color(nk_rgb(99,202,255)); - ctx.style.contextual_button.border_color = nk_rgba(0,0,0,0); - ctx.style.contextual_button.text_background = nk_rgba(0,0,0,0); - ctx.style.contextual_button.text_normal = nk_rgb(95,95,95); - ctx.style.contextual_button.text_hover = nk_rgb(95,95,95); - ctx.style.contextual_button.text_active = nk_rgb(95,95,95); - - /* menu button */ - ctx.style.menu_button.normal = nk_style_item_color(nk_rgb(206,206,206)); - ctx.style.menu_button.hover = nk_style_item_color(nk_rgb(229,229,229)); - ctx.style.menu_button.active = nk_style_item_color(nk_rgb(99,202,255)); - ctx.style.menu_button.border_color = nk_rgba(0,0,0,0); - ctx.style.menu_button.text_background = nk_rgba(0,0,0,0); - ctx.style.menu_button.text_normal = nk_rgb(95,95,95); - ctx.style.menu_button.text_hover = nk_rgb(95,95,95); - ctx.style.menu_button.text_active = nk_rgb(95,95,95); - - /* tree */ - ctx.style.tab.text = nk_rgb(95,95,95); - ctx.style.tab.tab_minimize_button.normal = nk_style_item_image(media.tab_minimize); - ctx.style.tab.tab_minimize_button.hover = nk_style_item_image(media.tab_minimize); - ctx.style.tab.tab_minimize_button.active = nk_style_item_image(media.tab_minimize); - ctx.style.tab.tab_minimize_button.text_background = nk_rgba(0,0,0,0); - ctx.style.tab.tab_minimize_button.text_normal = nk_rgba(0,0,0,0); - ctx.style.tab.tab_minimize_button.text_hover = nk_rgba(0,0,0,0); - ctx.style.tab.tab_minimize_button.text_active = nk_rgba(0,0,0,0); - - ctx.style.tab.tab_maximize_button.normal = nk_style_item_image(media.tab_maximize); - ctx.style.tab.tab_maximize_button.hover = nk_style_item_image(media.tab_maximize); - ctx.style.tab.tab_maximize_button.active = nk_style_item_image(media.tab_maximize); - ctx.style.tab.tab_maximize_button.text_background = nk_rgba(0,0,0,0); - ctx.style.tab.tab_maximize_button.text_normal = nk_rgba(0,0,0,0); - ctx.style.tab.tab_maximize_button.text_hover = nk_rgba(0,0,0,0); - ctx.style.tab.tab_maximize_button.text_active = nk_rgba(0,0,0,0); - - ctx.style.tab.node_minimize_button.normal = nk_style_item_image(media.tab_minimize); - ctx.style.tab.node_minimize_button.hover = nk_style_item_image(media.tab_minimize); - ctx.style.tab.node_minimize_button.active = nk_style_item_image(media.tab_minimize); - ctx.style.tab.node_minimize_button.text_background = nk_rgba(0,0,0,0); - ctx.style.tab.node_minimize_button.text_normal = nk_rgba(0,0,0,0); - ctx.style.tab.node_minimize_button.text_hover = nk_rgba(0,0,0,0); - ctx.style.tab.node_minimize_button.text_active = nk_rgba(0,0,0,0); - - ctx.style.tab.node_maximize_button.normal = nk_style_item_image(media.tab_maximize); - ctx.style.tab.node_maximize_button.hover = nk_style_item_image(media.tab_maximize); - ctx.style.tab.node_maximize_button.active = nk_style_item_image(media.tab_maximize); - ctx.style.tab.node_maximize_button.text_background = nk_rgba(0,0,0,0); - ctx.style.tab.node_maximize_button.text_normal = nk_rgba(0,0,0,0); - ctx.style.tab.node_maximize_button.text_hover = nk_rgba(0,0,0,0); - ctx.style.tab.node_maximize_button.text_active = nk_rgba(0,0,0,0); - - /* selectable */ - ctx.style.selectable.normal = nk_style_item_color(nk_rgb(206,206,206)); - ctx.style.selectable.hover = nk_style_item_color(nk_rgb(206,206,206)); - ctx.style.selectable.pressed = nk_style_item_color(nk_rgb(206,206,206)); - ctx.style.selectable.normal_active = nk_style_item_color(nk_rgb(185,205,248)); - ctx.style.selectable.hover_active = nk_style_item_color(nk_rgb(185,205,248)); - ctx.style.selectable.pressed_active = nk_style_item_color(nk_rgb(185,205,248)); - ctx.style.selectable.text_normal = nk_rgb(95,95,95); - ctx.style.selectable.text_hover = nk_rgb(95,95,95); - ctx.style.selectable.text_pressed = nk_rgb(95,95,95); - ctx.style.selectable.text_normal_active = nk_rgb(95,95,95); - ctx.style.selectable.text_hover_active = nk_rgb(95,95,95); - ctx.style.selectable.text_pressed_active = nk_rgb(95,95,95); - - /* slider */ - ctx.style.slider.normal = nk_style_item_hide(); - ctx.style.slider.hover = nk_style_item_hide(); - ctx.style.slider.active = nk_style_item_hide(); - ctx.style.slider.bar_normal = nk_rgb(156,156,156); - ctx.style.slider.bar_hover = nk_rgb(156,156,156); - ctx.style.slider.bar_active = nk_rgb(156,156,156); - ctx.style.slider.bar_filled = nk_rgb(156,156,156); - ctx.style.slider.cursor_normal = nk_style_item_image(media.slider); - ctx.style.slider.cursor_hover = nk_style_item_image(media.slider_hover); - ctx.style.slider.cursor_active = nk_style_item_image(media.slider_active); - ctx.style.slider.cursor_size = nk_vec2(16.5f,21); - ctx.style.slider.bar_height = 1; - - /* progressbar */ - ctx.style.progress.normal = nk_style_item_color(nk_rgb(231,231,231)); - ctx.style.progress.hover = nk_style_item_color(nk_rgb(231,231,231)); - ctx.style.progress.active = nk_style_item_color(nk_rgb(231,231,231)); - ctx.style.progress.cursor_normal = nk_style_item_color(nk_rgb(63,242,93)); - ctx.style.progress.cursor_hover = nk_style_item_color(nk_rgb(63,242,93)); - ctx.style.progress.cursor_active = nk_style_item_color(nk_rgb(63,242,93)); - ctx.style.progress.border_color = nk_rgb(114,116,115); - ctx.style.progress.padding = nk_vec2(0,0); - ctx.style.progress.border = 2; - ctx.style.progress.rounding = 1; - - /* combo */ - ctx.style.combo.normal = nk_style_item_color(nk_rgb(216,216,216)); - ctx.style.combo.hover = nk_style_item_color(nk_rgb(216,216,216)); - ctx.style.combo.active = nk_style_item_color(nk_rgb(216,216,216)); - ctx.style.combo.border_color = nk_rgb(95,95,95); - ctx.style.combo.label_normal = nk_rgb(95,95,95); - ctx.style.combo.label_hover = nk_rgb(95,95,95); - ctx.style.combo.label_active = nk_rgb(95,95,95); - ctx.style.combo.border = 1; - ctx.style.combo.rounding = 1; - - /* combo button */ - ctx.style.combo.button.normal = nk_style_item_color(nk_rgb(216,216,216)); - ctx.style.combo.button.hover = nk_style_item_color(nk_rgb(216,216,216)); - ctx.style.combo.button.active = nk_style_item_color(nk_rgb(216,216,216)); - ctx.style.combo.button.text_background = nk_rgb(216,216,216); - ctx.style.combo.button.text_normal = nk_rgb(95,95,95); - ctx.style.combo.button.text_hover = nk_rgb(95,95,95); - ctx.style.combo.button.text_active = nk_rgb(95,95,95); - - /* property */ - ctx.style.property.normal = nk_style_item_color(nk_rgb(216,216,216)); - ctx.style.property.hover = nk_style_item_color(nk_rgb(216,216,216)); - ctx.style.property.active = nk_style_item_color(nk_rgb(216,216,216)); - ctx.style.property.border_color = nk_rgb(81,81,81); - ctx.style.property.label_normal = nk_rgb(95,95,95); - ctx.style.property.label_hover = nk_rgb(95,95,95); - ctx.style.property.label_active = nk_rgb(95,95,95); - ctx.style.property.sym_left = NK_SYMBOL_TRIANGLE_LEFT; - ctx.style.property.sym_right = NK_SYMBOL_TRIANGLE_RIGHT; - ctx.style.property.rounding = 10; - ctx.style.property.border = 1; - - /* edit */ - ctx.style.edit.normal = nk_style_item_color(nk_rgb(240,240,240)); - ctx.style.edit.hover = nk_style_item_color(nk_rgb(240,240,240)); - ctx.style.edit.active = nk_style_item_color(nk_rgb(240,240,240)); - ctx.style.edit.border_color = nk_rgb(62,62,62); - ctx.style.edit.cursor_normal = nk_rgb(99,202,255); - ctx.style.edit.cursor_hover = nk_rgb(99,202,255); - ctx.style.edit.cursor_text_normal = nk_rgb(95,95,95); - ctx.style.edit.cursor_text_hover = nk_rgb(95,95,95); - ctx.style.edit.text_normal = nk_rgb(95,95,95); - ctx.style.edit.text_hover = nk_rgb(95,95,95); - ctx.style.edit.text_active = nk_rgb(95,95,95); - ctx.style.edit.selected_normal = nk_rgb(99,202,255); - ctx.style.edit.selected_hover = nk_rgb(99,202,255); - ctx.style.edit.selected_text_normal = nk_rgb(95,95,95); - ctx.style.edit.selected_text_hover = nk_rgb(95,95,95); - ctx.style.edit.border = 1; - ctx.style.edit.rounding = 2; - - /* property buttons */ - ctx.style.property.dec_button.normal = nk_style_item_color(nk_rgb(216,216,216)); - ctx.style.property.dec_button.hover = nk_style_item_color(nk_rgb(216,216,216)); - ctx.style.property.dec_button.active = nk_style_item_color(nk_rgb(216,216,216)); - ctx.style.property.dec_button.text_background = nk_rgba(0,0,0,0); - ctx.style.property.dec_button.text_normal = nk_rgb(95,95,95); - ctx.style.property.dec_button.text_hover = nk_rgb(95,95,95); - ctx.style.property.dec_button.text_active = nk_rgb(95,95,95); - ctx.style.property.inc_button = ctx.style.property.dec_button; - - /* property edit */ - ctx.style.property.edit.normal = nk_style_item_color(nk_rgb(216,216,216)); - ctx.style.property.edit.hover = nk_style_item_color(nk_rgb(216,216,216)); - ctx.style.property.edit.active = nk_style_item_color(nk_rgb(216,216,216)); - ctx.style.property.edit.border_color = nk_rgba(0,0,0,0); - ctx.style.property.edit.cursor_normal = nk_rgb(95,95,95); - ctx.style.property.edit.cursor_hover = nk_rgb(95,95,95); - ctx.style.property.edit.cursor_text_normal = nk_rgb(216,216,216); - ctx.style.property.edit.cursor_text_hover = nk_rgb(216,216,216); - ctx.style.property.edit.text_normal = nk_rgb(95,95,95); - ctx.style.property.edit.text_hover = nk_rgb(95,95,95); - ctx.style.property.edit.text_active = nk_rgb(95,95,95); - ctx.style.property.edit.selected_normal = nk_rgb(95,95,95); - ctx.style.property.edit.selected_hover = nk_rgb(95,95,95); - ctx.style.property.edit.selected_text_normal = nk_rgb(216,216,216); - ctx.style.property.edit.selected_text_hover = nk_rgb(216,216,216); - - /* chart */ - ctx.style.chart.background = nk_style_item_color(nk_rgb(216,216,216)); - ctx.style.chart.border_color = nk_rgb(81,81,81); - ctx.style.chart.color = nk_rgb(95,95,95); - ctx.style.chart.selected_color = nk_rgb(255,0,0); - ctx.style.chart.border = 1; - } - - while (!glfwWindowShouldClose(win)) - { - /* High DPI displays */ - struct nk_vec2 scale; - glfwGetWindowSize(win, &width, &height); - glfwGetFramebufferSize(win, &display_width, &display_height); - scale.x = (float)display_width/(float)width; - scale.y = (float)display_height/(float)height; - - /* Input */ - {double x, y; - nk_input_begin(&ctx); - glfwPollEvents(); - nk_input_key(&ctx, NK_KEY_DEL, glfwGetKey(win, GLFW_KEY_DELETE) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_ENTER, glfwGetKey(win, GLFW_KEY_ENTER) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_TAB, glfwGetKey(win, GLFW_KEY_TAB) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_BACKSPACE, glfwGetKey(win, GLFW_KEY_BACKSPACE) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_UP, glfwGetKey(win, GLFW_KEY_UP) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_DOWN, glfwGetKey(win, GLFW_KEY_DOWN) == GLFW_PRESS); - if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS || - glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS) { - nk_input_key(&ctx, NK_KEY_COPY, glfwGetKey(win, GLFW_KEY_C) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_PASTE, glfwGetKey(win, GLFW_KEY_P) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_X) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_E) == GLFW_PRESS); - nk_input_key(&ctx, NK_KEY_SHIFT, 1); - } else { - nk_input_key(&ctx, NK_KEY_COPY, 0); - nk_input_key(&ctx, NK_KEY_PASTE, 0); - nk_input_key(&ctx, NK_KEY_CUT, 0); - nk_input_key(&ctx, NK_KEY_SHIFT, 0); - } - glfwGetCursorPos(win, &x, &y); - nk_input_motion(&ctx, (int)x, (int)y); - nk_input_button(&ctx, NK_BUTTON_LEFT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS); - nk_input_button(&ctx, NK_BUTTON_MIDDLE, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS); - nk_input_button(&ctx, NK_BUTTON_RIGHT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS); - nk_input_end(&ctx);} - - /* GUI */ - {struct nk_panel layout, tab; - if (nk_begin(&ctx, "Demo", nk_rect(50, 50, 300, 400), - NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_TITLE)) - { - int i; - float id; - static int slider = 10; - static int field_len; - static nk_size prog_value = 60; - static int current_weapon = 0; - static char field_buffer[64]; - static float pos; - static const char *weapons[] = {"Fist","Pistol","Shotgun","Plasma","BFG"}; - const float step = (2*3.141592654f) / 32; - - nk_layout_row_static(&ctx, 30, 120, 1); - if (nk_button_label(&ctx, "button")) - fprintf(stdout, "button pressed\n"); - - nk_layout_row_dynamic(&ctx, 20, 1); - nk_label(&ctx, "Label", NK_TEXT_LEFT); - nk_layout_row_dynamic(&ctx, 30, 2); - nk_check_label(&ctx, "inactive", 0); - nk_check_label(&ctx, "active", 1); - nk_option_label(&ctx, "active", 1); - nk_option_label(&ctx, "inactive", 0); - - nk_layout_row_dynamic(&ctx, 30, 1); - nk_slider_int(&ctx, 0, &slider, 16, 1); - nk_layout_row_dynamic(&ctx, 20, 1); - nk_progress(&ctx, &prog_value, 100, NK_MODIFIABLE); - - nk_layout_row_dynamic(&ctx, 25, 1); - nk_edit_string(&ctx, NK_EDIT_FIELD, field_buffer, &field_len, 64, nk_filter_default); - nk_property_float(&ctx, "#X:", -1024.0f, &pos, 1024.0f, 1, 1); - current_weapon = nk_combo(&ctx, weapons, LEN(weapons), current_weapon, 25, nk_vec2(nk_widget_width(&ctx),200)); - - nk_layout_row_dynamic(&ctx, 100, 1); - if (nk_chart_begin_colored(&ctx, NK_CHART_LINES, nk_rgb(255,0,0), nk_rgb(150,0,0), 32, 0.0f, 1.0f)) { - nk_chart_add_slot_colored(&ctx, NK_CHART_LINES, nk_rgb(0,0,255), nk_rgb(0,0,150),32, -1.0f, 1.0f); - nk_chart_add_slot_colored(&ctx, NK_CHART_LINES, nk_rgb(0,255,0), nk_rgb(0,150,0), 32, -1.0f, 1.0f); - for (id = 0, i = 0; i < 32; ++i) { - nk_chart_push_slot(&ctx, (float)fabs(sin(id)), 0); - nk_chart_push_slot(&ctx, (float)cos(id), 1); - nk_chart_push_slot(&ctx, (float)sin(id), 2); - id += step; - } - } - nk_chart_end(&ctx); - - nk_layout_row_dynamic(&ctx, 250, 1); - if (nk_group_begin(&ctx, "Standard", NK_WINDOW_BORDER|NK_WINDOW_BORDER)) - { - if (nk_tree_push(&ctx, NK_TREE_NODE, "Window", NK_MAXIMIZED)) { - static int selected[8]; - if (nk_tree_push(&ctx, NK_TREE_NODE, "Next", NK_MAXIMIZED)) { - nk_layout_row_dynamic(&ctx, 20, 1); - for (i = 0; i < 4; ++i) - nk_selectable_label(&ctx, (selected[i]) ? "Selected": "Unselected", NK_TEXT_LEFT, &selected[i]); - nk_tree_pop(&ctx); - } - if (nk_tree_push(&ctx, NK_TREE_NODE, "Previous", NK_MAXIMIZED)) { - nk_layout_row_dynamic(&ctx, 20, 1); - for (i = 4; i < 8; ++i) - nk_selectable_label(&ctx, (selected[i]) ? "Selected": "Unselected", NK_TEXT_LEFT, &selected[i]); - nk_tree_pop(&ctx); - } - nk_tree_pop(&ctx); - } - nk_group_end(&ctx); - } - } - nk_end(&ctx);} - - /* Draw */ - glViewport(0, 0, display_width, display_height); - glClear(GL_COLOR_BUFFER_BIT); - glClearColor(0.5882, 0.6666, 0.6666, 1.0f); - device_draw(&device, &ctx, width, height, scale, NK_ANTI_ALIASING_ON); - glfwSwapBuffers(win); - } - glDeleteTextures(1,(const GLuint*)&media.skin); - nk_font_atlas_clear(&atlas); - nk_free(&ctx); - device_shutdown(&device); - glfwTerminate(); - return 0; -} - diff --git a/deps/nuklear/example/skins/gwen.png b/deps/nuklear/example/skins/gwen.png deleted file mode 100644 index 40956c9411c4c59a9b5001589ae0fa2a6e2258c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24565 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 G-~10fwS(yZ diff --git a/deps/nuklear/example/stb_image.h b/deps/nuklear/example/stb_image.h deleted file mode 100644 index 0a9de39b..00000000 --- a/deps/nuklear/example/stb_image.h +++ /dev/null @@ -1,6509 +0,0 @@ -/* stb_image - v2.08 - public domain image loader - http://nothings.org/stb_image.h - no warranty implied; use at your own risk - - Do this: - #define STB_IMAGE_IMPLEMENTATION - before you include this file in *one* C or C++ file to create the implementation. - - // i.e. it should look like this: - #include ... - #include ... - #include ... - #define STB_IMAGE_IMPLEMENTATION - #include "stb_image.h" - - You can #define STBI_ASSERT(x) before the #include to avoid using assert.h. - And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free - - - QUICK NOTES: - Primarily of interest to game developers and other people who can - avoid problematic images and only need the trivial interface - - JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib) - PNG 1/2/4/8-bit-per-channel (16 bpc not supported) - - TGA (not sure what subset, if a subset) - BMP non-1bpp, non-RLE - PSD (composited view only, no extra channels, 8/16 bit-per-channel) - - GIF (*comp always reports as 4-channel) - HDR (radiance rgbE format) - PIC (Softimage PIC) - PNM (PPM and PGM binary only) - - Animated GIF still needs a proper API, but here's one way to do it: - http://gist.github.com/urraka/685d9a6340b26b830d49 - - - decode from memory or through FILE (define STBI_NO_STDIO to remove code) - - decode from arbitrary I/O callbacks - - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON) - - Full documentation under "DOCUMENTATION" below. - - - Revision 2.00 release notes: - - - Progressive JPEG is now supported. - - - PPM and PGM binary formats are now supported, thanks to Ken Miller. - - - x86 platforms now make use of SSE2 SIMD instructions for - JPEG decoding, and ARM platforms can use NEON SIMD if requested. - This work was done by Fabian "ryg" Giesen. SSE2 is used by - default, but NEON must be enabled explicitly; see docs. - - With other JPEG optimizations included in this version, we see - 2x speedup on a JPEG on an x86 machine, and a 1.5x speedup - on a JPEG on an ARM machine, relative to previous versions of this - library. The same results will not obtain for all JPGs and for all - x86/ARM machines. (Note that progressive JPEGs are significantly - slower to decode than regular JPEGs.) This doesn't mean that this - is the fastest JPEG decoder in the land; rather, it brings it - closer to parity with standard libraries. If you want the fastest - decode, look elsewhere. (See "Philosophy" section of docs below.) - - See final bullet items below for more info on SIMD. - - - Added STBI_MALLOC, STBI_REALLOC, and STBI_FREE macros for replacing - the memory allocator. Unlike other STBI libraries, these macros don't - support a context parameter, so if you need to pass a context in to - the allocator, you'll have to store it in a global or a thread-local - variable. - - - Split existing STBI_NO_HDR flag into two flags, STBI_NO_HDR and - STBI_NO_LINEAR. - STBI_NO_HDR: suppress implementation of .hdr reader format - STBI_NO_LINEAR: suppress high-dynamic-range light-linear float API - - - You can suppress implementation of any of the decoders to reduce - your code footprint by #defining one or more of the following - symbols before creating the implementation. - - STBI_NO_JPEG - STBI_NO_PNG - STBI_NO_BMP - STBI_NO_PSD - STBI_NO_TGA - STBI_NO_GIF - STBI_NO_HDR - STBI_NO_PIC - STBI_NO_PNM (.ppm and .pgm) - - - You can request *only* certain decoders and suppress all other ones - (this will be more forward-compatible, as addition of new decoders - doesn't require you to disable them explicitly): - - STBI_ONLY_JPEG - STBI_ONLY_PNG - STBI_ONLY_BMP - STBI_ONLY_PSD - STBI_ONLY_TGA - STBI_ONLY_GIF - STBI_ONLY_HDR - STBI_ONLY_PIC - STBI_ONLY_PNM (.ppm and .pgm) - - Note that you can define multiples of these, and you will get all - of them ("only x" and "only y" is interpreted to mean "only x&y"). - - - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still - want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB - - - Compilation of all SIMD code can be suppressed with - #define STBI_NO_SIMD - It should not be necessary to disable SIMD unless you have issues - compiling (e.g. using an x86 compiler which doesn't support SSE - intrinsics or that doesn't support the method used to detect - SSE2 support at run-time), and even those can be reported as - bugs so I can refine the built-in compile-time checking to be - smarter. - - - The old STBI_SIMD system which allowed installing a user-defined - IDCT etc. has been removed. If you need this, don't upgrade. My - assumption is that almost nobody was doing this, and those who - were will find the built-in SIMD more satisfactory anyway. - - - RGB values computed for JPEG images are slightly different from - previous versions of stb_image. (This is due to using less - integer precision in SIMD.) The C code has been adjusted so - that the same RGB values will be computed regardless of whether - SIMD support is available, so your app should always produce - consistent results. But these results are slightly different from - previous versions. (Specifically, about 3% of available YCbCr values - will compute different RGB results from pre-1.49 versions by +-1; - most of the deviating values are one smaller in the G channel.) - - - If you must produce consistent results with previous versions of - stb_image, #define STBI_JPEG_OLD and you will get the same results - you used to; however, you will not get the SIMD speedups for - the YCbCr-to-RGB conversion step (although you should still see - significant JPEG speedup from the other changes). - - Please note that STBI_JPEG_OLD is a temporary feature; it will be - removed in future versions of the library. It is only intended for - near-term back-compatibility use. - - - Latest revision history: - 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA - 2.07 (2015-09-13) partial animated GIF support - limited 16-bit PSD support - minor bugs, code cleanup, and compiler warnings - 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value - 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning - 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit - 2.03 (2015-04-12) additional corruption checking - stbi_set_flip_vertically_on_load - fix NEON support; fix mingw support - 2.02 (2015-01-19) fix incorrect assert, fix warning - 2.01 (2015-01-17) fix various warnings - 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG - 2.00 (2014-12-25) optimize JPEG, including x86 SSE2 & ARM NEON SIMD - progressive JPEG - PGM/PPM support - STBI_MALLOC,STBI_REALLOC,STBI_FREE - STBI_NO_*, STBI_ONLY_* - GIF bugfix - 1.48 (2014-12-14) fix incorrectly-named assert() - 1.47 (2014-12-14) 1/2/4-bit PNG support (both grayscale and paletted) - optimize PNG - fix bug in interlaced PNG with user-specified channel count - - See end of file for full revision history. - - - ============================ Contributors ========================= - - Image formats Bug fixes & warning fixes - Sean Barrett (jpeg, png, bmp) Marc LeBlanc - Nicolas Schulz (hdr, psd) Christpher Lloyd - Jonathan Dummer (tga) Dave Moore - Jean-Marc Lienher (gif) Won Chun - Tom Seddon (pic) the Horde3D community - Thatcher Ulrich (psd) Janez Zemva - Ken Miller (pgm, ppm) Jonathan Blow - urraka@github (animated gif) Laurent Gomila - Aruelien Pocheville - Ryamond Barbiero - David Woo - Extensions, features Martin Golini - Jetro Lauha (stbi_info) Roy Eltham - Martin "SpartanJ" Golini (stbi_info) Luke Graham - James "moose2000" Brown (iPhone PNG) Thomas Ruf - Ben "Disch" Wenger (io callbacks) John Bartholomew - Omar Cornut (1/2/4-bit PNG) Ken Hamada - Nicolas Guillemot (vertical flip) Cort Stratton - Richard Mitton (16-bit PSD) Blazej Dariusz Roszkowski - Thibault Reuille - Paul Du Bois - Guillaume George - Jerry Jansson - Hayaki Saito - Johan Duparc - Ronny Chevalier - Optimizations & bugfixes Michal Cichon - Fabian "ryg" Giesen Tero Hanninen - Arseny Kapoulkine Sergio Gonzalez - Cass Everitt - Engin Manap - If your name should be here but Martins Mozeiko - isn't, let Sean know. Joseph Thomson - Phil Jordan - Nathan Reed - Michaelangel007@github - Nick Verigakis - -LICENSE - -This software is in the public domain. Where that dedication is not -recognized, you are granted a perpetual, irrevocable license to copy, -distribute, and modify this file as you see fit. - -*/ - -#ifndef STBI_INCLUDE_STB_IMAGE_H -#define STBI_INCLUDE_STB_IMAGE_H - -// DOCUMENTATION -// -// Limitations: -// - no 16-bit-per-channel PNG -// - no 12-bit-per-channel JPEG -// - no JPEGs with arithmetic coding -// - no 1-bit BMP -// - GIF always returns *comp=4 -// -// Basic usage (see HDR discussion below for HDR usage): -// int x,y,n; -// unsigned char *data = stbi_load(filename, &x, &y, &n, 0); -// // ... process data if not NULL ... -// // ... x = width, y = height, n = # 8-bit components per pixel ... -// // ... replace '0' with '1'..'4' to force that many components per pixel -// // ... but 'n' will always be the number that it would have been if you said 0 -// stbi_image_free(data) -// -// Standard parameters: -// int *x -- outputs image width in pixels -// int *y -- outputs image height in pixels -// int *comp -- outputs # of image components in image file -// int req_comp -- if non-zero, # of image components requested in result -// -// The return value from an image loader is an 'unsigned char *' which points -// to the pixel data, or NULL on an allocation failure or if the image is -// corrupt or invalid. The pixel data consists of *y scanlines of *x pixels, -// with each pixel consisting of N interleaved 8-bit components; the first -// pixel pointed to is top-left-most in the image. There is no padding between -// image scanlines or between pixels, regardless of format. The number of -// components N is 'req_comp' if req_comp is non-zero, or *comp otherwise. -// If req_comp is non-zero, *comp has the number of components that _would_ -// have been output otherwise. E.g. if you set req_comp to 4, you will always -// get RGBA output, but you can check *comp to see if it's trivially opaque -// because e.g. there were only 3 channels in the source image. -// -// An output image with N components has the following components interleaved -// in this order in each pixel: -// -// N=#comp components -// 1 grey -// 2 grey, alpha -// 3 red, green, blue -// 4 red, green, blue, alpha -// -// If image loading fails for any reason, the return value will be NULL, -// and *x, *y, *comp will be unchanged. The function stbi_failure_reason() -// can be queried for an extremely brief, end-user unfriendly explanation -// of why the load failed. Define STBI_NO_FAILURE_STRINGS to avoid -// compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly -// more user-friendly ones. -// -// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. -// -// =========================================================================== -// -// Philosophy -// -// stb libraries are designed with the following priorities: -// -// 1. easy to use -// 2. easy to maintain -// 3. good performance -// -// Sometimes I let "good performance" creep up in priority over "easy to maintain", -// and for best performance I may provide less-easy-to-use APIs that give higher -// performance, in addition to the easy to use ones. Nevertheless, it's important -// to keep in mind that from the standpoint of you, a client of this library, -// all you care about is #1 and #3, and stb libraries do not emphasize #3 above all. -// -// Some secondary priorities arise directly from the first two, some of which -// make more explicit reasons why performance can't be emphasized. -// -// - Portable ("ease of use") -// - Small footprint ("easy to maintain") -// - No dependencies ("ease of use") -// -// =========================================================================== -// -// I/O callbacks -// -// I/O callbacks allow you to read from arbitrary sources, like packaged -// files or some other source. Data read from callbacks are processed -// through a small internal buffer (currently 128 bytes) to try to reduce -// overhead. -// -// The three functions you must define are "read" (reads some bytes of data), -// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). -// -// =========================================================================== -// -// SIMD support -// -// The JPEG decoder will try to automatically use SIMD kernels on x86 when -// supported by the compiler. For ARM Neon support, you must explicitly -// request it. -// -// (The old do-it-yourself SIMD API is no longer supported in the current -// code.) -// -// On x86, SSE2 will automatically be used when available based on a run-time -// test; if not, the generic C versions are used as a fall-back. On ARM targets, -// the typical path is to have separate builds for NEON and non-NEON devices -// (at least this is true for iOS and Android). Therefore, the NEON support is -// toggled by a build flag: define STBI_NEON to get NEON loops. -// -// The output of the JPEG decoder is slightly different from versions where -// SIMD support was introduced (that is, for versions before 1.49). The -// difference is only +-1 in the 8-bit RGB channels, and only on a small -// fraction of pixels. You can force the pre-1.49 behavior by defining -// STBI_JPEG_OLD, but this will disable some of the SIMD decoding path -// and hence cost some performance. -// -// If for some reason you do not want to use any of SIMD code, or if -// you have issues compiling it, you can disable it entirely by -// defining STBI_NO_SIMD. -// -// =========================================================================== -// -// HDR image support (disable by defining STBI_NO_HDR) -// -// stb_image now supports loading HDR images in general, and currently -// the Radiance .HDR file format, although the support is provided -// generically. You can still load any file through the existing interface; -// if you attempt to load an HDR file, it will be automatically remapped to -// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; -// both of these constants can be reconfigured through this interface: -// -// stbi_hdr_to_ldr_gamma(2.2f); -// stbi_hdr_to_ldr_scale(1.0f); -// -// (note, do not use _inverse_ constants; stbi_image will invert them -// appropriately). -// -// Additionally, there is a new, parallel interface for loading files as -// (linear) floats to preserve the full dynamic range: -// -// float *data = stbi_loadf(filename, &x, &y, &n, 0); -// -// If you load LDR images through this interface, those images will -// be promoted to floating point values, run through the inverse of -// constants corresponding to the above: -// -// stbi_ldr_to_hdr_scale(1.0f); -// stbi_ldr_to_hdr_gamma(2.2f); -// -// Finally, given a filename (or an open file or memory block--see header -// file for details) containing image data, you can query for the "most -// appropriate" interface to use (that is, whether the image is HDR or -// not), using: -// -// stbi_is_hdr(char *filename); -// -// =========================================================================== -// -// iPhone PNG support: -// -// By default we convert iphone-formatted PNGs back to RGB, even though -// they are internally encoded differently. You can disable this conversion -// by by calling stbi_convert_iphone_png_to_rgb(0), in which case -// you will always just get the native iphone "format" through (which -// is BGR stored in RGB). -// -// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per -// pixel to remove any premultiplied alpha *only* if the image file explicitly -// says there's premultiplied data (currently only happens in iPhone images, -// and only if iPhone convert-to-rgb processing is on). -// - - -#ifndef STBI_NO_STDIO -#include -#endif // STBI_NO_STDIO - -#define STBI_VERSION 1 - -enum -{ - STBI_default = 0, // only used for req_comp - - STBI_grey = 1, - STBI_grey_alpha = 2, - STBI_rgb = 3, - STBI_rgb_alpha = 4 -}; - -typedef unsigned char stbi_uc; - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef STB_IMAGE_STATIC -#define STBIDEF static -#else -#define STBIDEF extern -#endif - -////////////////////////////////////////////////////////////////////////////// -// -// PRIMARY API - works on images of any type -// - -// -// load image by filename, open file, or memory buffer -// - -typedef struct -{ - int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read - void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative - int (*eof) (void *user); // returns nonzero if we are at end of file/data -} stbi_io_callbacks; - -STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *comp, int req_comp); -STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *comp, int req_comp); -STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *comp, int req_comp); - -#ifndef STBI_NO_STDIO -STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); -// for stbi_load_from_file, file pointer is left pointing immediately after image -#endif - -#ifndef STBI_NO_LINEAR - STBIDEF float *stbi_loadf (char const *filename, int *x, int *y, int *comp, int req_comp); - STBIDEF float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); - STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp); - - #ifndef STBI_NO_STDIO - STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); - #endif -#endif - -#ifndef STBI_NO_HDR - STBIDEF void stbi_hdr_to_ldr_gamma(float gamma); - STBIDEF void stbi_hdr_to_ldr_scale(float scale); -#endif - -#ifndef STBI_NO_LINEAR - STBIDEF void stbi_ldr_to_hdr_gamma(float gamma); - STBIDEF void stbi_ldr_to_hdr_scale(float scale); -#endif // STBI_NO_HDR - -// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR -STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); -STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); -#ifndef STBI_NO_STDIO -STBIDEF int stbi_is_hdr (char const *filename); -STBIDEF int stbi_is_hdr_from_file(FILE *f); -#endif // STBI_NO_STDIO - - -// get a VERY brief reason for failure -// NOT THREADSAFE -STBIDEF const char *stbi_failure_reason (void); - -// free the loaded image -- this is just free() -STBIDEF void stbi_image_free (void *retval_from_stbi_load); - -// get image dimensions & components without fully decoding -STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); -STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); - -#ifndef STBI_NO_STDIO -STBIDEF int stbi_info (char const *filename, int *x, int *y, int *comp); -STBIDEF int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); - -#endif - - - -// for image formats that explicitly notate that they have premultiplied alpha, -// we just return the colors as stored in the file. set this flag to force -// unpremultiplication. results are undefined if the unpremultiply overflow. -STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); - -// indicate whether we should process iphone images back to canonical format, -// or just pass them through "as-is" -STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); - -// flip the image vertically, so the first pixel in the output array is the bottom left -STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip); - -// ZLIB client - used by PNG, available for other purposes - -STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); -STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header); -STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); -STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); - -STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); -STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); - - -#ifdef __cplusplus -} -#endif - -// -// -//// end header file ///////////////////////////////////////////////////// -#endif // STBI_INCLUDE_STB_IMAGE_H - -#ifdef STB_IMAGE_IMPLEMENTATION - -#if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) \ - || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) \ - || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) \ - || defined(STBI_ONLY_ZLIB) - #ifndef STBI_ONLY_JPEG - #define STBI_NO_JPEG - #endif - #ifndef STBI_ONLY_PNG - #define STBI_NO_PNG - #endif - #ifndef STBI_ONLY_BMP - #define STBI_NO_BMP - #endif - #ifndef STBI_ONLY_PSD - #define STBI_NO_PSD - #endif - #ifndef STBI_ONLY_TGA - #define STBI_NO_TGA - #endif - #ifndef STBI_ONLY_GIF - #define STBI_NO_GIF - #endif - #ifndef STBI_ONLY_HDR - #define STBI_NO_HDR - #endif - #ifndef STBI_ONLY_PIC - #define STBI_NO_PIC - #endif - #ifndef STBI_ONLY_PNM - #define STBI_NO_PNM - #endif -#endif - -#if defined(STBI_NO_PNG) && !defined(STBI_SUPPORT_ZLIB) && !defined(STBI_NO_ZLIB) -#define STBI_NO_ZLIB -#endif - - -#include -#include // ptrdiff_t on osx -#include -#include - -#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) -#include // ldexp -#endif - -#ifndef STBI_NO_STDIO -#include -#endif - -#ifndef STBI_ASSERT -#include -#define STBI_ASSERT(x) assert(x) -#endif - - -#ifndef _MSC_VER - #ifdef __cplusplus - #define stbi_inline inline - #else - #define stbi_inline - #endif -#else - #define stbi_inline __forceinline -#endif - - -#ifdef _MSC_VER -typedef unsigned short stbi__uint16; -typedef signed short stbi__int16; -typedef unsigned int stbi__uint32; -typedef signed int stbi__int32; -#else -#include -typedef uint16_t stbi__uint16; -typedef int16_t stbi__int16; -typedef uint32_t stbi__uint32; -typedef int32_t stbi__int32; -#endif - -// should produce compiler error if size is wrong -typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; - -#ifdef _MSC_VER -#define STBI_NOTUSED(v) (void)(v) -#else -#define STBI_NOTUSED(v) (void)sizeof(v) -#endif - -#ifdef _MSC_VER -#define STBI_HAS_LROTL -#endif - -#ifdef STBI_HAS_LROTL - #define stbi_lrot(x,y) _lrotl(x,y) -#else - #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) -#endif - -#if defined(STBI_MALLOC) && defined(STBI_FREE) && defined(STBI_REALLOC) -// ok -#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) -// ok -#else -#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC." -#endif - -#ifndef STBI_MALLOC -#define STBI_MALLOC(sz) malloc(sz) -#define STBI_REALLOC(p,sz) realloc(p,sz) -#define STBI_FREE(p) free(p) -#endif - -// x86/x64 detection -#if defined(__x86_64__) || defined(_M_X64) -#define STBI__X64_TARGET -#elif defined(__i386) || defined(_M_IX86) -#define STBI__X86_TARGET -#endif - -#if defined(__GNUC__) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) && !defined(__SSE2__) && !defined(STBI_NO_SIMD) -// NOTE: not clear do we actually need this for the 64-bit path? -// gcc doesn't support sse2 intrinsics unless you compile with -msse2, -// (but compiling with -msse2 allows the compiler to use SSE2 everywhere; -// this is just broken and gcc are jerks for not fixing it properly -// http://www.virtualdub.org/blog/pivot/entry.php?id=363 ) -#define STBI_NO_SIMD -#endif - -#if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD) -// Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET -// -// 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the -// Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant. -// As a result, enabling SSE2 on 32-bit MinGW is dangerous when not -// simultaneously enabling "-mstackrealign". -// -// See https://github.com/nothings/stb/issues/81 for more information. -// -// So default to no SSE2 on 32-bit MinGW. If you've read this far and added -// -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2. -#define STBI_NO_SIMD -#endif - -#if !defined(STBI_NO_SIMD) && defined(STBI__X86_TARGET) -#define STBI_SSE2 -#include - -#ifdef _MSC_VER - -#if _MSC_VER >= 1400 // not VC6 -#include // __cpuid -static int stbi__cpuid3(void) -{ - int info[4]; - __cpuid(info,1); - return info[3]; -} -#else -static int stbi__cpuid3(void) -{ - int res; - __asm { - mov eax,1 - cpuid - mov res,edx - } - return res; -} -#endif - -#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name - -static int stbi__sse2_available() -{ - int info3 = stbi__cpuid3(); - return ((info3 >> 26) & 1) != 0; -} -#else // assume GCC-style if not VC++ -#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) - -static int stbi__sse2_available() -{ -#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 // GCC 4.8 or later - // GCC 4.8+ has a nice way to do this - return __builtin_cpu_supports("sse2"); -#else - // portable way to do this, preferably without using GCC inline ASM? - // just bail for now. - return 0; -#endif -} -#endif -#endif - -// ARM NEON -#if defined(STBI_NO_SIMD) && defined(STBI_NEON) -#undef STBI_NEON -#endif - -#ifdef STBI_NEON -#include -// assume GCC or Clang on ARM targets -#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) -#endif - -#ifndef STBI_SIMD_ALIGN -#define STBI_SIMD_ALIGN(type, name) type name -#endif - -/////////////////////////////////////////////// -// -// stbi__context struct and start_xxx functions - -// stbi__context structure is our basic context used by all images, so it -// contains all the IO context, plus some basic image information -typedef struct -{ - stbi__uint32 img_x, img_y; - int img_n, img_out_n; - - stbi_io_callbacks io; - void *io_user_data; - - int read_from_callbacks; - int buflen; - stbi_uc buffer_start[128]; - - stbi_uc *img_buffer, *img_buffer_end; - stbi_uc *img_buffer_original, *img_buffer_original_end; -} stbi__context; - - -static void stbi__refill_buffer(stbi__context *s); - -// initialize a memory-decode context -static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len) -{ - s->io.read = NULL; - s->read_from_callbacks = 0; - s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer; - s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len; -} - -// initialize a callback-based context -static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *user) -{ - s->io = *c; - s->io_user_data = user; - s->buflen = sizeof(s->buffer_start); - s->read_from_callbacks = 1; - s->img_buffer_original = s->buffer_start; - stbi__refill_buffer(s); - s->img_buffer_original_end = s->img_buffer_end; -} - -#ifndef STBI_NO_STDIO - -static int stbi__stdio_read(void *user, char *data, int size) -{ - return (int) fread(data,1,size,(FILE*) user); -} - -static void stbi__stdio_skip(void *user, int n) -{ - fseek((FILE*) user, n, SEEK_CUR); -} - -static int stbi__stdio_eof(void *user) -{ - return feof((FILE*) user); -} - -static stbi_io_callbacks stbi__stdio_callbacks = -{ - stbi__stdio_read, - stbi__stdio_skip, - stbi__stdio_eof, -}; - -static void stbi__start_file(stbi__context *s, FILE *f) -{ - stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f); -} - -//static void stop_file(stbi__context *s) { } - -#endif // !STBI_NO_STDIO - -static void stbi__rewind(stbi__context *s) -{ - // conceptually rewind SHOULD rewind to the beginning of the stream, - // but we just rewind to the beginning of the initial buffer, because - // we only use it after doing 'test', which only ever looks at at most 92 bytes - s->img_buffer = s->img_buffer_original; - s->img_buffer_end = s->img_buffer_original_end; -} - -#ifndef STBI_NO_JPEG -static int stbi__jpeg_test(stbi__context *s); -static stbi_uc *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); -static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_PNG -static int stbi__png_test(stbi__context *s); -static stbi_uc *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); -static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_BMP -static int stbi__bmp_test(stbi__context *s); -static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); -static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_TGA -static int stbi__tga_test(stbi__context *s); -static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); -static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_PSD -static int stbi__psd_test(stbi__context *s); -static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); -static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_HDR -static int stbi__hdr_test(stbi__context *s); -static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); -static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_PIC -static int stbi__pic_test(stbi__context *s); -static stbi_uc *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); -static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_GIF -static int stbi__gif_test(stbi__context *s); -static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); -static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_PNM -static int stbi__pnm_test(stbi__context *s); -static stbi_uc *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); -static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -// this is not threadsafe -static const char *stbi__g_failure_reason; - -STBIDEF const char *stbi_failure_reason(void) -{ - return stbi__g_failure_reason; -} - -static int stbi__err(const char *str) -{ - stbi__g_failure_reason = str; - return 0; -} - -static void *stbi__malloc(size_t size) -{ - return STBI_MALLOC(size); -} - -// stbi__err - error -// stbi__errpf - error returning pointer to float -// stbi__errpuc - error returning pointer to unsigned char - -#ifdef STBI_NO_FAILURE_STRINGS - #define stbi__err(x,y) 0 -#elif defined(STBI_FAILURE_USERMSG) - #define stbi__err(x,y) stbi__err(y) -#else - #define stbi__err(x,y) stbi__err(x) -#endif - -#define stbi__errpf(x,y) ((float *)(size_t) (stbi__err(x,y)?NULL:NULL)) -#define stbi__errpuc(x,y) ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL)) - -STBIDEF void stbi_image_free(void *retval_from_stbi_load) -{ - STBI_FREE(retval_from_stbi_load); -} - -#ifndef STBI_NO_LINEAR -static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp); -#endif - -#ifndef STBI_NO_HDR -static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp); -#endif - -static int stbi__vertically_flip_on_load = 0; - -STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) -{ - stbi__vertically_flip_on_load = flag_true_if_should_flip; -} - -static unsigned char *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) -{ - #ifndef STBI_NO_JPEG - if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp); - #endif - #ifndef STBI_NO_PNG - if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp); - #endif - #ifndef STBI_NO_BMP - if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp); - #endif - #ifndef STBI_NO_GIF - if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp); - #endif - #ifndef STBI_NO_PSD - if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp); - #endif - #ifndef STBI_NO_PIC - if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp); - #endif - #ifndef STBI_NO_PNM - if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp); - #endif - - #ifndef STBI_NO_HDR - if (stbi__hdr_test(s)) { - float *hdr = stbi__hdr_load(s, x,y,comp,req_comp); - return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); - } - #endif - - #ifndef STBI_NO_TGA - // test tga last because it's a crappy test! - if (stbi__tga_test(s)) - return stbi__tga_load(s,x,y,comp,req_comp); - #endif - - return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); -} - -static unsigned char *stbi__load_flip(stbi__context *s, int *x, int *y, int *comp, int req_comp) -{ - unsigned char *result = stbi__load_main(s, x, y, comp, req_comp); - - if (stbi__vertically_flip_on_load && result != NULL) { - int w = *x, h = *y; - int depth = req_comp ? req_comp : *comp; - int row,col,z; - stbi_uc temp; - - // @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once - for (row = 0; row < (h>>1); row++) { - for (col = 0; col < w; col++) { - for (z = 0; z < depth; z++) { - temp = result[(row * w + col) * depth + z]; - result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z]; - result[((h - row - 1) * w + col) * depth + z] = temp; - } - } - } - } - - return result; -} - -#ifndef STBI_NO_HDR -static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp) -{ - if (stbi__vertically_flip_on_load && result != NULL) { - int w = *x, h = *y; - int depth = req_comp ? req_comp : *comp; - int row,col,z; - float temp; - - // @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once - for (row = 0; row < (h>>1); row++) { - for (col = 0; col < w; col++) { - for (z = 0; z < depth; z++) { - temp = result[(row * w + col) * depth + z]; - result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z]; - result[((h - row - 1) * w + col) * depth + z] = temp; - } - } - } - } -} -#endif - -#ifndef STBI_NO_STDIO - -static FILE *stbi__fopen(char const *filename, char const *mode) -{ - FILE *f; -#if defined(_MSC_VER) && _MSC_VER >= 1400 - if (0 != fopen_s(&f, filename, mode)) - f=0; -#else - f = fopen(filename, mode); -#endif - return f; -} - - -STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) -{ - FILE *f = stbi__fopen(filename, "rb"); - unsigned char *result; - if (!f) return stbi__errpuc("can't fopen", "Unable to open file"); - result = stbi_load_from_file(f,x,y,comp,req_comp); - fclose(f); - return result; -} - -STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) -{ - unsigned char *result; - stbi__context s; - stbi__start_file(&s,f); - result = stbi__load_flip(&s,x,y,comp,req_comp); - if (result) { - // need to 'unget' all the characters in the IO buffer - fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); - } - return result; -} -#endif //!STBI_NO_STDIO - -STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) -{ - stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__load_flip(&s,x,y,comp,req_comp); -} - -STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) -{ - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); - return stbi__load_flip(&s,x,y,comp,req_comp); -} - -#ifndef STBI_NO_LINEAR -static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) -{ - unsigned char *data; - #ifndef STBI_NO_HDR - if (stbi__hdr_test(s)) { - float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp); - if (hdr_data) - stbi__float_postprocess(hdr_data,x,y,comp,req_comp); - return hdr_data; - } - #endif - data = stbi__load_flip(s, x, y, comp, req_comp); - if (data) - return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); - return stbi__errpf("unknown image type", "Image not of any known type, or corrupt"); -} - -STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) -{ - stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__loadf_main(&s,x,y,comp,req_comp); -} - -STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) -{ - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); - return stbi__loadf_main(&s,x,y,comp,req_comp); -} - -#ifndef STBI_NO_STDIO -STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) -{ - float *result; - FILE *f = stbi__fopen(filename, "rb"); - if (!f) return stbi__errpf("can't fopen", "Unable to open file"); - result = stbi_loadf_from_file(f,x,y,comp,req_comp); - fclose(f); - return result; -} - -STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) -{ - stbi__context s; - stbi__start_file(&s,f); - return stbi__loadf_main(&s,x,y,comp,req_comp); -} -#endif // !STBI_NO_STDIO - -#endif // !STBI_NO_LINEAR - -// these is-hdr-or-not is defined independent of whether STBI_NO_LINEAR is -// defined, for API simplicity; if STBI_NO_LINEAR is defined, it always -// reports false! - -STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) -{ - #ifndef STBI_NO_HDR - stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__hdr_test(&s); - #else - STBI_NOTUSED(buffer); - STBI_NOTUSED(len); - return 0; - #endif -} - -#ifndef STBI_NO_STDIO -STBIDEF int stbi_is_hdr (char const *filename) -{ - FILE *f = stbi__fopen(filename, "rb"); - int result=0; - if (f) { - result = stbi_is_hdr_from_file(f); - fclose(f); - } - return result; -} - -STBIDEF int stbi_is_hdr_from_file(FILE *f) -{ - #ifndef STBI_NO_HDR - stbi__context s; - stbi__start_file(&s,f); - return stbi__hdr_test(&s); - #else - STBI_NOTUSED(f); - return 0; - #endif -} -#endif // !STBI_NO_STDIO - -STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) -{ - #ifndef STBI_NO_HDR - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); - return stbi__hdr_test(&s); - #else - STBI_NOTUSED(clbk); - STBI_NOTUSED(user); - return 0; - #endif -} - -static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f; -static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f; - -#ifndef STBI_NO_LINEAR -STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; } -STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; } -#endif - -STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; } -STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; } - - -////////////////////////////////////////////////////////////////////////////// -// -// Common code used by all image loaders -// - -enum -{ - STBI__SCAN_load=0, - STBI__SCAN_type, - STBI__SCAN_header -}; - -static void stbi__refill_buffer(stbi__context *s) -{ - int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen); - if (n == 0) { - // at end of file, treat same as if from memory, but need to handle case - // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file - s->read_from_callbacks = 0; - s->img_buffer = s->buffer_start; - s->img_buffer_end = s->buffer_start+1; - *s->img_buffer = 0; - } else { - s->img_buffer = s->buffer_start; - s->img_buffer_end = s->buffer_start + n; - } -} - -stbi_inline static stbi_uc stbi__get8(stbi__context *s) -{ - if (s->img_buffer < s->img_buffer_end) - return *s->img_buffer++; - if (s->read_from_callbacks) { - stbi__refill_buffer(s); - return *s->img_buffer++; - } - return 0; -} - -stbi_inline static int stbi__at_eof(stbi__context *s) -{ - if (s->io.read) { - if (!(s->io.eof)(s->io_user_data)) return 0; - // if feof() is true, check if buffer = end - // special case: we've only got the special 0 character at the end - if (s->read_from_callbacks == 0) return 1; - } - - return s->img_buffer >= s->img_buffer_end; -} - -static void stbi__skip(stbi__context *s, int n) -{ - if (n < 0) { - s->img_buffer = s->img_buffer_end; - return; - } - if (s->io.read) { - int blen = (int) (s->img_buffer_end - s->img_buffer); - if (blen < n) { - s->img_buffer = s->img_buffer_end; - (s->io.skip)(s->io_user_data, n - blen); - return; - } - } - s->img_buffer += n; -} - -static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n) -{ - if (s->io.read) { - int blen = (int) (s->img_buffer_end - s->img_buffer); - if (blen < n) { - int res, count; - - memcpy(buffer, s->img_buffer, blen); - - count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen); - res = (count == (n-blen)); - s->img_buffer = s->img_buffer_end; - return res; - } - } - - if (s->img_buffer+n <= s->img_buffer_end) { - memcpy(buffer, s->img_buffer, n); - s->img_buffer += n; - return 1; - } else - return 0; -} - -static int stbi__get16be(stbi__context *s) -{ - int z = stbi__get8(s); - return (z << 8) + stbi__get8(s); -} - -static stbi__uint32 stbi__get32be(stbi__context *s) -{ - stbi__uint32 z = stbi__get16be(s); - return (z << 16) + stbi__get16be(s); -} - -#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) -// nothing -#else -static int stbi__get16le(stbi__context *s) -{ - int z = stbi__get8(s); - return z + (stbi__get8(s) << 8); -} -#endif - -#ifndef STBI_NO_BMP -static stbi__uint32 stbi__get32le(stbi__context *s) -{ - stbi__uint32 z = stbi__get16le(s); - return z + (stbi__get16le(s) << 16); -} -#endif - -#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings - - -////////////////////////////////////////////////////////////////////////////// -// -// generic converter from built-in img_n to req_comp -// individual types do this automatically as much as possible (e.g. jpeg -// does all cases internally since it needs to colorspace convert anyway, -// and it never has alpha, so very few cases ). png can automatically -// interleave an alpha=255 channel, but falls back to this for other cases -// -// assume data buffer is malloced, so malloc a new one and free that one -// only failure mode is malloc failing - -static stbi_uc stbi__compute_y(int r, int g, int b) -{ - return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8); -} - -static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y) -{ - int i,j; - unsigned char *good; - - if (req_comp == img_n) return data; - STBI_ASSERT(req_comp >= 1 && req_comp <= 4); - - good = (unsigned char *) stbi__malloc(req_comp * x * y); - if (good == NULL) { - STBI_FREE(data); - return stbi__errpuc("outofmem", "Out of memory"); - } - - for (j=0; j < (int) y; ++j) { - unsigned char *src = data + j * x * img_n ; - unsigned char *dest = good + j * x * req_comp; - - #define COMBO(a,b) ((a)*8+(b)) - #define CASE(a,b) case COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) - // convert source image with img_n components to one with req_comp components; - // avoid switch per pixel, so use switch per scanline and massive macros - switch (COMBO(img_n, req_comp)) { - CASE(1,2) dest[0]=src[0], dest[1]=255; break; - CASE(1,3) dest[0]=dest[1]=dest[2]=src[0]; break; - CASE(1,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; break; - CASE(2,1) dest[0]=src[0]; break; - CASE(2,3) dest[0]=dest[1]=dest[2]=src[0]; break; - CASE(2,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; break; - CASE(3,4) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; break; - CASE(3,1) dest[0]=stbi__compute_y(src[0],src[1],src[2]); break; - CASE(3,2) dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = 255; break; - CASE(4,1) dest[0]=stbi__compute_y(src[0],src[1],src[2]); break; - CASE(4,2) dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; break; - CASE(4,3) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; break; - default: STBI_ASSERT(0); - } - #undef CASE - } - - STBI_FREE(data); - return good; -} - -#ifndef STBI_NO_LINEAR -static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) -{ - int i,k,n; - float *output = (float *) stbi__malloc(x * y * comp * sizeof(float)); - if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } - // compute number of non-alpha components - if (comp & 1) n = comp; else n = comp-1; - for (i=0; i < x*y; ++i) { - for (k=0; k < n; ++k) { - output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale); - } - if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f; - } - STBI_FREE(data); - return output; -} -#endif - -#ifndef STBI_NO_HDR -#define stbi__float2int(x) ((int) (x)) -static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp) -{ - int i,k,n; - stbi_uc *output = (stbi_uc *) stbi__malloc(x * y * comp); - if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } - // compute number of non-alpha components - if (comp & 1) n = comp; else n = comp-1; - for (i=0; i < x*y; ++i) { - for (k=0; k < n; ++k) { - float z = (float) pow(data[i*comp+k]*stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; - if (z < 0) z = 0; - if (z > 255) z = 255; - output[i*comp + k] = (stbi_uc) stbi__float2int(z); - } - if (k < comp) { - float z = data[i*comp+k] * 255 + 0.5f; - if (z < 0) z = 0; - if (z > 255) z = 255; - output[i*comp + k] = (stbi_uc) stbi__float2int(z); - } - } - STBI_FREE(data); - return output; -} -#endif - -////////////////////////////////////////////////////////////////////////////// -// -// "baseline" JPEG/JFIF decoder -// -// simple implementation -// - doesn't support delayed output of y-dimension -// - simple interface (only one output format: 8-bit interleaved RGB) -// - doesn't try to recover corrupt jpegs -// - doesn't allow partial loading, loading multiple at once -// - still fast on x86 (copying globals into locals doesn't help x86) -// - allocates lots of intermediate memory (full size of all components) -// - non-interleaved case requires this anyway -// - allows good upsampling (see next) -// high-quality -// - upsampled channels are bilinearly interpolated, even across blocks -// - quality integer IDCT derived from IJG's 'slow' -// performance -// - fast huffman; reasonable integer IDCT -// - some SIMD kernels for common paths on targets with SSE2/NEON -// - uses a lot of intermediate memory, could cache poorly - -#ifndef STBI_NO_JPEG - -// huffman decoding acceleration -#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache - -typedef struct -{ - stbi_uc fast[1 << FAST_BITS]; - // weirdly, repacking this into AoS is a 10% speed loss, instead of a win - stbi__uint16 code[256]; - stbi_uc values[256]; - stbi_uc size[257]; - unsigned int maxcode[18]; - int delta[17]; // old 'firstsymbol' - old 'firstcode' -} stbi__huffman; - -typedef struct -{ - stbi__context *s; - stbi__huffman huff_dc[4]; - stbi__huffman huff_ac[4]; - stbi_uc dequant[4][64]; - stbi__int16 fast_ac[4][1 << FAST_BITS]; - -// sizes for components, interleaved MCUs - int img_h_max, img_v_max; - int img_mcu_x, img_mcu_y; - int img_mcu_w, img_mcu_h; - -// definition of jpeg image component - struct - { - int id; - int h,v; - int tq; - int hd,ha; - int dc_pred; - - int x,y,w2,h2; - stbi_uc *data; - void *raw_data, *raw_coeff; - stbi_uc *linebuf; - short *coeff; // progressive only - int coeff_w, coeff_h; // number of 8x8 coefficient blocks - } img_comp[4]; - - stbi__uint32 code_buffer; // jpeg entropy-coded buffer - int code_bits; // number of valid bits - unsigned char marker; // marker seen while filling entropy buffer - int nomore; // flag if we saw a marker so must stop - - int progressive; - int spec_start; - int spec_end; - int succ_high; - int succ_low; - int eob_run; - - int scan_n, order[4]; - int restart_interval, todo; - -// kernels - void (*idct_block_kernel)(stbi_uc *out, int out_stride, short data[64]); - void (*YCbCr_to_RGB_kernel)(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step); - stbi_uc *(*resample_row_hv_2_kernel)(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs); -} stbi__jpeg; - -static int stbi__build_huffman(stbi__huffman *h, int *count) -{ - int i,j,k=0,code; - // build size list for each symbol (from JPEG spec) - for (i=0; i < 16; ++i) - for (j=0; j < count[i]; ++j) - h->size[k++] = (stbi_uc) (i+1); - h->size[k] = 0; - - // compute actual symbols (from jpeg spec) - code = 0; - k = 0; - for(j=1; j <= 16; ++j) { - // compute delta to add to code to compute symbol id - h->delta[j] = k - code; - if (h->size[k] == j) { - while (h->size[k] == j) - h->code[k++] = (stbi__uint16) (code++); - if (code-1 >= (1 << j)) return stbi__err("bad code lengths","Corrupt JPEG"); - } - // compute largest code + 1 for this size, preshifted as needed later - h->maxcode[j] = code << (16-j); - code <<= 1; - } - h->maxcode[j] = 0xffffffff; - - // build non-spec acceleration table; 255 is flag for not-accelerated - memset(h->fast, 255, 1 << FAST_BITS); - for (i=0; i < k; ++i) { - int s = h->size[i]; - if (s <= FAST_BITS) { - int c = h->code[i] << (FAST_BITS-s); - int m = 1 << (FAST_BITS-s); - for (j=0; j < m; ++j) { - h->fast[c+j] = (stbi_uc) i; - } - } - } - return 1; -} - -// build a table that decodes both magnitude and value of small ACs in -// one go. -static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h) -{ - int i; - for (i=0; i < (1 << FAST_BITS); ++i) { - stbi_uc fast = h->fast[i]; - fast_ac[i] = 0; - if (fast < 255) { - int rs = h->values[fast]; - int run = (rs >> 4) & 15; - int magbits = rs & 15; - int len = h->size[fast]; - - if (magbits && len + magbits <= FAST_BITS) { - // magnitude code followed by receive_extend code - int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); - int m = 1 << (magbits - 1); - if (k < m) k += (-1 << magbits) + 1; - // if the result is small enough, we can fit it in fast_ac table - if (k >= -128 && k <= 127) - fast_ac[i] = (stbi__int16) ((k << 8) + (run << 4) + (len + magbits)); - } - } - } -} - -static void stbi__grow_buffer_unsafe(stbi__jpeg *j) -{ - do { - int b = j->nomore ? 0 : stbi__get8(j->s); - if (b == 0xff) { - int c = stbi__get8(j->s); - if (c != 0) { - j->marker = (unsigned char) c; - j->nomore = 1; - return; - } - } - j->code_buffer |= b << (24 - j->code_bits); - j->code_bits += 8; - } while (j->code_bits <= 24); -} - -// (1 << n) - 1 -static stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; - -// decode a jpeg huffman value from the bitstream -stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h) -{ - unsigned int temp; - int c,k; - - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - - // look at the top FAST_BITS and determine what symbol ID it is, - // if the code is <= FAST_BITS - c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); - k = h->fast[c]; - if (k < 255) { - int s = h->size[k]; - if (s > j->code_bits) - return -1; - j->code_buffer <<= s; - j->code_bits -= s; - return h->values[k]; - } - - // naive test is to shift the code_buffer down so k bits are - // valid, then test against maxcode. To speed this up, we've - // preshifted maxcode left so that it has (16-k) 0s at the - // end; in other words, regardless of the number of bits, it - // wants to be compared against something shifted to have 16; - // that way we don't need to shift inside the loop. - temp = j->code_buffer >> 16; - for (k=FAST_BITS+1 ; ; ++k) - if (temp < h->maxcode[k]) - break; - if (k == 17) { - // error! code not found - j->code_bits -= 16; - return -1; - } - - if (k > j->code_bits) - return -1; - - // convert the huffman code to the symbol id - c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; - STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); - - // convert the id to a symbol - j->code_bits -= k; - j->code_buffer <<= k; - return h->values[c]; -} - -// bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); - - sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB - k = stbi_lrot(j->code_buffer, n); - STBI_ASSERT(n >= 0 && n < (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask))); - j->code_buffer = k & ~stbi__bmask[n]; - k &= stbi__bmask[n]; - j->code_bits -= n; - return k + (stbi__jbias[n] & ~sgn); -} - -// get some unsigned bits -stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n) -{ - unsigned int k; - if (j->code_bits < n) stbi__grow_buffer_unsafe(j); - k = stbi_lrot(j->code_buffer, n); - j->code_buffer = k & ~stbi__bmask[n]; - k &= stbi__bmask[n]; - j->code_bits -= n; - return k; -} - -stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j) -{ - unsigned int k; - if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); - k = j->code_buffer; - j->code_buffer <<= 1; - --j->code_bits; - return k & 0x80000000; -} - -// given a value that's at position X in the zigzag stream, -// where does it appear in the 8x8 matrix coded as row-major? -static stbi_uc stbi__jpeg_dezigzag[64+15] = -{ - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, - 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63, - // let corrupt input sample past end - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63 -}; - -// decode one 64-entry block-- -static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi_uc *dequant) -{ - int diff,dc,k; - int t; - - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - t = stbi__jpeg_huff_decode(j, hdc); - if (t < 0) return stbi__err("bad huffman code","Corrupt JPEG"); - - // 0 all the ac values now so we can do it 32-bits at a time - memset(data,0,64*sizeof(data[0])); - - diff = t ? stbi__extend_receive(j, t) : 0; - dc = j->img_comp[b].dc_pred + diff; - j->img_comp[b].dc_pred = dc; - data[0] = (short) (dc * dequant[0]); - - // decode AC components, see JPEG spec - k = 1; - do { - unsigned int zig; - int c,r,s; - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); - r = fac[c]; - if (r) { // fast-AC path - k += (r >> 4) & 15; // run - s = r & 15; // combined length - j->code_buffer <<= s; - j->code_bits -= s; - // decode into unzigzag'd location - zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short) ((r >> 8) * dequant[zig]); - } else { - int rs = stbi__jpeg_huff_decode(j, hac); - if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); - s = rs & 15; - r = rs >> 4; - if (s == 0) { - if (rs != 0xf0) break; // end block - k += 16; - } else { - k += r; - // decode into unzigzag'd location - zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short) (stbi__extend_receive(j,s) * dequant[zig]); - } - } - } while (k < 64); - return 1; -} - -static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__huffman *hdc, int b) -{ - int diff,dc; - int t; - if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); - - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - - if (j->succ_high == 0) { - // first scan for DC coefficient, must be first - memset(data,0,64*sizeof(data[0])); // 0 all the ac values now - t = stbi__jpeg_huff_decode(j, hdc); - diff = t ? stbi__extend_receive(j, t) : 0; - - dc = j->img_comp[b].dc_pred + diff; - j->img_comp[b].dc_pred = dc; - data[0] = (short) (dc << j->succ_low); - } else { - // refinement scan for DC coefficient - if (stbi__jpeg_get_bit(j)) - data[0] += (short) (1 << j->succ_low); - } - return 1; -} - -// @OPTIMIZE: store non-zigzagged during the decode passes, -// and only de-zigzag when dequantizing -static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__huffman *hac, stbi__int16 *fac) -{ - int k; - if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); - - if (j->succ_high == 0) { - int shift = j->succ_low; - - if (j->eob_run) { - --j->eob_run; - return 1; - } - - k = j->spec_start; - do { - unsigned int zig; - int c,r,s; - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); - r = fac[c]; - if (r) { // fast-AC path - k += (r >> 4) & 15; // run - s = r & 15; // combined length - j->code_buffer <<= s; - j->code_bits -= s; - zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short) ((r >> 8) << shift); - } else { - int rs = stbi__jpeg_huff_decode(j, hac); - if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); - s = rs & 15; - r = rs >> 4; - if (s == 0) { - if (r < 15) { - j->eob_run = (1 << r); - if (r) - j->eob_run += stbi__jpeg_get_bits(j, r); - --j->eob_run; - break; - } - k += 16; - } else { - k += r; - zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short) (stbi__extend_receive(j,s) << shift); - } - } - } while (k <= j->spec_end); - } else { - // refinement scan for these AC coefficients - - short bit = (short) (1 << j->succ_low); - - if (j->eob_run) { - --j->eob_run; - for (k = j->spec_start; k <= j->spec_end; ++k) { - short *p = &data[stbi__jpeg_dezigzag[k]]; - if (*p != 0) - if (stbi__jpeg_get_bit(j)) - if ((*p & bit)==0) { - if (*p > 0) - *p += bit; - else - *p -= bit; - } - } - } else { - k = j->spec_start; - do { - int r,s; - int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh - if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); - s = rs & 15; - r = rs >> 4; - if (s == 0) { - if (r < 15) { - j->eob_run = (1 << r) - 1; - if (r) - j->eob_run += stbi__jpeg_get_bits(j, r); - r = 64; // force end of block - } else { - // r=15 s=0 should write 16 0s, so we just do - // a run of 15 0s and then write s (which is 0), - // so we don't have to do anything special here - } - } else { - if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); - // sign bit - if (stbi__jpeg_get_bit(j)) - s = bit; - else - s = -bit; - } - - // advance by r - while (k <= j->spec_end) { - short *p = &data[stbi__jpeg_dezigzag[k++]]; - if (*p != 0) { - if (stbi__jpeg_get_bit(j)) - if ((*p & bit)==0) { - if (*p > 0) - *p += bit; - else - *p -= bit; - } - } else { - if (r == 0) { - *p = (short) s; - break; - } - --r; - } - } - } while (k <= j->spec_end); - } - } - return 1; -} - -// take a -128..127 value and stbi__clamp it and convert to 0..255 -stbi_inline static stbi_uc stbi__clamp(int x) -{ - // trick to use a single test to catch both cases - if ((unsigned int) x > 255) { - if (x < 0) return 0; - if (x > 255) return 255; - } - return (stbi_uc) x; -} - -#define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) -#define stbi__fsh(x) ((x) << 12) - -// derived from jidctint -- DCT_ISLOW -#define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ - int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ - p2 = s2; \ - p3 = s6; \ - p1 = (p2+p3) * stbi__f2f(0.5411961f); \ - t2 = p1 + p3*stbi__f2f(-1.847759065f); \ - t3 = p1 + p2*stbi__f2f( 0.765366865f); \ - p2 = s0; \ - p3 = s4; \ - t0 = stbi__fsh(p2+p3); \ - t1 = stbi__fsh(p2-p3); \ - x0 = t0+t3; \ - x3 = t0-t3; \ - x1 = t1+t2; \ - x2 = t1-t2; \ - t0 = s7; \ - t1 = s5; \ - t2 = s3; \ - t3 = s1; \ - p3 = t0+t2; \ - p4 = t1+t3; \ - p1 = t0+t3; \ - p2 = t1+t2; \ - p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ - t0 = t0*stbi__f2f( 0.298631336f); \ - t1 = t1*stbi__f2f( 2.053119869f); \ - t2 = t2*stbi__f2f( 3.072711026f); \ - t3 = t3*stbi__f2f( 1.501321110f); \ - p1 = p5 + p1*stbi__f2f(-0.899976223f); \ - p2 = p5 + p2*stbi__f2f(-2.562915447f); \ - p3 = p3*stbi__f2f(-1.961570560f); \ - p4 = p4*stbi__f2f(-0.390180644f); \ - t3 += p1+p4; \ - t2 += p2+p3; \ - t1 += p2+p4; \ - t0 += p1+p3; - -static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64]) -{ - int i,val[64],*v=val; - stbi_uc *o; - short *d = data; - - // columns - for (i=0; i < 8; ++i,++d, ++v) { - // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing - if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 - && d[40]==0 && d[48]==0 && d[56]==0) { - // no shortcut 0 seconds - // (1|2|3|4|5|6|7)==0 0 seconds - // all separate -0.047 seconds - // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds - int dcterm = d[0] << 2; - v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; - } else { - STBI__IDCT_1D(d[ 0],d[ 8],d[16],d[24],d[32],d[40],d[48],d[56]) - // constants scaled things up by 1<<12; let's bring them back - // down, but keep 2 extra bits of precision - x0 += 512; x1 += 512; x2 += 512; x3 += 512; - v[ 0] = (x0+t3) >> 10; - v[56] = (x0-t3) >> 10; - v[ 8] = (x1+t2) >> 10; - v[48] = (x1-t2) >> 10; - v[16] = (x2+t1) >> 10; - v[40] = (x2-t1) >> 10; - v[24] = (x3+t0) >> 10; - v[32] = (x3-t0) >> 10; - } - } - - for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { - // no fast case since the first 1D IDCT spread components out - STBI__IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) - // constants scaled things up by 1<<12, plus we had 1<<2 from first - // loop, plus horizontal and vertical each scale by sqrt(8) so together - // we've got an extra 1<<3, so 1<<17 total we need to remove. - // so we want to round that, which means adding 0.5 * 1<<17, - // aka 65536. Also, we'll end up with -128 to 127 that we want - // to encode as 0..255 by adding 128, so we'll add that before the shift - x0 += 65536 + (128<<17); - x1 += 65536 + (128<<17); - x2 += 65536 + (128<<17); - x3 += 65536 + (128<<17); - // tried computing the shifts into temps, or'ing the temps to see - // if any were out of range, but that was slower - o[0] = stbi__clamp((x0+t3) >> 17); - o[7] = stbi__clamp((x0-t3) >> 17); - o[1] = stbi__clamp((x1+t2) >> 17); - o[6] = stbi__clamp((x1-t2) >> 17); - o[2] = stbi__clamp((x2+t1) >> 17); - o[5] = stbi__clamp((x2-t1) >> 17); - o[3] = stbi__clamp((x3+t0) >> 17); - o[4] = stbi__clamp((x3-t0) >> 17); - } -} - -#ifdef STBI_SSE2 -// sse2 integer IDCT. not the fastest possible implementation but it -// produces bit-identical results to the generic C version so it's -// fully "transparent". -static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) -{ - // This is constructed to match our regular (generic) integer IDCT exactly. - __m128i row0, row1, row2, row3, row4, row5, row6, row7; - __m128i tmp; - - // dot product constant: even elems=x, odd elems=y - #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) - - // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) - // out(1) = c1[even]*x + c1[odd]*y - #define dct_rot(out0,out1, x,y,c0,c1) \ - __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ - __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ - __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ - __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ - __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ - __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) - - // out = in << 12 (in 16-bit, out 32-bit) - #define dct_widen(out, in) \ - __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ - __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) - - // wide add - #define dct_wadd(out, a, b) \ - __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ - __m128i out##_h = _mm_add_epi32(a##_h, b##_h) - - // wide sub - #define dct_wsub(out, a, b) \ - __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ - __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) - - // butterfly a/b, add bias, then shift by "s" and pack - #define dct_bfly32o(out0, out1, a,b,bias,s) \ - { \ - __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ - __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ - dct_wadd(sum, abiased, b); \ - dct_wsub(dif, abiased, b); \ - out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ - out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ - } - - // 8-bit interleave step (for transposes) - #define dct_interleave8(a, b) \ - tmp = a; \ - a = _mm_unpacklo_epi8(a, b); \ - b = _mm_unpackhi_epi8(tmp, b) - - // 16-bit interleave step (for transposes) - #define dct_interleave16(a, b) \ - tmp = a; \ - a = _mm_unpacklo_epi16(a, b); \ - b = _mm_unpackhi_epi16(tmp, b) - - #define dct_pass(bias,shift) \ - { \ - /* even part */ \ - dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ - __m128i sum04 = _mm_add_epi16(row0, row4); \ - __m128i dif04 = _mm_sub_epi16(row0, row4); \ - dct_widen(t0e, sum04); \ - dct_widen(t1e, dif04); \ - dct_wadd(x0, t0e, t3e); \ - dct_wsub(x3, t0e, t3e); \ - dct_wadd(x1, t1e, t2e); \ - dct_wsub(x2, t1e, t2e); \ - /* odd part */ \ - dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ - dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ - __m128i sum17 = _mm_add_epi16(row1, row7); \ - __m128i sum35 = _mm_add_epi16(row3, row5); \ - dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ - dct_wadd(x4, y0o, y4o); \ - dct_wadd(x5, y1o, y5o); \ - dct_wadd(x6, y2o, y5o); \ - dct_wadd(x7, y3o, y4o); \ - dct_bfly32o(row0,row7, x0,x7,bias,shift); \ - dct_bfly32o(row1,row6, x1,x6,bias,shift); \ - dct_bfly32o(row2,row5, x2,x5,bias,shift); \ - dct_bfly32o(row3,row4, x3,x4,bias,shift); \ - } - - __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); - __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f( 0.765366865f), stbi__f2f(0.5411961f)); - __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); - __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); - __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f( 0.298631336f), stbi__f2f(-1.961570560f)); - __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f( 3.072711026f)); - __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f( 2.053119869f), stbi__f2f(-0.390180644f)); - __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f( 1.501321110f)); - - // rounding biases in column/row passes, see stbi__idct_block for explanation. - __m128i bias_0 = _mm_set1_epi32(512); - __m128i bias_1 = _mm_set1_epi32(65536 + (128<<17)); - - // load - row0 = _mm_load_si128((const __m128i *) (data + 0*8)); - row1 = _mm_load_si128((const __m128i *) (data + 1*8)); - row2 = _mm_load_si128((const __m128i *) (data + 2*8)); - row3 = _mm_load_si128((const __m128i *) (data + 3*8)); - row4 = _mm_load_si128((const __m128i *) (data + 4*8)); - row5 = _mm_load_si128((const __m128i *) (data + 5*8)); - row6 = _mm_load_si128((const __m128i *) (data + 6*8)); - row7 = _mm_load_si128((const __m128i *) (data + 7*8)); - - // column pass - dct_pass(bias_0, 10); - - { - // 16bit 8x8 transpose pass 1 - dct_interleave16(row0, row4); - dct_interleave16(row1, row5); - dct_interleave16(row2, row6); - dct_interleave16(row3, row7); - - // transpose pass 2 - dct_interleave16(row0, row2); - dct_interleave16(row1, row3); - dct_interleave16(row4, row6); - dct_interleave16(row5, row7); - - // transpose pass 3 - dct_interleave16(row0, row1); - dct_interleave16(row2, row3); - dct_interleave16(row4, row5); - dct_interleave16(row6, row7); - } - - // row pass - dct_pass(bias_1, 17); - - { - // pack - __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 - __m128i p1 = _mm_packus_epi16(row2, row3); - __m128i p2 = _mm_packus_epi16(row4, row5); - __m128i p3 = _mm_packus_epi16(row6, row7); - - // 8bit 8x8 transpose pass 1 - dct_interleave8(p0, p2); // a0e0a1e1... - dct_interleave8(p1, p3); // c0g0c1g1... - - // transpose pass 2 - dct_interleave8(p0, p1); // a0c0e0g0... - dct_interleave8(p2, p3); // b0d0f0h0... - - // transpose pass 3 - dct_interleave8(p0, p2); // a0b0c0d0... - dct_interleave8(p1, p3); // a4b4c4d4... - - // store - _mm_storel_epi64((__m128i *) out, p0); out += out_stride; - _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; - _mm_storel_epi64((__m128i *) out, p2); out += out_stride; - _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; - _mm_storel_epi64((__m128i *) out, p1); out += out_stride; - _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; - _mm_storel_epi64((__m128i *) out, p3); out += out_stride; - _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p3, 0x4e)); - } - -#undef dct_const -#undef dct_rot -#undef dct_widen -#undef dct_wadd -#undef dct_wsub -#undef dct_bfly32o -#undef dct_interleave8 -#undef dct_interleave16 -#undef dct_pass -} - -#endif // STBI_SSE2 - -#ifdef STBI_NEON - -// NEON integer IDCT. should produce bit-identical -// results to the generic C version. -static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) -{ - int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; - - int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); - int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); - int16x4_t rot0_2 = vdup_n_s16(stbi__f2f( 0.765366865f)); - int16x4_t rot1_0 = vdup_n_s16(stbi__f2f( 1.175875602f)); - int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); - int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); - int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); - int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); - int16x4_t rot3_0 = vdup_n_s16(stbi__f2f( 0.298631336f)); - int16x4_t rot3_1 = vdup_n_s16(stbi__f2f( 2.053119869f)); - int16x4_t rot3_2 = vdup_n_s16(stbi__f2f( 3.072711026f)); - int16x4_t rot3_3 = vdup_n_s16(stbi__f2f( 1.501321110f)); - -#define dct_long_mul(out, inq, coeff) \ - int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ - int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) - -#define dct_long_mac(out, acc, inq, coeff) \ - int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ - int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) - -#define dct_widen(out, inq) \ - int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ - int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) - -// wide add -#define dct_wadd(out, a, b) \ - int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ - int32x4_t out##_h = vaddq_s32(a##_h, b##_h) - -// wide sub -#define dct_wsub(out, a, b) \ - int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ - int32x4_t out##_h = vsubq_s32(a##_h, b##_h) - -// butterfly a/b, then shift using "shiftop" by "s" and pack -#define dct_bfly32o(out0,out1, a,b,shiftop,s) \ - { \ - dct_wadd(sum, a, b); \ - dct_wsub(dif, a, b); \ - out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ - out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ - } - -#define dct_pass(shiftop, shift) \ - { \ - /* even part */ \ - int16x8_t sum26 = vaddq_s16(row2, row6); \ - dct_long_mul(p1e, sum26, rot0_0); \ - dct_long_mac(t2e, p1e, row6, rot0_1); \ - dct_long_mac(t3e, p1e, row2, rot0_2); \ - int16x8_t sum04 = vaddq_s16(row0, row4); \ - int16x8_t dif04 = vsubq_s16(row0, row4); \ - dct_widen(t0e, sum04); \ - dct_widen(t1e, dif04); \ - dct_wadd(x0, t0e, t3e); \ - dct_wsub(x3, t0e, t3e); \ - dct_wadd(x1, t1e, t2e); \ - dct_wsub(x2, t1e, t2e); \ - /* odd part */ \ - int16x8_t sum15 = vaddq_s16(row1, row5); \ - int16x8_t sum17 = vaddq_s16(row1, row7); \ - int16x8_t sum35 = vaddq_s16(row3, row5); \ - int16x8_t sum37 = vaddq_s16(row3, row7); \ - int16x8_t sumodd = vaddq_s16(sum17, sum35); \ - dct_long_mul(p5o, sumodd, rot1_0); \ - dct_long_mac(p1o, p5o, sum17, rot1_1); \ - dct_long_mac(p2o, p5o, sum35, rot1_2); \ - dct_long_mul(p3o, sum37, rot2_0); \ - dct_long_mul(p4o, sum15, rot2_1); \ - dct_wadd(sump13o, p1o, p3o); \ - dct_wadd(sump24o, p2o, p4o); \ - dct_wadd(sump23o, p2o, p3o); \ - dct_wadd(sump14o, p1o, p4o); \ - dct_long_mac(x4, sump13o, row7, rot3_0); \ - dct_long_mac(x5, sump24o, row5, rot3_1); \ - dct_long_mac(x6, sump23o, row3, rot3_2); \ - dct_long_mac(x7, sump14o, row1, rot3_3); \ - dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ - dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ - dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ - dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ - } - - // load - row0 = vld1q_s16(data + 0*8); - row1 = vld1q_s16(data + 1*8); - row2 = vld1q_s16(data + 2*8); - row3 = vld1q_s16(data + 3*8); - row4 = vld1q_s16(data + 4*8); - row5 = vld1q_s16(data + 5*8); - row6 = vld1q_s16(data + 6*8); - row7 = vld1q_s16(data + 7*8); - - // add DC bias - row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); - - // column pass - dct_pass(vrshrn_n_s32, 10); - - // 16bit 8x8 transpose - { -// these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. -// whether compilers actually get this is another story, sadly. -#define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } -#define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } -#define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } - - // pass 1 - dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 - dct_trn16(row2, row3); - dct_trn16(row4, row5); - dct_trn16(row6, row7); - - // pass 2 - dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 - dct_trn32(row1, row3); - dct_trn32(row4, row6); - dct_trn32(row5, row7); - - // pass 3 - dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 - dct_trn64(row1, row5); - dct_trn64(row2, row6); - dct_trn64(row3, row7); - -#undef dct_trn16 -#undef dct_trn32 -#undef dct_trn64 - } - - // row pass - // vrshrn_n_s32 only supports shifts up to 16, we need - // 17. so do a non-rounding shift of 16 first then follow - // up with a rounding shift by 1. - dct_pass(vshrn_n_s32, 16); - - { - // pack and round - uint8x8_t p0 = vqrshrun_n_s16(row0, 1); - uint8x8_t p1 = vqrshrun_n_s16(row1, 1); - uint8x8_t p2 = vqrshrun_n_s16(row2, 1); - uint8x8_t p3 = vqrshrun_n_s16(row3, 1); - uint8x8_t p4 = vqrshrun_n_s16(row4, 1); - uint8x8_t p5 = vqrshrun_n_s16(row5, 1); - uint8x8_t p6 = vqrshrun_n_s16(row6, 1); - uint8x8_t p7 = vqrshrun_n_s16(row7, 1); - - // again, these can translate into one instruction, but often don't. -#define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } -#define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } -#define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } - - // sadly can't use interleaved stores here since we only write - // 8 bytes to each scan line! - - // 8x8 8-bit transpose pass 1 - dct_trn8_8(p0, p1); - dct_trn8_8(p2, p3); - dct_trn8_8(p4, p5); - dct_trn8_8(p6, p7); - - // pass 2 - dct_trn8_16(p0, p2); - dct_trn8_16(p1, p3); - dct_trn8_16(p4, p6); - dct_trn8_16(p5, p7); - - // pass 3 - dct_trn8_32(p0, p4); - dct_trn8_32(p1, p5); - dct_trn8_32(p2, p6); - dct_trn8_32(p3, p7); - - // store - vst1_u8(out, p0); out += out_stride; - vst1_u8(out, p1); out += out_stride; - vst1_u8(out, p2); out += out_stride; - vst1_u8(out, p3); out += out_stride; - vst1_u8(out, p4); out += out_stride; - vst1_u8(out, p5); out += out_stride; - vst1_u8(out, p6); out += out_stride; - vst1_u8(out, p7); - -#undef dct_trn8_8 -#undef dct_trn8_16 -#undef dct_trn8_32 - } - -#undef dct_long_mul -#undef dct_long_mac -#undef dct_widen -#undef dct_wadd -#undef dct_wsub -#undef dct_bfly32o -#undef dct_pass -} - -#endif // STBI_NEON - -#define STBI__MARKER_none 0xff -// if there's a pending marker from the entropy stream, return that -// otherwise, fetch from the stream and get a marker. if there's no -// marker, return 0xff, which is never a valid marker value -static stbi_uc stbi__get_marker(stbi__jpeg *j) -{ - stbi_uc x; - if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } - x = stbi__get8(j->s); - if (x != 0xff) return STBI__MARKER_none; - while (x == 0xff) - x = stbi__get8(j->s); - return x; -} - -// in each scan, we'll have scan_n components, and the order -// of the components is specified by order[] -#define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) - -// after a restart interval, stbi__jpeg_reset the entropy decoder and -// the dc prediction -static void stbi__jpeg_reset(stbi__jpeg *j) -{ - j->code_bits = 0; - j->code_buffer = 0; - j->nomore = 0; - j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = 0; - j->marker = STBI__MARKER_none; - j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; - j->eob_run = 0; - // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, - // since we don't even allow 1<<30 pixels -} - -static int stbi__parse_entropy_coded_data(stbi__jpeg *z) -{ - stbi__jpeg_reset(z); - if (!z->progressive) { - if (z->scan_n == 1) { - int i,j; - STBI_SIMD_ALIGN(short, data[64]); - int n = z->order[0]; - // non-interleaved data, we just need to process one block at a time, - // in trivial scanline order - // number of blocks to do just depends on how many actual "pixels" this - // component has, independent of interleaved MCU blocking and such - int w = (z->img_comp[n].x+7) >> 3; - int h = (z->img_comp[n].y+7) >> 3; - for (j=0; j < h; ++j) { - for (i=0; i < w; ++i) { - int ha = z->img_comp[n].ha; - if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; - z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); - // every data block is an MCU, so countdown the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); - // if it's NOT a restart, then just bail, so we get corrupt data - // rather than no data - if (!STBI__RESTART(z->marker)) return 1; - stbi__jpeg_reset(z); - } - } - } - return 1; - } else { // interleaved - int i,j,k,x,y; - STBI_SIMD_ALIGN(short, data[64]); - for (j=0; j < z->img_mcu_y; ++j) { - for (i=0; i < z->img_mcu_x; ++i) { - // scan an interleaved mcu... process scan_n components in order - for (k=0; k < z->scan_n; ++k) { - int n = z->order[k]; - // scan out an mcu's worth of this component; that's just determined - // by the basic H and V specified for the component - for (y=0; y < z->img_comp[n].v; ++y) { - for (x=0; x < z->img_comp[n].h; ++x) { - int x2 = (i*z->img_comp[n].h + x)*8; - int y2 = (j*z->img_comp[n].v + y)*8; - int ha = z->img_comp[n].ha; - if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; - z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data); - } - } - } - // after all interleaved components, that's an interleaved MCU, - // so now count down the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); - if (!STBI__RESTART(z->marker)) return 1; - stbi__jpeg_reset(z); - } - } - } - return 1; - } - } else { - if (z->scan_n == 1) { - int i,j; - int n = z->order[0]; - // non-interleaved data, we just need to process one block at a time, - // in trivial scanline order - // number of blocks to do just depends on how many actual "pixels" this - // component has, independent of interleaved MCU blocking and such - int w = (z->img_comp[n].x+7) >> 3; - int h = (z->img_comp[n].y+7) >> 3; - for (j=0; j < h; ++j) { - for (i=0; i < w; ++i) { - short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); - if (z->spec_start == 0) { - if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) - return 0; - } else { - int ha = z->img_comp[n].ha; - if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) - return 0; - } - // every data block is an MCU, so countdown the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); - if (!STBI__RESTART(z->marker)) return 1; - stbi__jpeg_reset(z); - } - } - } - return 1; - } else { // interleaved - int i,j,k,x,y; - for (j=0; j < z->img_mcu_y; ++j) { - for (i=0; i < z->img_mcu_x; ++i) { - // scan an interleaved mcu... process scan_n components in order - for (k=0; k < z->scan_n; ++k) { - int n = z->order[k]; - // scan out an mcu's worth of this component; that's just determined - // by the basic H and V specified for the component - for (y=0; y < z->img_comp[n].v; ++y) { - for (x=0; x < z->img_comp[n].h; ++x) { - int x2 = (i*z->img_comp[n].h + x); - int y2 = (j*z->img_comp[n].v + y); - short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); - if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) - return 0; - } - } - } - // after all interleaved components, that's an interleaved MCU, - // so now count down the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); - if (!STBI__RESTART(z->marker)) return 1; - stbi__jpeg_reset(z); - } - } - } - return 1; - } - } -} - -static void stbi__jpeg_dequantize(short *data, stbi_uc *dequant) -{ - int i; - for (i=0; i < 64; ++i) - data[i] *= dequant[i]; -} - -static void stbi__jpeg_finish(stbi__jpeg *z) -{ - if (z->progressive) { - // dequantize and idct the data - int i,j,n; - for (n=0; n < z->s->img_n; ++n) { - int w = (z->img_comp[n].x+7) >> 3; - int h = (z->img_comp[n].y+7) >> 3; - for (j=0; j < h; ++j) { - for (i=0; i < w; ++i) { - short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); - stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); - z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); - } - } - } - } -} - -static int stbi__process_marker(stbi__jpeg *z, int m) -{ - int L; - switch (m) { - case STBI__MARKER_none: // no marker found - return stbi__err("expected marker","Corrupt JPEG"); - - case 0xDD: // DRI - specify restart interval - if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len","Corrupt JPEG"); - z->restart_interval = stbi__get16be(z->s); - return 1; - - case 0xDB: // DQT - define quantization table - L = stbi__get16be(z->s)-2; - while (L > 0) { - int q = stbi__get8(z->s); - int p = q >> 4; - int t = q & 15,i; - if (p != 0) return stbi__err("bad DQT type","Corrupt JPEG"); - if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG"); - for (i=0; i < 64; ++i) - z->dequant[t][stbi__jpeg_dezigzag[i]] = stbi__get8(z->s); - L -= 65; - } - return L==0; - - case 0xC4: // DHT - define huffman table - L = stbi__get16be(z->s)-2; - while (L > 0) { - stbi_uc *v; - int sizes[16],i,n=0; - int q = stbi__get8(z->s); - int tc = q >> 4; - int th = q & 15; - if (tc > 1 || th > 3) return stbi__err("bad DHT header","Corrupt JPEG"); - for (i=0; i < 16; ++i) { - sizes[i] = stbi__get8(z->s); - n += sizes[i]; - } - L -= 17; - if (tc == 0) { - if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0; - v = z->huff_dc[th].values; - } else { - if (!stbi__build_huffman(z->huff_ac+th, sizes)) return 0; - v = z->huff_ac[th].values; - } - for (i=0; i < n; ++i) - v[i] = stbi__get8(z->s); - if (tc != 0) - stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); - L -= n; - } - return L==0; - } - // check for comment block or APP blocks - if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { - stbi__skip(z->s, stbi__get16be(z->s)-2); - return 1; - } - return 0; -} - -// after we see SOS -static int stbi__process_scan_header(stbi__jpeg *z) -{ - int i; - int Ls = stbi__get16be(z->s); - z->scan_n = stbi__get8(z->s); - if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return stbi__err("bad SOS component count","Corrupt JPEG"); - if (Ls != 6+2*z->scan_n) return stbi__err("bad SOS len","Corrupt JPEG"); - for (i=0; i < z->scan_n; ++i) { - int id = stbi__get8(z->s), which; - int q = stbi__get8(z->s); - for (which = 0; which < z->s->img_n; ++which) - if (z->img_comp[which].id == id) - break; - if (which == z->s->img_n) return 0; // no match - z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff","Corrupt JPEG"); - z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff","Corrupt JPEG"); - z->order[i] = which; - } - - { - int aa; - z->spec_start = stbi__get8(z->s); - z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 - aa = stbi__get8(z->s); - z->succ_high = (aa >> 4); - z->succ_low = (aa & 15); - if (z->progressive) { - if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) - return stbi__err("bad SOS", "Corrupt JPEG"); - } else { - if (z->spec_start != 0) return stbi__err("bad SOS","Corrupt JPEG"); - if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS","Corrupt JPEG"); - z->spec_end = 63; - } - } - - return 1; -} - -static int stbi__process_frame_header(stbi__jpeg *z, int scan) -{ - stbi__context *s = z->s; - int Lf,p,i,q, h_max=1,v_max=1,c; - Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len","Corrupt JPEG"); // JPEG - p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline - s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG - s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires - c = stbi__get8(s); - if (c != 3 && c != 1) return stbi__err("bad component count","Corrupt JPEG"); // JFIF requires - s->img_n = c; - for (i=0; i < c; ++i) { - z->img_comp[i].data = NULL; - z->img_comp[i].linebuf = NULL; - } - - if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG"); - - for (i=0; i < s->img_n; ++i) { - z->img_comp[i].id = stbi__get8(s); - if (z->img_comp[i].id != i+1) // JFIF requires - if (z->img_comp[i].id != i) // some version of jpegtran outputs non-JFIF-compliant files! - return stbi__err("bad component ID","Corrupt JPEG"); - q = stbi__get8(s); - z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG"); - z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG"); - z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ","Corrupt JPEG"); - } - - if (scan != STBI__SCAN_load) return 1; - - if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); - - for (i=0; i < s->img_n; ++i) { - if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; - if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; - } - - // compute interleaved mcu info - z->img_h_max = h_max; - z->img_v_max = v_max; - z->img_mcu_w = h_max * 8; - z->img_mcu_h = v_max * 8; - z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; - z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; - - for (i=0; i < s->img_n; ++i) { - // number of effective pixels (e.g. for non-interleaved MCU) - z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; - z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; - // to simplify generation, we'll allocate enough memory to decode - // the bogus oversized data from using interleaved MCUs and their - // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't - // discard the extra data until colorspace conversion - z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; - z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; - z->img_comp[i].raw_data = stbi__malloc(z->img_comp[i].w2 * z->img_comp[i].h2+15); - - if (z->img_comp[i].raw_data == NULL) { - for(--i; i >= 0; --i) { - STBI_FREE(z->img_comp[i].raw_data); - z->img_comp[i].raw_data = NULL; - } - return stbi__err("outofmem", "Out of memory"); - } - // align blocks for idct using mmx/sse - z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); - z->img_comp[i].linebuf = NULL; - if (z->progressive) { - z->img_comp[i].coeff_w = (z->img_comp[i].w2 + 7) >> 3; - z->img_comp[i].coeff_h = (z->img_comp[i].h2 + 7) >> 3; - z->img_comp[i].raw_coeff = STBI_MALLOC(z->img_comp[i].coeff_w * z->img_comp[i].coeff_h * 64 * sizeof(short) + 15); - z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15); - } else { - z->img_comp[i].coeff = 0; - z->img_comp[i].raw_coeff = 0; - } - } - - return 1; -} - -// use comparisons since in some cases we handle more than one case (e.g. SOF) -#define stbi__DNL(x) ((x) == 0xdc) -#define stbi__SOI(x) ((x) == 0xd8) -#define stbi__EOI(x) ((x) == 0xd9) -#define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) -#define stbi__SOS(x) ((x) == 0xda) - -#define stbi__SOF_progressive(x) ((x) == 0xc2) - -static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) -{ - int m; - z->marker = STBI__MARKER_none; // initialize cached marker to empty - m = stbi__get_marker(z); - if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG"); - if (scan == STBI__SCAN_type) return 1; - m = stbi__get_marker(z); - while (!stbi__SOF(m)) { - if (!stbi__process_marker(z,m)) return 0; - m = stbi__get_marker(z); - while (m == STBI__MARKER_none) { - // some files have extra padding after their blocks, so ok, we'll scan - if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); - m = stbi__get_marker(z); - } - } - z->progressive = stbi__SOF_progressive(m); - if (!stbi__process_frame_header(z, scan)) return 0; - return 1; -} - -// decode image to YCbCr format -static int stbi__decode_jpeg_image(stbi__jpeg *j) -{ - int m; - for (m = 0; m < 4; m++) { - j->img_comp[m].raw_data = NULL; - j->img_comp[m].raw_coeff = NULL; - } - j->restart_interval = 0; - if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; - m = stbi__get_marker(j); - while (!stbi__EOI(m)) { - if (stbi__SOS(m)) { - if (!stbi__process_scan_header(j)) return 0; - if (!stbi__parse_entropy_coded_data(j)) return 0; - if (j->marker == STBI__MARKER_none ) { - // handle 0s at the end of image data from IP Kamera 9060 - while (!stbi__at_eof(j->s)) { - int x = stbi__get8(j->s); - if (x == 255) { - j->marker = stbi__get8(j->s); - break; - } else if (x != 0) { - return stbi__err("junk before marker", "Corrupt JPEG"); - } - } - // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 - } - } else { - if (!stbi__process_marker(j, m)) return 0; - } - m = stbi__get_marker(j); - } - if (j->progressive) - stbi__jpeg_finish(j); - return 1; -} - -// static jfif-centered resampling (across block boundaries) - -typedef stbi_uc *(*resample_row_func)(stbi_uc *out, stbi_uc *in0, stbi_uc *in1, - int w, int hs); - -#define stbi__div4(x) ((stbi_uc) ((x) >> 2)) - -static stbi_uc *resample_row_1(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) -{ - STBI_NOTUSED(out); - STBI_NOTUSED(in_far); - STBI_NOTUSED(w); - STBI_NOTUSED(hs); - return in_near; -} - -static stbi_uc* stbi__resample_row_v_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) -{ - // need to generate two samples vertically for every one in input - int i; - STBI_NOTUSED(hs); - for (i=0; i < w; ++i) - out[i] = stbi__div4(3*in_near[i] + in_far[i] + 2); - return out; -} - -static stbi_uc* stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) -{ - // need to generate two samples horizontally for every one in input - int i; - stbi_uc *input = in_near; - - if (w == 1) { - // if only one sample, can't do any interpolation - out[0] = out[1] = input[0]; - return out; - } - - out[0] = input[0]; - out[1] = stbi__div4(input[0]*3 + input[1] + 2); - for (i=1; i < w-1; ++i) { - int n = 3*input[i]+2; - out[i*2+0] = stbi__div4(n+input[i-1]); - out[i*2+1] = stbi__div4(n+input[i+1]); - } - out[i*2+0] = stbi__div4(input[w-2]*3 + input[w-1] + 2); - out[i*2+1] = input[w-1]; - - STBI_NOTUSED(in_far); - STBI_NOTUSED(hs); - - return out; -} - -#define stbi__div16(x) ((stbi_uc) ((x) >> 4)) - -static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) -{ - // need to generate 2x2 samples for every one in input - int i,t0,t1; - if (w == 1) { - out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); - return out; - } - - t1 = 3*in_near[0] + in_far[0]; - out[0] = stbi__div4(t1+2); - for (i=1; i < w; ++i) { - t0 = t1; - t1 = 3*in_near[i]+in_far[i]; - out[i*2-1] = stbi__div16(3*t0 + t1 + 8); - out[i*2 ] = stbi__div16(3*t1 + t0 + 8); - } - out[w*2-1] = stbi__div4(t1+2); - - STBI_NOTUSED(hs); - - return out; -} - -#if defined(STBI_SSE2) || defined(STBI_NEON) -static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) -{ - // need to generate 2x2 samples for every one in input - int i=0,t0,t1; - - if (w == 1) { - out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); - return out; - } - - t1 = 3*in_near[0] + in_far[0]; - // process groups of 8 pixels for as long as we can. - // note we can't handle the last pixel in a row in this loop - // because we need to handle the filter boundary conditions. - for (; i < ((w-1) & ~7); i += 8) { -#if defined(STBI_SSE2) - // load and perform the vertical filtering pass - // this uses 3*x + y = 4*x + (y - x) - __m128i zero = _mm_setzero_si128(); - __m128i farb = _mm_loadl_epi64((__m128i *) (in_far + i)); - __m128i nearb = _mm_loadl_epi64((__m128i *) (in_near + i)); - __m128i farw = _mm_unpacklo_epi8(farb, zero); - __m128i nearw = _mm_unpacklo_epi8(nearb, zero); - __m128i diff = _mm_sub_epi16(farw, nearw); - __m128i nears = _mm_slli_epi16(nearw, 2); - __m128i curr = _mm_add_epi16(nears, diff); // current row - - // horizontal filter works the same based on shifted vers of current - // row. "prev" is current row shifted right by 1 pixel; we need to - // insert the previous pixel value (from t1). - // "next" is current row shifted left by 1 pixel, with first pixel - // of next block of 8 pixels added in. - __m128i prv0 = _mm_slli_si128(curr, 2); - __m128i nxt0 = _mm_srli_si128(curr, 2); - __m128i prev = _mm_insert_epi16(prv0, t1, 0); - __m128i next = _mm_insert_epi16(nxt0, 3*in_near[i+8] + in_far[i+8], 7); - - // horizontal filter, polyphase implementation since it's convenient: - // even pixels = 3*cur + prev = cur*4 + (prev - cur) - // odd pixels = 3*cur + next = cur*4 + (next - cur) - // note the shared term. - __m128i bias = _mm_set1_epi16(8); - __m128i curs = _mm_slli_epi16(curr, 2); - __m128i prvd = _mm_sub_epi16(prev, curr); - __m128i nxtd = _mm_sub_epi16(next, curr); - __m128i curb = _mm_add_epi16(curs, bias); - __m128i even = _mm_add_epi16(prvd, curb); - __m128i odd = _mm_add_epi16(nxtd, curb); - - // interleave even and odd pixels, then undo scaling. - __m128i int0 = _mm_unpacklo_epi16(even, odd); - __m128i int1 = _mm_unpackhi_epi16(even, odd); - __m128i de0 = _mm_srli_epi16(int0, 4); - __m128i de1 = _mm_srli_epi16(int1, 4); - - // pack and write output - __m128i outv = _mm_packus_epi16(de0, de1); - _mm_storeu_si128((__m128i *) (out + i*2), outv); -#elif defined(STBI_NEON) - // load and perform the vertical filtering pass - // this uses 3*x + y = 4*x + (y - x) - uint8x8_t farb = vld1_u8(in_far + i); - uint8x8_t nearb = vld1_u8(in_near + i); - int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); - int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); - int16x8_t curr = vaddq_s16(nears, diff); // current row - - // horizontal filter works the same based on shifted vers of current - // row. "prev" is current row shifted right by 1 pixel; we need to - // insert the previous pixel value (from t1). - // "next" is current row shifted left by 1 pixel, with first pixel - // of next block of 8 pixels added in. - int16x8_t prv0 = vextq_s16(curr, curr, 7); - int16x8_t nxt0 = vextq_s16(curr, curr, 1); - int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); - int16x8_t next = vsetq_lane_s16(3*in_near[i+8] + in_far[i+8], nxt0, 7); - - // horizontal filter, polyphase implementation since it's convenient: - // even pixels = 3*cur + prev = cur*4 + (prev - cur) - // odd pixels = 3*cur + next = cur*4 + (next - cur) - // note the shared term. - int16x8_t curs = vshlq_n_s16(curr, 2); - int16x8_t prvd = vsubq_s16(prev, curr); - int16x8_t nxtd = vsubq_s16(next, curr); - int16x8_t even = vaddq_s16(curs, prvd); - int16x8_t odd = vaddq_s16(curs, nxtd); - - // undo scaling and round, then store with even/odd phases interleaved - uint8x8x2_t o; - o.val[0] = vqrshrun_n_s16(even, 4); - o.val[1] = vqrshrun_n_s16(odd, 4); - vst2_u8(out + i*2, o); -#endif - - // "previous" value for next iter - t1 = 3*in_near[i+7] + in_far[i+7]; - } - - t0 = t1; - t1 = 3*in_near[i] + in_far[i]; - out[i*2] = stbi__div16(3*t1 + t0 + 8); - - for (++i; i < w; ++i) { - t0 = t1; - t1 = 3*in_near[i]+in_far[i]; - out[i*2-1] = stbi__div16(3*t0 + t1 + 8); - out[i*2 ] = stbi__div16(3*t1 + t0 + 8); - } - out[w*2-1] = stbi__div4(t1+2); - - STBI_NOTUSED(hs); - - return out; -} -#endif - -static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) -{ - // resample with nearest-neighbor - int i,j; - STBI_NOTUSED(in_far); - for (i=0; i < w; ++i) - for (j=0; j < hs; ++j) - out[i*hs+j] = in_near[i]; - return out; -} - -#ifdef STBI_JPEG_OLD -// this is the same YCbCr-to-RGB calculation that stb_image has used -// historically before the algorithm changes in 1.49 -#define float2fixed(x) ((int) ((x) * 65536 + 0.5)) -static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) -{ - int i; - for (i=0; i < count; ++i) { - int y_fixed = (y[i] << 16) + 32768; // rounding - int r,g,b; - int cr = pcr[i] - 128; - int cb = pcb[i] - 128; - r = y_fixed + cr*float2fixed(1.40200f); - g = y_fixed - cr*float2fixed(0.71414f) - cb*float2fixed(0.34414f); - b = y_fixed + cb*float2fixed(1.77200f); - r >>= 16; - g >>= 16; - b >>= 16; - if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } - if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } - if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } - out[0] = (stbi_uc)r; - out[1] = (stbi_uc)g; - out[2] = (stbi_uc)b; - out[3] = 255; - out += step; - } -} -#else -// this is a reduced-precision calculation of YCbCr-to-RGB introduced -// to make sure the code produces the same results in both SIMD and scalar -#define float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) -static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) -{ - int i; - for (i=0; i < count; ++i) { - int y_fixed = (y[i] << 20) + (1<<19); // rounding - int r,g,b; - int cr = pcr[i] - 128; - int cb = pcb[i] - 128; - r = y_fixed + cr* float2fixed(1.40200f); - g = y_fixed + (cr*-float2fixed(0.71414f)) + ((cb*-float2fixed(0.34414f)) & 0xffff0000); - b = y_fixed + cb* float2fixed(1.77200f); - r >>= 20; - g >>= 20; - b >>= 20; - if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } - if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } - if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } - out[0] = (stbi_uc)r; - out[1] = (stbi_uc)g; - out[2] = (stbi_uc)b; - out[3] = 255; - out += step; - } -} -#endif - -#if defined(STBI_SSE2) || defined(STBI_NEON) -static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step) -{ - int i = 0; - -#ifdef STBI_SSE2 - // step == 3 is pretty ugly on the final interleave, and i'm not convinced - // it's useful in practice (you wouldn't use it for textures, for example). - // so just accelerate step == 4 case. - if (step == 4) { - // this is a fairly straightforward implementation and not super-optimized. - __m128i signflip = _mm_set1_epi8(-0x80); - __m128i cr_const0 = _mm_set1_epi16( (short) ( 1.40200f*4096.0f+0.5f)); - __m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f)); - __m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f)); - __m128i cb_const1 = _mm_set1_epi16( (short) ( 1.77200f*4096.0f+0.5f)); - __m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128); - __m128i xw = _mm_set1_epi16(255); // alpha channel - - for (; i+7 < count; i += 8) { - // load - __m128i y_bytes = _mm_loadl_epi64((__m128i *) (y+i)); - __m128i cr_bytes = _mm_loadl_epi64((__m128i *) (pcr+i)); - __m128i cb_bytes = _mm_loadl_epi64((__m128i *) (pcb+i)); - __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 - __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 - - // unpack to short (and left-shift cr, cb by 8) - __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); - __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); - __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); - - // color transform - __m128i yws = _mm_srli_epi16(yw, 4); - __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); - __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); - __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); - __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); - __m128i rws = _mm_add_epi16(cr0, yws); - __m128i gwt = _mm_add_epi16(cb0, yws); - __m128i bws = _mm_add_epi16(yws, cb1); - __m128i gws = _mm_add_epi16(gwt, cr1); - - // descale - __m128i rw = _mm_srai_epi16(rws, 4); - __m128i bw = _mm_srai_epi16(bws, 4); - __m128i gw = _mm_srai_epi16(gws, 4); - - // back to byte, set up for transpose - __m128i brb = _mm_packus_epi16(rw, bw); - __m128i gxb = _mm_packus_epi16(gw, xw); - - // transpose to interleave channels - __m128i t0 = _mm_unpacklo_epi8(brb, gxb); - __m128i t1 = _mm_unpackhi_epi8(brb, gxb); - __m128i o0 = _mm_unpacklo_epi16(t0, t1); - __m128i o1 = _mm_unpackhi_epi16(t0, t1); - - // store - _mm_storeu_si128((__m128i *) (out + 0), o0); - _mm_storeu_si128((__m128i *) (out + 16), o1); - out += 32; - } - } -#endif - -#ifdef STBI_NEON - // in this version, step=3 support would be easy to add. but is there demand? - if (step == 4) { - // this is a fairly straightforward implementation and not super-optimized. - uint8x8_t signflip = vdup_n_u8(0x80); - int16x8_t cr_const0 = vdupq_n_s16( (short) ( 1.40200f*4096.0f+0.5f)); - int16x8_t cr_const1 = vdupq_n_s16( - (short) ( 0.71414f*4096.0f+0.5f)); - int16x8_t cb_const0 = vdupq_n_s16( - (short) ( 0.34414f*4096.0f+0.5f)); - int16x8_t cb_const1 = vdupq_n_s16( (short) ( 1.77200f*4096.0f+0.5f)); - - for (; i+7 < count; i += 8) { - // load - uint8x8_t y_bytes = vld1_u8(y + i); - uint8x8_t cr_bytes = vld1_u8(pcr + i); - uint8x8_t cb_bytes = vld1_u8(pcb + i); - int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); - int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); - - // expand to s16 - int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); - int16x8_t crw = vshll_n_s8(cr_biased, 7); - int16x8_t cbw = vshll_n_s8(cb_biased, 7); - - // color transform - int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); - int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); - int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); - int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); - int16x8_t rws = vaddq_s16(yws, cr0); - int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); - int16x8_t bws = vaddq_s16(yws, cb1); - - // undo scaling, round, convert to byte - uint8x8x4_t o; - o.val[0] = vqrshrun_n_s16(rws, 4); - o.val[1] = vqrshrun_n_s16(gws, 4); - o.val[2] = vqrshrun_n_s16(bws, 4); - o.val[3] = vdup_n_u8(255); - - // store, interleaving r/g/b/a - vst4_u8(out, o); - out += 8*4; - } - } -#endif - - for (; i < count; ++i) { - int y_fixed = (y[i] << 20) + (1<<19); // rounding - int r,g,b; - int cr = pcr[i] - 128; - int cb = pcb[i] - 128; - r = y_fixed + cr* float2fixed(1.40200f); - g = y_fixed + cr*-float2fixed(0.71414f) + ((cb*-float2fixed(0.34414f)) & 0xffff0000); - b = y_fixed + cb* float2fixed(1.77200f); - r >>= 20; - g >>= 20; - b >>= 20; - if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } - if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } - if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } - out[0] = (stbi_uc)r; - out[1] = (stbi_uc)g; - out[2] = (stbi_uc)b; - out[3] = 255; - out += step; - } -} -#endif - -// set up the kernels -static void stbi__setup_jpeg(stbi__jpeg *j) -{ - j->idct_block_kernel = stbi__idct_block; - j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; - j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; - -#ifdef STBI_SSE2 - if (stbi__sse2_available()) { - j->idct_block_kernel = stbi__idct_simd; - #ifndef STBI_JPEG_OLD - j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; - #endif - j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; - } -#endif - -#ifdef STBI_NEON - j->idct_block_kernel = stbi__idct_simd; - #ifndef STBI_JPEG_OLD - j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; - #endif - j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; -#endif -} - -// clean up the temporary component buffers -static void stbi__cleanup_jpeg(stbi__jpeg *j) -{ - int i; - for (i=0; i < j->s->img_n; ++i) { - if (j->img_comp[i].raw_data) { - STBI_FREE(j->img_comp[i].raw_data); - j->img_comp[i].raw_data = NULL; - j->img_comp[i].data = NULL; - } - if (j->img_comp[i].raw_coeff) { - STBI_FREE(j->img_comp[i].raw_coeff); - j->img_comp[i].raw_coeff = 0; - j->img_comp[i].coeff = 0; - } - if (j->img_comp[i].linebuf) { - STBI_FREE(j->img_comp[i].linebuf); - j->img_comp[i].linebuf = NULL; - } - } -} - -typedef struct -{ - resample_row_func resample; - stbi_uc *line0,*line1; - int hs,vs; // expansion factor in each axis - int w_lores; // horizontal pixels pre-expansion - int ystep; // how far through vertical expansion we are - int ypos; // which pre-expansion row we're on -} stbi__resample; - -static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) -{ - int n, decode_n; - z->s->img_n = 0; // make stbi__cleanup_jpeg safe - - // validate req_comp - if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); - - // load a jpeg image from whichever source, but leave in YCbCr format - if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } - - // determine actual number of components to generate - n = req_comp ? req_comp : z->s->img_n; - - if (z->s->img_n == 3 && n < 3) - decode_n = 1; - else - decode_n = z->s->img_n; - - // resample and color-convert - { - int k; - unsigned int i,j; - stbi_uc *output; - stbi_uc *coutput[4]; - - stbi__resample res_comp[4]; - - for (k=0; k < decode_n; ++k) { - stbi__resample *r = &res_comp[k]; - - // allocate line buffer big enough for upsampling off the edges - // with upsample factor of 4 - z->img_comp[k].linebuf = (stbi_uc *) stbi__malloc(z->s->img_x + 3); - if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } - - r->hs = z->img_h_max / z->img_comp[k].h; - r->vs = z->img_v_max / z->img_comp[k].v; - r->ystep = r->vs >> 1; - r->w_lores = (z->s->img_x + r->hs-1) / r->hs; - r->ypos = 0; - r->line0 = r->line1 = z->img_comp[k].data; - - if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; - else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; - else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; - else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; - else r->resample = stbi__resample_row_generic; - } - - // can't error after this so, this is safe - output = (stbi_uc *) stbi__malloc(n * z->s->img_x * z->s->img_y + 1); - if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } - - // now go ahead and resample - for (j=0; j < z->s->img_y; ++j) { - stbi_uc *out = output + n * z->s->img_x * j; - for (k=0; k < decode_n; ++k) { - stbi__resample *r = &res_comp[k]; - int y_bot = r->ystep >= (r->vs >> 1); - coutput[k] = r->resample(z->img_comp[k].linebuf, - y_bot ? r->line1 : r->line0, - y_bot ? r->line0 : r->line1, - r->w_lores, r->hs); - if (++r->ystep >= r->vs) { - r->ystep = 0; - r->line0 = r->line1; - if (++r->ypos < z->img_comp[k].y) - r->line1 += z->img_comp[k].w2; - } - } - if (n >= 3) { - stbi_uc *y = coutput[0]; - if (z->s->img_n == 3) { - z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); - } else - for (i=0; i < z->s->img_x; ++i) { - out[0] = out[1] = out[2] = y[i]; - out[3] = 255; // not used if n==3 - out += n; - } - } else { - stbi_uc *y = coutput[0]; - if (n == 1) - for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; - else - for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255; - } - } - stbi__cleanup_jpeg(z); - *out_x = z->s->img_x; - *out_y = z->s->img_y; - if (comp) *comp = z->s->img_n; // report original components, not output - return output; - } -} - -static unsigned char *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) -{ - stbi__jpeg j; - j.s = s; - stbi__setup_jpeg(&j); - return load_jpeg_image(&j, x,y,comp,req_comp); -} - -static int stbi__jpeg_test(stbi__context *s) -{ - int r; - stbi__jpeg j; - j.s = s; - stbi__setup_jpeg(&j); - r = stbi__decode_jpeg_header(&j, STBI__SCAN_type); - stbi__rewind(s); - return r; -} - -static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp) -{ - if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { - stbi__rewind( j->s ); - return 0; - } - if (x) *x = j->s->img_x; - if (y) *y = j->s->img_y; - if (comp) *comp = j->s->img_n; - return 1; -} - -static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp) -{ - stbi__jpeg j; - j.s = s; - return stbi__jpeg_info_raw(&j, x, y, comp); -} -#endif - -// public domain zlib decode v0.2 Sean Barrett 2006-11-18 -// simple implementation -// - all input must be provided in an upfront buffer -// - all output is written to a single output buffer (can malloc/realloc) -// performance -// - fast huffman - -#ifndef STBI_NO_ZLIB - -// fast-way is faster to check than jpeg huffman, but slow way is slower -#define STBI__ZFAST_BITS 9 // accelerate all cases in default tables -#define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) - -// zlib-style huffman encoding -// (jpegs packs from left, zlib from right, so can't share code) -typedef struct -{ - stbi__uint16 fast[1 << STBI__ZFAST_BITS]; - stbi__uint16 firstcode[16]; - int maxcode[17]; - stbi__uint16 firstsymbol[16]; - stbi_uc size[288]; - stbi__uint16 value[288]; -} stbi__zhuffman; - -stbi_inline static int stbi__bitreverse16(int n) -{ - n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); - n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); - n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); - n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); - return n; -} - -stbi_inline static int stbi__bit_reverse(int v, int bits) -{ - STBI_ASSERT(bits <= 16); - // to bit reverse n bits, reverse 16 and shift - // e.g. 11 bits, bit reverse and shift away 5 - return stbi__bitreverse16(v) >> (16-bits); -} - -static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num) -{ - int i,k=0; - int code, next_code[16], sizes[17]; - - // DEFLATE spec for generating codes - memset(sizes, 0, sizeof(sizes)); - memset(z->fast, 0, sizeof(z->fast)); - for (i=0; i < num; ++i) - ++sizes[sizelist[i]]; - sizes[0] = 0; - for (i=1; i < 16; ++i) - if (sizes[i] > (1 << i)) - return stbi__err("bad sizes", "Corrupt PNG"); - code = 0; - for (i=1; i < 16; ++i) { - next_code[i] = code; - z->firstcode[i] = (stbi__uint16) code; - z->firstsymbol[i] = (stbi__uint16) k; - code = (code + sizes[i]); - if (sizes[i]) - if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt PNG"); - z->maxcode[i] = code << (16-i); // preshift for inner loop - code <<= 1; - k += sizes[i]; - } - z->maxcode[16] = 0x10000; // sentinel - for (i=0; i < num; ++i) { - int s = sizelist[i]; - if (s) { - int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; - stbi__uint16 fastv = (stbi__uint16) ((s << 9) | i); - z->size [c] = (stbi_uc ) s; - z->value[c] = (stbi__uint16) i; - if (s <= STBI__ZFAST_BITS) { - int j = stbi__bit_reverse(next_code[s],s); - while (j < (1 << STBI__ZFAST_BITS)) { - z->fast[j] = fastv; - j += (1 << s); - } - } - ++next_code[s]; - } - } - return 1; -} - -// zlib-from-memory implementation for PNG reading -// because PNG allows splitting the zlib stream arbitrarily, -// and it's annoying structurally to have PNG call ZLIB call PNG, -// we require PNG read all the IDATs and combine them into a single -// memory buffer - -typedef struct -{ - stbi_uc *zbuffer, *zbuffer_end; - int num_bits; - stbi__uint32 code_buffer; - - char *zout; - char *zout_start; - char *zout_end; - int z_expandable; - - stbi__zhuffman z_length, z_distance; -} stbi__zbuf; - -stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z) -{ - if (z->zbuffer >= z->zbuffer_end) return 0; - return *z->zbuffer++; -} - -static void stbi__fill_bits(stbi__zbuf *z) -{ - do { - STBI_ASSERT(z->code_buffer < (1U << z->num_bits)); - z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits; - z->num_bits += 8; - } while (z->num_bits <= 24); -} - -stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n) -{ - unsigned int k; - if (z->num_bits < n) stbi__fill_bits(z); - k = z->code_buffer & ((1 << n) - 1); - z->code_buffer >>= n; - z->num_bits -= n; - return k; -} - -static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) -{ - int b,s,k; - // not resolved by fast table, so compute it the slow way - // use jpeg approach, which requires MSbits at top - k = stbi__bit_reverse(a->code_buffer, 16); - for (s=STBI__ZFAST_BITS+1; ; ++s) - if (k < z->maxcode[s]) - break; - if (s == 16) return -1; // invalid code! - // code size is s, so: - b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; - STBI_ASSERT(z->size[b] == s); - a->code_buffer >>= s; - a->num_bits -= s; - return z->value[b]; -} - -stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) -{ - int b,s; - if (a->num_bits < 16) stbi__fill_bits(a); - b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; - if (b) { - s = b >> 9; - a->code_buffer >>= s; - a->num_bits -= s; - return b & 511; - } - return stbi__zhuffman_decode_slowpath(a, z); -} - -static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes -{ - char *q; - int cur, limit; - z->zout = zout; - if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG"); - cur = (int) (z->zout - z->zout_start); - limit = (int) (z->zout_end - z->zout_start); - while (cur + n > limit) - limit *= 2; - q = (char *) STBI_REALLOC(z->zout_start, limit); - if (q == NULL) return stbi__err("outofmem", "Out of memory"); - z->zout_start = q; - z->zout = q + cur; - z->zout_end = q + limit; - return 1; -} - -static int stbi__zlength_base[31] = { - 3,4,5,6,7,8,9,10,11,13, - 15,17,19,23,27,31,35,43,51,59, - 67,83,99,115,131,163,195,227,258,0,0 }; - -static int stbi__zlength_extra[31]= -{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; - -static int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, -257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; - -static int stbi__zdist_extra[32] = -{ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -static int stbi__parse_huffman_block(stbi__zbuf *a) -{ - char *zout = a->zout; - for(;;) { - int z = stbi__zhuffman_decode(a, &a->z_length); - if (z < 256) { - if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); // error in huffman codes - if (zout >= a->zout_end) { - if (!stbi__zexpand(a, zout, 1)) return 0; - zout = a->zout; - } - *zout++ = (char) z; - } else { - stbi_uc *p; - int len,dist; - if (z == 256) { - a->zout = zout; - return 1; - } - z -= 257; - len = stbi__zlength_base[z]; - if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); - z = stbi__zhuffman_decode(a, &a->z_distance); - if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); - dist = stbi__zdist_base[z]; - if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); - if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG"); - if (zout + len > a->zout_end) { - if (!stbi__zexpand(a, zout, len)) return 0; - zout = a->zout; - } - p = (stbi_uc *) (zout - dist); - if (dist == 1) { // run of one byte; common in images. - stbi_uc v = *p; - if (len) { do *zout++ = v; while (--len); } - } else { - if (len) { do *zout++ = *p++; while (--len); } - } - } - } -} - -static int stbi__compute_huffman_codes(stbi__zbuf *a) -{ - static stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; - stbi__zhuffman z_codelength; - stbi_uc lencodes[286+32+137];//padding for maximum single op - stbi_uc codelength_sizes[19]; - int i,n; - - int hlit = stbi__zreceive(a,5) + 257; - int hdist = stbi__zreceive(a,5) + 1; - int hclen = stbi__zreceive(a,4) + 4; - - memset(codelength_sizes, 0, sizeof(codelength_sizes)); - for (i=0; i < hclen; ++i) { - int s = stbi__zreceive(a,3); - codelength_sizes[length_dezigzag[i]] = (stbi_uc) s; - } - if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; - - n = 0; - while (n < hlit + hdist) { - int c = stbi__zhuffman_decode(a, &z_codelength); - if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); - if (c < 16) - lencodes[n++] = (stbi_uc) c; - else if (c == 16) { - c = stbi__zreceive(a,2)+3; - memset(lencodes+n, lencodes[n-1], c); - n += c; - } else if (c == 17) { - c = stbi__zreceive(a,3)+3; - memset(lencodes+n, 0, c); - n += c; - } else { - STBI_ASSERT(c == 18); - c = stbi__zreceive(a,7)+11; - memset(lencodes+n, 0, c); - n += c; - } - } - if (n != hlit+hdist) return stbi__err("bad codelengths","Corrupt PNG"); - if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; - if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; - return 1; -} - -static int stbi__parse_uncomperssed_block(stbi__zbuf *a) -{ - stbi_uc header[4]; - int len,nlen,k; - if (a->num_bits & 7) - stbi__zreceive(a, a->num_bits & 7); // discard - // drain the bit-packed data into header - k = 0; - while (a->num_bits > 0) { - header[k++] = (stbi_uc) (a->code_buffer & 255); // suppress MSVC run-time check - a->code_buffer >>= 8; - a->num_bits -= 8; - } - STBI_ASSERT(a->num_bits == 0); - // now fill header the normal way - while (k < 4) - header[k++] = stbi__zget8(a); - len = header[1] * 256 + header[0]; - nlen = header[3] * 256 + header[2]; - if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt","Corrupt PNG"); - if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer","Corrupt PNG"); - if (a->zout + len > a->zout_end) - if (!stbi__zexpand(a, a->zout, len)) return 0; - memcpy(a->zout, a->zbuffer, len); - a->zbuffer += len; - a->zout += len; - return 1; -} - -static int stbi__parse_zlib_header(stbi__zbuf *a) -{ - int cmf = stbi__zget8(a); - int cm = cmf & 15; - /* int cinfo = cmf >> 4; */ - int flg = stbi__zget8(a); - if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec - if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png - if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png - // window = 1 << (8 + cinfo)... but who cares, we fully buffer output - return 1; -} - -// @TODO: should statically initialize these for optimal thread safety -static stbi_uc stbi__zdefault_length[288], stbi__zdefault_distance[32]; -static void stbi__init_zdefaults(void) -{ - int i; // use <= to match clearly with spec - for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; - for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; - for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; - for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; - - for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; -} - -static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) -{ - int final, type; - if (parse_header) - if (!stbi__parse_zlib_header(a)) return 0; - a->num_bits = 0; - a->code_buffer = 0; - do { - final = stbi__zreceive(a,1); - type = stbi__zreceive(a,2); - if (type == 0) { - if (!stbi__parse_uncomperssed_block(a)) return 0; - } else if (type == 3) { - return 0; - } else { - if (type == 1) { - // use fixed code lengths - if (!stbi__zdefault_distance[31]) stbi__init_zdefaults(); - if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0; - if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; - } else { - if (!stbi__compute_huffman_codes(a)) return 0; - } - if (!stbi__parse_huffman_block(a)) return 0; - } - } while (!final); - return 1; -} - -static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse_header) -{ - a->zout_start = obuf; - a->zout = obuf; - a->zout_end = obuf + olen; - a->z_expandable = exp; - - return stbi__parse_zlib(a, parse_header); -} - -STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) -{ - stbi__zbuf a; - char *p = (char *) stbi__malloc(initial_size); - if (p == NULL) return NULL; - a.zbuffer = (stbi_uc *) buffer; - a.zbuffer_end = (stbi_uc *) buffer + len; - if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { - if (outlen) *outlen = (int) (a.zout - a.zout_start); - return a.zout_start; - } else { - STBI_FREE(a.zout_start); - return NULL; - } -} - -STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) -{ - return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); -} - -STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header) -{ - stbi__zbuf a; - char *p = (char *) stbi__malloc(initial_size); - if (p == NULL) return NULL; - a.zbuffer = (stbi_uc *) buffer; - a.zbuffer_end = (stbi_uc *) buffer + len; - if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { - if (outlen) *outlen = (int) (a.zout - a.zout_start); - return a.zout_start; - } else { - STBI_FREE(a.zout_start); - return NULL; - } -} - -STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) -{ - stbi__zbuf a; - a.zbuffer = (stbi_uc *) ibuffer; - a.zbuffer_end = (stbi_uc *) ibuffer + ilen; - if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) - return (int) (a.zout - a.zout_start); - else - return -1; -} - -STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) -{ - stbi__zbuf a; - char *p = (char *) stbi__malloc(16384); - if (p == NULL) return NULL; - a.zbuffer = (stbi_uc *) buffer; - a.zbuffer_end = (stbi_uc *) buffer+len; - if (stbi__do_zlib(&a, p, 16384, 1, 0)) { - if (outlen) *outlen = (int) (a.zout - a.zout_start); - return a.zout_start; - } else { - STBI_FREE(a.zout_start); - return NULL; - } -} - -STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) -{ - stbi__zbuf a; - a.zbuffer = (stbi_uc *) ibuffer; - a.zbuffer_end = (stbi_uc *) ibuffer + ilen; - if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) - return (int) (a.zout - a.zout_start); - else - return -1; -} -#endif - -// public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 -// simple implementation -// - only 8-bit samples -// - no CRC checking -// - allocates lots of intermediate memory -// - avoids problem of streaming data between subsystems -// - avoids explicit window management -// performance -// - uses stb_zlib, a PD zlib implementation with fast huffman decoding - -#ifndef STBI_NO_PNG -typedef struct -{ - stbi__uint32 length; - stbi__uint32 type; -} stbi__pngchunk; - -static stbi__pngchunk stbi__get_chunk_header(stbi__context *s) -{ - stbi__pngchunk c; - c.length = stbi__get32be(s); - c.type = stbi__get32be(s); - return c; -} - -static int stbi__check_png_header(stbi__context *s) -{ - static stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; - int i; - for (i=0; i < 8; ++i) - if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig","Not a PNG"); - return 1; -} - -typedef struct -{ - stbi__context *s; - stbi_uc *idata, *expanded, *out; -} stbi__png; - - -enum { - STBI__F_none=0, - STBI__F_sub=1, - STBI__F_up=2, - STBI__F_avg=3, - STBI__F_paeth=4, - // synthetic filters used for first scanline to avoid needing a dummy row of 0s - STBI__F_avg_first, - STBI__F_paeth_first -}; - -static stbi_uc first_row_filter[5] = -{ - STBI__F_none, - STBI__F_sub, - STBI__F_none, - STBI__F_avg_first, - STBI__F_paeth_first -}; - -static int stbi__paeth(int a, int b, int c) -{ - int p = a + b - c; - int pa = abs(p-a); - int pb = abs(p-b); - int pc = abs(p-c); - if (pa <= pb && pa <= pc) return a; - if (pb <= pc) return b; - return c; -} - -static stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; - -// create the png data from post-deflated data -static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) -{ - stbi__context *s = a->s; - stbi__uint32 i,j,stride = x*out_n; - stbi__uint32 img_len, img_width_bytes; - int k; - int img_n = s->img_n; // copy it into a local for later - - STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1); - a->out = (stbi_uc *) stbi__malloc(x * y * out_n); // extra bytes to write off the end into - if (!a->out) return stbi__err("outofmem", "Out of memory"); - - img_width_bytes = (((img_n * x * depth) + 7) >> 3); - img_len = (img_width_bytes + 1) * y; - if (s->img_x == x && s->img_y == y) { - if (raw_len != img_len) return stbi__err("not enough pixels","Corrupt PNG"); - } else { // interlaced: - if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG"); - } - - for (j=0; j < y; ++j) { - stbi_uc *cur = a->out + stride*j; - stbi_uc *prior = cur - stride; - int filter = *raw++; - int filter_bytes = img_n; - int width = x; - if (filter > 4) - return stbi__err("invalid filter","Corrupt PNG"); - - if (depth < 8) { - STBI_ASSERT(img_width_bytes <= x); - cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place - filter_bytes = 1; - width = img_width_bytes; - } - - // if first row, use special filter that doesn't sample previous row - if (j == 0) filter = first_row_filter[filter]; - - // handle first byte explicitly - for (k=0; k < filter_bytes; ++k) { - switch (filter) { - case STBI__F_none : cur[k] = raw[k]; break; - case STBI__F_sub : cur[k] = raw[k]; break; - case STBI__F_up : cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; - case STBI__F_avg : cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); break; - case STBI__F_paeth : cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0,prior[k],0)); break; - case STBI__F_avg_first : cur[k] = raw[k]; break; - case STBI__F_paeth_first: cur[k] = raw[k]; break; - } - } - - if (depth == 8) { - if (img_n != out_n) - cur[img_n] = 255; // first pixel - raw += img_n; - cur += out_n; - prior += out_n; - } else { - raw += 1; - cur += 1; - prior += 1; - } - - // this is a little gross, so that we don't switch per-pixel or per-component - if (depth < 8 || img_n == out_n) { - int nk = (width - 1)*img_n; - #define CASE(f) \ - case f: \ - for (k=0; k < nk; ++k) - switch (filter) { - // "none" filter turns into a memcpy here; make that explicit. - case STBI__F_none: memcpy(cur, raw, nk); break; - CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); break; - CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; - CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); break; - CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); break; - CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); break; - CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); break; - } - #undef CASE - raw += nk; - } else { - STBI_ASSERT(img_n+1 == out_n); - #define CASE(f) \ - case f: \ - for (i=x-1; i >= 1; --i, cur[img_n]=255,raw+=img_n,cur+=out_n,prior+=out_n) \ - for (k=0; k < img_n; ++k) - switch (filter) { - CASE(STBI__F_none) cur[k] = raw[k]; break; - CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k-out_n]); break; - CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; - CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-out_n])>>1)); break; - CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-out_n],prior[k],prior[k-out_n])); break; - CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k-out_n] >> 1)); break; - CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-out_n],0,0)); break; - } - #undef CASE - } - } - - // we make a separate pass to expand bits to pixels; for performance, - // this could run two scanlines behind the above code, so it won't - // intefere with filtering but will still be in the cache. - if (depth < 8) { - for (j=0; j < y; ++j) { - stbi_uc *cur = a->out + stride*j; - stbi_uc *in = a->out + stride*j + x*out_n - img_width_bytes; - // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit - // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop - stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range - - // note that the final byte might overshoot and write more data than desired. - // we can allocate enough data that this never writes out of memory, but it - // could also overwrite the next scanline. can it overwrite non-empty data - // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. - // so we need to explicitly clamp the final ones - - if (depth == 4) { - for (k=x*img_n; k >= 2; k-=2, ++in) { - *cur++ = scale * ((*in >> 4) ); - *cur++ = scale * ((*in ) & 0x0f); - } - if (k > 0) *cur++ = scale * ((*in >> 4) ); - } else if (depth == 2) { - for (k=x*img_n; k >= 4; k-=4, ++in) { - *cur++ = scale * ((*in >> 6) ); - *cur++ = scale * ((*in >> 4) & 0x03); - *cur++ = scale * ((*in >> 2) & 0x03); - *cur++ = scale * ((*in ) & 0x03); - } - if (k > 0) *cur++ = scale * ((*in >> 6) ); - if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); - if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); - } else if (depth == 1) { - for (k=x*img_n; k >= 8; k-=8, ++in) { - *cur++ = scale * ((*in >> 7) ); - *cur++ = scale * ((*in >> 6) & 0x01); - *cur++ = scale * ((*in >> 5) & 0x01); - *cur++ = scale * ((*in >> 4) & 0x01); - *cur++ = scale * ((*in >> 3) & 0x01); - *cur++ = scale * ((*in >> 2) & 0x01); - *cur++ = scale * ((*in >> 1) & 0x01); - *cur++ = scale * ((*in ) & 0x01); - } - if (k > 0) *cur++ = scale * ((*in >> 7) ); - if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); - if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); - if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); - if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); - if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); - if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); - } - if (img_n != out_n) { - int q; - // insert alpha = 255 - cur = a->out + stride*j; - if (img_n == 1) { - for (q=x-1; q >= 0; --q) { - cur[q*2+1] = 255; - cur[q*2+0] = cur[q]; - } - } else { - STBI_ASSERT(img_n == 3); - for (q=x-1; q >= 0; --q) { - cur[q*4+3] = 255; - cur[q*4+2] = cur[q*3+2]; - cur[q*4+1] = cur[q*3+1]; - cur[q*4+0] = cur[q*3+0]; - } - } - } - } - } - - return 1; -} - -static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) -{ - stbi_uc *final; - int p; - if (!interlaced) - return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); - - // de-interlacing - final = (stbi_uc *) stbi__malloc(a->s->img_x * a->s->img_y * out_n); - for (p=0; p < 7; ++p) { - int xorig[] = { 0,4,0,2,0,1,0 }; - int yorig[] = { 0,0,4,0,2,0,1 }; - int xspc[] = { 8,8,4,4,2,2,1 }; - int yspc[] = { 8,8,8,4,4,2,2 }; - int i,j,x,y; - // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 - x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p]; - y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p]; - if (x && y) { - stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; - if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { - STBI_FREE(final); - return 0; - } - for (j=0; j < y; ++j) { - for (i=0; i < x; ++i) { - int out_y = j*yspc[p]+yorig[p]; - int out_x = i*xspc[p]+xorig[p]; - memcpy(final + out_y*a->s->img_x*out_n + out_x*out_n, - a->out + (j*x+i)*out_n, out_n); - } - } - STBI_FREE(a->out); - image_data += img_len; - image_data_len -= img_len; - } - } - a->out = final; - - return 1; -} - -static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n) -{ - stbi__context *s = z->s; - stbi__uint32 i, pixel_count = s->img_x * s->img_y; - stbi_uc *p = z->out; - - // compute color-based transparency, assuming we've - // already got 255 as the alpha value in the output - STBI_ASSERT(out_n == 2 || out_n == 4); - - if (out_n == 2) { - for (i=0; i < pixel_count; ++i) { - p[1] = (p[0] == tc[0] ? 0 : 255); - p += 2; - } - } else { - for (i=0; i < pixel_count; ++i) { - if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) - p[3] = 0; - p += 4; - } - } - return 1; -} - -static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n) -{ - stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; - stbi_uc *p, *temp_out, *orig = a->out; - - p = (stbi_uc *) stbi__malloc(pixel_count * pal_img_n); - if (p == NULL) return stbi__err("outofmem", "Out of memory"); - - // between here and free(out) below, exitting would leak - temp_out = p; - - if (pal_img_n == 3) { - for (i=0; i < pixel_count; ++i) { - int n = orig[i]*4; - p[0] = palette[n ]; - p[1] = palette[n+1]; - p[2] = palette[n+2]; - p += 3; - } - } else { - for (i=0; i < pixel_count; ++i) { - int n = orig[i]*4; - p[0] = palette[n ]; - p[1] = palette[n+1]; - p[2] = palette[n+2]; - p[3] = palette[n+3]; - p += 4; - } - } - STBI_FREE(a->out); - a->out = temp_out; - - STBI_NOTUSED(len); - - return 1; -} - -static int stbi__unpremultiply_on_load = 0; -static int stbi__de_iphone_flag = 0; - -STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) -{ - stbi__unpremultiply_on_load = flag_true_if_should_unpremultiply; -} - -STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) -{ - stbi__de_iphone_flag = flag_true_if_should_convert; -} - -static void stbi__de_iphone(stbi__png *z) -{ - stbi__context *s = z->s; - stbi__uint32 i, pixel_count = s->img_x * s->img_y; - stbi_uc *p = z->out; - - if (s->img_out_n == 3) { // convert bgr to rgb - for (i=0; i < pixel_count; ++i) { - stbi_uc t = p[0]; - p[0] = p[2]; - p[2] = t; - p += 3; - } - } else { - STBI_ASSERT(s->img_out_n == 4); - if (stbi__unpremultiply_on_load) { - // convert bgr to rgb and unpremultiply - for (i=0; i < pixel_count; ++i) { - stbi_uc a = p[3]; - stbi_uc t = p[0]; - if (a) { - p[0] = p[2] * 255 / a; - p[1] = p[1] * 255 / a; - p[2] = t * 255 / a; - } else { - p[0] = p[2]; - p[2] = t; - } - p += 4; - } - } else { - // convert bgr to rgb - for (i=0; i < pixel_count; ++i) { - stbi_uc t = p[0]; - p[0] = p[2]; - p[2] = t; - p += 4; - } - } - } -} - -#define STBI__PNG_TYPE(a,b,c,d) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d)) - -static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) -{ - stbi_uc palette[1024], pal_img_n=0; - stbi_uc has_trans=0, tc[3]; - stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0; - int first=1,k,interlace=0, color=0, depth=0, is_iphone=0; - stbi__context *s = z->s; - - z->expanded = NULL; - z->idata = NULL; - z->out = NULL; - - if (!stbi__check_png_header(s)) return 0; - - if (scan == STBI__SCAN_type) return 1; - - for (;;) { - stbi__pngchunk c = stbi__get_chunk_header(s); - switch (c.type) { - case STBI__PNG_TYPE('C','g','B','I'): - is_iphone = 1; - stbi__skip(s, c.length); - break; - case STBI__PNG_TYPE('I','H','D','R'): { - int comp,filter; - if (!first) return stbi__err("multiple IHDR","Corrupt PNG"); - first = 0; - if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG"); - s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)"); - s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)"); - depth = stbi__get8(s); if (depth != 1 && depth != 2 && depth != 4 && depth != 8) return stbi__err("1/2/4/8-bit only","PNG not supported: 1/2/4/8-bit only"); - color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG"); - if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG"); - comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG"); - filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG"); - interlace = stbi__get8(s); if (interlace>1) return stbi__err("bad interlace method","Corrupt PNG"); - if (!s->img_x || !s->img_y) return stbi__err("0-pixel image","Corrupt PNG"); - if (!pal_img_n) { - s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); - if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); - if (scan == STBI__SCAN_header) return 1; - } else { - // if paletted, then pal_n is our final components, and - // img_n is # components to decompress/filter. - s->img_n = 1; - if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG"); - // if SCAN_header, have to scan to see if we have a tRNS - } - break; - } - - case STBI__PNG_TYPE('P','L','T','E'): { - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (c.length > 256*3) return stbi__err("invalid PLTE","Corrupt PNG"); - pal_len = c.length / 3; - if (pal_len * 3 != c.length) return stbi__err("invalid PLTE","Corrupt PNG"); - for (i=0; i < pal_len; ++i) { - palette[i*4+0] = stbi__get8(s); - palette[i*4+1] = stbi__get8(s); - palette[i*4+2] = stbi__get8(s); - palette[i*4+3] = 255; - } - break; - } - - case STBI__PNG_TYPE('t','R','N','S'): { - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (z->idata) return stbi__err("tRNS after IDAT","Corrupt PNG"); - if (pal_img_n) { - if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } - if (pal_len == 0) return stbi__err("tRNS before PLTE","Corrupt PNG"); - if (c.length > pal_len) return stbi__err("bad tRNS len","Corrupt PNG"); - pal_img_n = 4; - for (i=0; i < c.length; ++i) - palette[i*4+3] = stbi__get8(s); - } else { - if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG"); - if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG"); - has_trans = 1; - for (k=0; k < s->img_n; ++k) - tc[k] = (stbi_uc) (stbi__get16be(s) & 255) * stbi__depth_scale_table[depth]; // non 8-bit images will be larger - } - break; - } - - case STBI__PNG_TYPE('I','D','A','T'): { - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG"); - if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; } - if ((int)(ioff + c.length) < (int)ioff) return 0; - if (ioff + c.length > idata_limit) { - stbi_uc *p; - if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; - while (ioff + c.length > idata_limit) - idata_limit *= 2; - p = (stbi_uc *) STBI_REALLOC(z->idata, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); - z->idata = p; - } - if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG"); - ioff += c.length; - break; - } - - case STBI__PNG_TYPE('I','E','N','D'): { - stbi__uint32 raw_len, bpl; - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (scan != STBI__SCAN_load) return 1; - if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG"); - // initial guess for decoded data size to avoid unnecessary reallocs - bpl = (s->img_x * depth + 7) / 8; // bytes per line, per component - raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; - z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone); - if (z->expanded == NULL) return 0; // zlib should set error - STBI_FREE(z->idata); z->idata = NULL; - if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) - s->img_out_n = s->img_n+1; - else - s->img_out_n = s->img_n; - if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, depth, color, interlace)) return 0; - if (has_trans) - if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; - if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) - stbi__de_iphone(z); - if (pal_img_n) { - // pal_img_n == 3 or 4 - s->img_n = pal_img_n; // record the actual colors we had - s->img_out_n = pal_img_n; - if (req_comp >= 3) s->img_out_n = req_comp; - if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) - return 0; - } - STBI_FREE(z->expanded); z->expanded = NULL; - return 1; - } - - default: - // if critical, fail - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if ((c.type & (1 << 29)) == 0) { - #ifndef STBI_NO_FAILURE_STRINGS - // not threadsafe - static char invalid_chunk[] = "XXXX PNG chunk not known"; - invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); - invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); - invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); - invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); - #endif - return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); - } - stbi__skip(s, c.length); - break; - } - // end of PNG chunk, read and skip CRC - stbi__get32be(s); - } -} - -static unsigned char *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp) -{ - unsigned char *result=NULL; - if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); - if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { - result = p->out; - p->out = NULL; - if (req_comp && req_comp != p->s->img_out_n) { - result = stbi__convert_format(result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); - p->s->img_out_n = req_comp; - if (result == NULL) return result; - } - *x = p->s->img_x; - *y = p->s->img_y; - if (n) *n = p->s->img_out_n; - } - STBI_FREE(p->out); p->out = NULL; - STBI_FREE(p->expanded); p->expanded = NULL; - STBI_FREE(p->idata); p->idata = NULL; - - return result; -} - -static unsigned char *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) -{ - stbi__png p; - p.s = s; - return stbi__do_png(&p, x,y,comp,req_comp); -} - -static int stbi__png_test(stbi__context *s) -{ - int r; - r = stbi__check_png_header(s); - stbi__rewind(s); - return r; -} - -static int stbi__png_info_raw(stbi__png *p, int *x, int *y, int *comp) -{ - if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { - stbi__rewind( p->s ); - return 0; - } - if (x) *x = p->s->img_x; - if (y) *y = p->s->img_y; - if (comp) *comp = p->s->img_n; - return 1; -} - -static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp) -{ - stbi__png p; - p.s = s; - return stbi__png_info_raw(&p, x, y, comp); -} -#endif - -// Microsoft/Windows BMP image - -#ifndef STBI_NO_BMP -static int stbi__bmp_test_raw(stbi__context *s) -{ - int r; - int sz; - if (stbi__get8(s) != 'B') return 0; - if (stbi__get8(s) != 'M') return 0; - stbi__get32le(s); // discard filesize - stbi__get16le(s); // discard reserved - stbi__get16le(s); // discard reserved - stbi__get32le(s); // discard data offset - sz = stbi__get32le(s); - r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); - return r; -} - -static int stbi__bmp_test(stbi__context *s) -{ - int r = stbi__bmp_test_raw(s); - stbi__rewind(s); - return r; -} - - -// returns 0..31 for the highest set bit -static int stbi__high_bit(unsigned int z) -{ - int n=0; - if (z == 0) return -1; - if (z >= 0x10000) n += 16, z >>= 16; - if (z >= 0x00100) n += 8, z >>= 8; - if (z >= 0x00010) n += 4, z >>= 4; - if (z >= 0x00004) n += 2, z >>= 2; - if (z >= 0x00002) n += 1, z >>= 1; - return n; -} - -static int stbi__bitcount(unsigned int a) -{ - a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 - a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 - a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits - a = (a + (a >> 8)); // max 16 per 8 bits - a = (a + (a >> 16)); // max 32 per 8 bits - return a & 0xff; -} - -static int stbi__shiftsigned(int v, int shift, int bits) -{ - int result; - int z=0; - - if (shift < 0) v <<= -shift; - else v >>= shift; - result = v; - - z = bits; - while (z < 8) { - result += v >> z; - z += bits; - } - return result; -} - -static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) -{ - stbi_uc *out; - unsigned int mr=0,mg=0,mb=0,ma=0, all_a=255; - stbi_uc pal[256][4]; - int psize=0,i,j,compress=0,width; - int bpp, flip_vertically, pad, target, offset, hsz; - if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); - stbi__get32le(s); // discard filesize - stbi__get16le(s); // discard reserved - stbi__get16le(s); // discard reserved - offset = stbi__get32le(s); - hsz = stbi__get32le(s); - if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); - if (hsz == 12) { - s->img_x = stbi__get16le(s); - s->img_y = stbi__get16le(s); - } else { - s->img_x = stbi__get32le(s); - s->img_y = stbi__get32le(s); - } - if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); - bpp = stbi__get16le(s); - if (bpp == 1) return stbi__errpuc("monochrome", "BMP type not supported: 1-bit"); - flip_vertically = ((int) s->img_y) > 0; - s->img_y = abs((int) s->img_y); - if (hsz == 12) { - if (bpp < 24) - psize = (offset - 14 - 24) / 3; - } else { - compress = stbi__get32le(s); - if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); - stbi__get32le(s); // discard sizeof - stbi__get32le(s); // discard hres - stbi__get32le(s); // discard vres - stbi__get32le(s); // discard colorsused - stbi__get32le(s); // discard max important - if (hsz == 40 || hsz == 56) { - if (hsz == 56) { - stbi__get32le(s); - stbi__get32le(s); - stbi__get32le(s); - stbi__get32le(s); - } - if (bpp == 16 || bpp == 32) { - mr = mg = mb = 0; - if (compress == 0) { - if (bpp == 32) { - mr = 0xffu << 16; - mg = 0xffu << 8; - mb = 0xffu << 0; - ma = 0xffu << 24; - all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 - } else { - mr = 31u << 10; - mg = 31u << 5; - mb = 31u << 0; - } - } else if (compress == 3) { - mr = stbi__get32le(s); - mg = stbi__get32le(s); - mb = stbi__get32le(s); - // not documented, but generated by photoshop and handled by mspaint - if (mr == mg && mg == mb) { - // ?!?!? - return stbi__errpuc("bad BMP", "bad BMP"); - } - } else - return stbi__errpuc("bad BMP", "bad BMP"); - } - } else { - STBI_ASSERT(hsz == 108 || hsz == 124); - mr = stbi__get32le(s); - mg = stbi__get32le(s); - mb = stbi__get32le(s); - ma = stbi__get32le(s); - stbi__get32le(s); // discard color space - for (i=0; i < 12; ++i) - stbi__get32le(s); // discard color space parameters - if (hsz == 124) { - stbi__get32le(s); // discard rendering intent - stbi__get32le(s); // discard offset of profile data - stbi__get32le(s); // discard size of profile data - stbi__get32le(s); // discard reserved - } - } - if (bpp < 16) - psize = (offset - 14 - hsz) >> 2; - } - s->img_n = ma ? 4 : 3; - if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 - target = req_comp; - else - target = s->img_n; // if they want monochrome, we'll post-convert - out = (stbi_uc *) stbi__malloc(target * s->img_x * s->img_y); - if (!out) return stbi__errpuc("outofmem", "Out of memory"); - if (bpp < 16) { - int z=0; - if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } - for (i=0; i < psize; ++i) { - pal[i][2] = stbi__get8(s); - pal[i][1] = stbi__get8(s); - pal[i][0] = stbi__get8(s); - if (hsz != 12) stbi__get8(s); - pal[i][3] = 255; - } - stbi__skip(s, offset - 14 - hsz - psize * (hsz == 12 ? 3 : 4)); - if (bpp == 4) width = (s->img_x + 1) >> 1; - else if (bpp == 8) width = s->img_x; - else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } - pad = (-width)&3; - for (j=0; j < (int) s->img_y; ++j) { - for (i=0; i < (int) s->img_x; i += 2) { - int v=stbi__get8(s),v2=0; - if (bpp == 4) { - v2 = v & 15; - v >>= 4; - } - out[z++] = pal[v][0]; - out[z++] = pal[v][1]; - out[z++] = pal[v][2]; - if (target == 4) out[z++] = 255; - if (i+1 == (int) s->img_x) break; - v = (bpp == 8) ? stbi__get8(s) : v2; - out[z++] = pal[v][0]; - out[z++] = pal[v][1]; - out[z++] = pal[v][2]; - if (target == 4) out[z++] = 255; - } - stbi__skip(s, pad); - } - } else { - int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; - int z = 0; - int easy=0; - stbi__skip(s, offset - 14 - hsz); - if (bpp == 24) width = 3 * s->img_x; - else if (bpp == 16) width = 2*s->img_x; - else /* bpp = 32 and pad = 0 */ width=0; - pad = (-width) & 3; - if (bpp == 24) { - easy = 1; - } else if (bpp == 32) { - if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) - easy = 2; - } - if (!easy) { - if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } - // right shift amt to put high bit in position #7 - rshift = stbi__high_bit(mr)-7; rcount = stbi__bitcount(mr); - gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg); - bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb); - ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma); - } - for (j=0; j < (int) s->img_y; ++j) { - if (easy) { - for (i=0; i < (int) s->img_x; ++i) { - unsigned char a; - out[z+2] = stbi__get8(s); - out[z+1] = stbi__get8(s); - out[z+0] = stbi__get8(s); - z += 3; - a = (easy == 2 ? stbi__get8(s) : 255); - all_a |= a; - if (target == 4) out[z++] = a; - } - } else { - for (i=0; i < (int) s->img_x; ++i) { - stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s)); - int a; - out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); - out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); - out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); - a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); - all_a |= a; - if (target == 4) out[z++] = STBI__BYTECAST(a); - } - } - stbi__skip(s, pad); - } - } - - // if alpha channel is all 0s, replace with all 255s - if (target == 4 && all_a == 0) - for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4) - out[i] = 255; - - if (flip_vertically) { - stbi_uc t; - for (j=0; j < (int) s->img_y>>1; ++j) { - stbi_uc *p1 = out + j *s->img_x*target; - stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; - for (i=0; i < (int) s->img_x*target; ++i) { - t = p1[i], p1[i] = p2[i], p2[i] = t; - } - } - } - - if (req_comp && req_comp != target) { - out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); - if (out == NULL) return out; // stbi__convert_format frees input on failure - } - - *x = s->img_x; - *y = s->img_y; - if (comp) *comp = s->img_n; - return out; -} -#endif - -// Targa Truevision - TGA -// by Jonathan Dummer -#ifndef STBI_NO_TGA -static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) -{ - int tga_w, tga_h, tga_comp; - int sz; - stbi__get8(s); // discard Offset - sz = stbi__get8(s); // color type - if( sz > 1 ) { - stbi__rewind(s); - return 0; // only RGB or indexed allowed - } - sz = stbi__get8(s); // image type - // only RGB or grey allowed, +/- RLE - if ((sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11)) return 0; - stbi__skip(s,9); - tga_w = stbi__get16le(s); - if( tga_w < 1 ) { - stbi__rewind(s); - return 0; // test width - } - tga_h = stbi__get16le(s); - if( tga_h < 1 ) { - stbi__rewind(s); - return 0; // test height - } - sz = stbi__get8(s); // bits per pixel - // only RGB or RGBA or grey allowed - if ((sz != 8) && (sz != 16) && (sz != 24) && (sz != 32)) { - stbi__rewind(s); - return 0; - } - tga_comp = sz; - if (x) *x = tga_w; - if (y) *y = tga_h; - if (comp) *comp = tga_comp / 8; - return 1; // seems to have passed everything -} - -static int stbi__tga_test(stbi__context *s) -{ - int res; - int sz; - stbi__get8(s); // discard Offset - sz = stbi__get8(s); // color type - if ( sz > 1 ) return 0; // only RGB or indexed allowed - sz = stbi__get8(s); // image type - if ( (sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11) ) return 0; // only RGB or grey allowed, +/- RLE - stbi__get16be(s); // discard palette start - stbi__get16be(s); // discard palette length - stbi__get8(s); // discard bits per palette color entry - stbi__get16be(s); // discard x origin - stbi__get16be(s); // discard y origin - if ( stbi__get16be(s) < 1 ) return 0; // test width - if ( stbi__get16be(s) < 1 ) return 0; // test height - sz = stbi__get8(s); // bits per pixel - if ( (sz != 8) && (sz != 16) && (sz != 24) && (sz != 32) ) - res = 0; - else - res = 1; - stbi__rewind(s); - return res; -} - -static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) -{ - // read in the TGA header stuff - int tga_offset = stbi__get8(s); - int tga_indexed = stbi__get8(s); - int tga_image_type = stbi__get8(s); - int tga_is_RLE = 0; - int tga_palette_start = stbi__get16le(s); - int tga_palette_len = stbi__get16le(s); - int tga_palette_bits = stbi__get8(s); - int tga_x_origin = stbi__get16le(s); - int tga_y_origin = stbi__get16le(s); - int tga_width = stbi__get16le(s); - int tga_height = stbi__get16le(s); - int tga_bits_per_pixel = stbi__get8(s); - int tga_comp = tga_bits_per_pixel / 8; - int tga_inverted = stbi__get8(s); - // image data - unsigned char *tga_data; - unsigned char *tga_palette = NULL; - int i, j; - unsigned char raw_data[4]; - int RLE_count = 0; - int RLE_repeating = 0; - int read_next_pixel = 1; - - // do a tiny bit of precessing - if ( tga_image_type >= 8 ) - { - tga_image_type -= 8; - tga_is_RLE = 1; - } - /* int tga_alpha_bits = tga_inverted & 15; */ - tga_inverted = 1 - ((tga_inverted >> 5) & 1); - - // error check - if ( //(tga_indexed) || - (tga_width < 1) || (tga_height < 1) || - (tga_image_type < 1) || (tga_image_type > 3) || - ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16) && - (tga_bits_per_pixel != 24) && (tga_bits_per_pixel != 32)) - ) - { - return NULL; // we don't report this as a bad TGA because we don't even know if it's TGA - } - - // If I'm paletted, then I'll use the number of bits from the palette - if ( tga_indexed ) - { - tga_comp = tga_palette_bits / 8; - } - - // tga info - *x = tga_width; - *y = tga_height; - if (comp) *comp = tga_comp; - - tga_data = (unsigned char*)stbi__malloc( (size_t)tga_width * tga_height * tga_comp ); - if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); - - // skip to the data's starting position (offset usually = 0) - stbi__skip(s, tga_offset ); - - if ( !tga_indexed && !tga_is_RLE) { - for (i=0; i < tga_height; ++i) { - int row = tga_inverted ? tga_height -i - 1 : i; - stbi_uc *tga_row = tga_data + row*tga_width*tga_comp; - stbi__getn(s, tga_row, tga_width * tga_comp); - } - } else { - // do I need to load a palette? - if ( tga_indexed) - { - // any data to skip? (offset usually = 0) - stbi__skip(s, tga_palette_start ); - // load the palette - tga_palette = (unsigned char*)stbi__malloc( tga_palette_len * tga_palette_bits / 8 ); - if (!tga_palette) { - STBI_FREE(tga_data); - return stbi__errpuc("outofmem", "Out of memory"); - } - if (!stbi__getn(s, tga_palette, tga_palette_len * tga_palette_bits / 8 )) { - STBI_FREE(tga_data); - STBI_FREE(tga_palette); - return stbi__errpuc("bad palette", "Corrupt TGA"); - } - } - // load the data - for (i=0; i < tga_width * tga_height; ++i) - { - // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? - if ( tga_is_RLE ) - { - if ( RLE_count == 0 ) - { - // yep, get the next byte as a RLE command - int RLE_cmd = stbi__get8(s); - RLE_count = 1 + (RLE_cmd & 127); - RLE_repeating = RLE_cmd >> 7; - read_next_pixel = 1; - } else if ( !RLE_repeating ) - { - read_next_pixel = 1; - } - } else - { - read_next_pixel = 1; - } - // OK, if I need to read a pixel, do it now - if ( read_next_pixel ) - { - // load however much data we did have - if ( tga_indexed ) - { - // read in 1 byte, then perform the lookup - int pal_idx = stbi__get8(s); - if ( pal_idx >= tga_palette_len ) - { - // invalid index - pal_idx = 0; - } - pal_idx *= tga_bits_per_pixel / 8; - for (j = 0; j*8 < tga_bits_per_pixel; ++j) - { - raw_data[j] = tga_palette[pal_idx+j]; - } - } else - { - // read in the data raw - for (j = 0; j*8 < tga_bits_per_pixel; ++j) - { - raw_data[j] = stbi__get8(s); - } - } - // clear the reading flag for the next pixel - read_next_pixel = 0; - } // end of reading a pixel - - // copy data - for (j = 0; j < tga_comp; ++j) - tga_data[i*tga_comp+j] = raw_data[j]; - - // in case we're in RLE mode, keep counting down - --RLE_count; - } - // do I need to invert the image? - if ( tga_inverted ) - { - for (j = 0; j*2 < tga_height; ++j) - { - int index1 = j * tga_width * tga_comp; - int index2 = (tga_height - 1 - j) * tga_width * tga_comp; - for (i = tga_width * tga_comp; i > 0; --i) - { - unsigned char temp = tga_data[index1]; - tga_data[index1] = tga_data[index2]; - tga_data[index2] = temp; - ++index1; - ++index2; - } - } - } - // clear my palette, if I had one - if ( tga_palette != NULL ) - { - STBI_FREE( tga_palette ); - } - } - - // swap RGB - if (tga_comp >= 3) - { - unsigned char* tga_pixel = tga_data; - for (i=0; i < tga_width * tga_height; ++i) - { - unsigned char temp = tga_pixel[0]; - tga_pixel[0] = tga_pixel[2]; - tga_pixel[2] = temp; - tga_pixel += tga_comp; - } - } - - // convert to target component count - if (req_comp && req_comp != tga_comp) - tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); - - // the things I do to get rid of an error message, and yet keep - // Microsoft's C compilers happy... [8^( - tga_palette_start = tga_palette_len = tga_palette_bits = - tga_x_origin = tga_y_origin = 0; - // OK, done - return tga_data; -} -#endif - -// ************************************************************************************************* -// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB - -#ifndef STBI_NO_PSD -static int stbi__psd_test(stbi__context *s) -{ - int r = (stbi__get32be(s) == 0x38425053); - stbi__rewind(s); - return r; -} - -static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) -{ - int pixelCount; - int channelCount, compression; - int channel, i, count, len; - int bitdepth; - int w,h; - stbi_uc *out; - - // Check identifier - if (stbi__get32be(s) != 0x38425053) // "8BPS" - return stbi__errpuc("not PSD", "Corrupt PSD image"); - - // Check file type version. - if (stbi__get16be(s) != 1) - return stbi__errpuc("wrong version", "Unsupported version of PSD image"); - - // Skip 6 reserved bytes. - stbi__skip(s, 6 ); - - // Read the number of channels (R, G, B, A, etc). - channelCount = stbi__get16be(s); - if (channelCount < 0 || channelCount > 16) - return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); - - // Read the rows and columns of the image. - h = stbi__get32be(s); - w = stbi__get32be(s); - - // Make sure the depth is 8 bits. - bitdepth = stbi__get16be(s); - if (bitdepth != 8 && bitdepth != 16) - return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); - - // Make sure the color mode is RGB. - // Valid options are: - // 0: Bitmap - // 1: Grayscale - // 2: Indexed color - // 3: RGB color - // 4: CMYK color - // 7: Multichannel - // 8: Duotone - // 9: Lab color - if (stbi__get16be(s) != 3) - return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); - - // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) - stbi__skip(s,stbi__get32be(s) ); - - // Skip the image resources. (resolution, pen tool paths, etc) - stbi__skip(s, stbi__get32be(s) ); - - // Skip the reserved data. - stbi__skip(s, stbi__get32be(s) ); - - // Find out if the data is compressed. - // Known values: - // 0: no compression - // 1: RLE compressed - compression = stbi__get16be(s); - if (compression > 1) - return stbi__errpuc("bad compression", "PSD has an unknown compression format"); - - // Create the destination image. - out = (stbi_uc *) stbi__malloc(4 * w*h); - if (!out) return stbi__errpuc("outofmem", "Out of memory"); - pixelCount = w*h; - - // Initialize the data to zero. - //memset( out, 0, pixelCount * 4 ); - - // Finally, the image data. - if (compression) { - // RLE as used by .PSD and .TIFF - // Loop until you get the number of unpacked bytes you are expecting: - // Read the next source byte into n. - // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. - // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. - // Else if n is 128, noop. - // Endloop - - // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data, - // which we're going to just skip. - stbi__skip(s, h * channelCount * 2 ); - - // Read the RLE data by channel. - for (channel = 0; channel < 4; channel++) { - stbi_uc *p; - - p = out+channel; - if (channel >= channelCount) { - // Fill this channel with default data. - for (i = 0; i < pixelCount; i++, p += 4) - *p = (channel == 3 ? 255 : 0); - } else { - // Read the RLE data. - count = 0; - while (count < pixelCount) { - len = stbi__get8(s); - if (len == 128) { - // No-op. - } else if (len < 128) { - // Copy next len+1 bytes literally. - len++; - count += len; - while (len) { - *p = stbi__get8(s); - p += 4; - len--; - } - } else if (len > 128) { - stbi_uc val; - // Next -len+1 bytes in the dest are replicated from next source byte. - // (Interpret len as a negative 8-bit int.) - len ^= 0x0FF; - len += 2; - val = stbi__get8(s); - count += len; - while (len) { - *p = val; - p += 4; - len--; - } - } - } - } - } - - } else { - // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) - // where each channel consists of an 8-bit value for each pixel in the image. - - // Read the data by channel. - for (channel = 0; channel < 4; channel++) { - stbi_uc *p; - - p = out + channel; - if (channel >= channelCount) { - // Fill this channel with default data. - stbi_uc val = channel == 3 ? 255 : 0; - for (i = 0; i < pixelCount; i++, p += 4) - *p = val; - } else { - // Read the data. - if (bitdepth == 16) { - for (i = 0; i < pixelCount; i++, p += 4) - *p = (stbi_uc) (stbi__get16be(s) >> 8); - } else { - for (i = 0; i < pixelCount; i++, p += 4) - *p = stbi__get8(s); - } - } - } - } - - if (req_comp && req_comp != 4) { - out = stbi__convert_format(out, 4, req_comp, w, h); - if (out == NULL) return out; // stbi__convert_format frees input on failure - } - - if (comp) *comp = 4; - *y = h; - *x = w; - - return out; -} -#endif - -// ************************************************************************************************* -// Softimage PIC loader -// by Tom Seddon -// -// See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format -// See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ - -#ifndef STBI_NO_PIC -static int stbi__pic_is4(stbi__context *s,const char *str) -{ - int i; - for (i=0; i<4; ++i) - if (stbi__get8(s) != (stbi_uc)str[i]) - return 0; - - return 1; -} - -static int stbi__pic_test_core(stbi__context *s) -{ - int i; - - if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) - return 0; - - for(i=0;i<84;++i) - stbi__get8(s); - - if (!stbi__pic_is4(s,"PICT")) - return 0; - - return 1; -} - -typedef struct -{ - stbi_uc size,type,channel; -} stbi__pic_packet; - -static stbi_uc *stbi__readval(stbi__context *s, int channel, stbi_uc *dest) -{ - int mask=0x80, i; - - for (i=0; i<4; ++i, mask>>=1) { - if (channel & mask) { - if (stbi__at_eof(s)) return stbi__errpuc("bad file","PIC file too short"); - dest[i]=stbi__get8(s); - } - } - - return dest; -} - -static void stbi__copyval(int channel,stbi_uc *dest,const stbi_uc *src) -{ - int mask=0x80,i; - - for (i=0;i<4; ++i, mask>>=1) - if (channel&mask) - dest[i]=src[i]; -} - -static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *comp, stbi_uc *result) -{ - int act_comp=0,num_packets=0,y,chained; - stbi__pic_packet packets[10]; - - // this will (should...) cater for even some bizarre stuff like having data - // for the same channel in multiple packets. - do { - stbi__pic_packet *packet; - - if (num_packets==sizeof(packets)/sizeof(packets[0])) - return stbi__errpuc("bad format","too many packets"); - - packet = &packets[num_packets++]; - - chained = stbi__get8(s); - packet->size = stbi__get8(s); - packet->type = stbi__get8(s); - packet->channel = stbi__get8(s); - - act_comp |= packet->channel; - - if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (reading packets)"); - if (packet->size != 8) return stbi__errpuc("bad format","packet isn't 8bpp"); - } while (chained); - - *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? - - for(y=0; ytype) { - default: - return stbi__errpuc("bad format","packet has bad compression type"); - - case 0: {//uncompressed - int x; - - for(x=0;xchannel,dest)) - return 0; - break; - } - - case 1://Pure RLE - { - int left=width, i; - - while (left>0) { - stbi_uc count,value[4]; - - count=stbi__get8(s); - if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pure read count)"); - - if (count > left) - count = (stbi_uc) left; - - if (!stbi__readval(s,packet->channel,value)) return 0; - - for(i=0; ichannel,dest,value); - left -= count; - } - } - break; - - case 2: {//Mixed RLE - int left=width; - while (left>0) { - int count = stbi__get8(s), i; - if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (mixed read count)"); - - if (count >= 128) { // Repeated - stbi_uc value[4]; - - if (count==128) - count = stbi__get16be(s); - else - count -= 127; - if (count > left) - return stbi__errpuc("bad file","scanline overrun"); - - if (!stbi__readval(s,packet->channel,value)) - return 0; - - for(i=0;ichannel,dest,value); - } else { // Raw - ++count; - if (count>left) return stbi__errpuc("bad file","scanline overrun"); - - for(i=0;ichannel,dest)) - return 0; - } - left-=count; - } - break; - } - } - } - } - - return result; -} - -static stbi_uc *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp) -{ - stbi_uc *result; - int i, x,y; - - for (i=0; i<92; ++i) - stbi__get8(s); - - x = stbi__get16be(s); - y = stbi__get16be(s); - if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)"); - if ((1 << 28) / x < y) return stbi__errpuc("too large", "Image too large to decode"); - - stbi__get32be(s); //skip `ratio' - stbi__get16be(s); //skip `fields' - stbi__get16be(s); //skip `pad' - - // intermediate buffer is RGBA - result = (stbi_uc *) stbi__malloc(x*y*4); - memset(result, 0xff, x*y*4); - - if (!stbi__pic_load_core(s,x,y,comp, result)) { - STBI_FREE(result); - result=0; - } - *px = x; - *py = y; - if (req_comp == 0) req_comp = *comp; - result=stbi__convert_format(result,4,req_comp,x,y); - - return result; -} - -static int stbi__pic_test(stbi__context *s) -{ - int r = stbi__pic_test_core(s); - stbi__rewind(s); - return r; -} -#endif - -// ************************************************************************************************* -// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb - -#ifndef STBI_NO_GIF -typedef struct -{ - stbi__int16 prefix; - stbi_uc first; - stbi_uc suffix; -} stbi__gif_lzw; - -typedef struct -{ - int w,h; - stbi_uc *out, *old_out; // output buffer (always 4 components) - int flags, bgindex, ratio, transparent, eflags, delay; - stbi_uc pal[256][4]; - stbi_uc lpal[256][4]; - stbi__gif_lzw codes[4096]; - stbi_uc *color_table; - int parse, step; - int lflags; - int start_x, start_y; - int max_x, max_y; - int cur_x, cur_y; - int line_size; -} stbi__gif; - -static int stbi__gif_test_raw(stbi__context *s) -{ - int sz; - if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; - sz = stbi__get8(s); - if (sz != '9' && sz != '7') return 0; - if (stbi__get8(s) != 'a') return 0; - return 1; -} - -static int stbi__gif_test(stbi__context *s) -{ - int r = stbi__gif_test_raw(s); - stbi__rewind(s); - return r; -} - -static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], int num_entries, int transp) -{ - int i; - for (i=0; i < num_entries; ++i) { - pal[i][2] = stbi__get8(s); - pal[i][1] = stbi__get8(s); - pal[i][0] = stbi__get8(s); - pal[i][3] = transp == i ? 0 : 255; - } -} - -static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info) -{ - stbi_uc version; - if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') - return stbi__err("not GIF", "Corrupt GIF"); - - version = stbi__get8(s); - if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); - if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); - - stbi__g_failure_reason = ""; - g->w = stbi__get16le(s); - g->h = stbi__get16le(s); - g->flags = stbi__get8(s); - g->bgindex = stbi__get8(s); - g->ratio = stbi__get8(s); - g->transparent = -1; - - if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments - - if (is_info) return 1; - - if (g->flags & 0x80) - stbi__gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1); - - return 1; -} - -static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp) -{ - stbi__gif g; - if (!stbi__gif_header(s, &g, comp, 1)) { - stbi__rewind( s ); - return 0; - } - if (x) *x = g.w; - if (y) *y = g.h; - return 1; -} - -static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code) -{ - stbi_uc *p, *c; - - // recurse to decode the prefixes, since the linked-list is backwards, - // and working backwards through an interleaved image would be nasty - if (g->codes[code].prefix >= 0) - stbi__out_gif_code(g, g->codes[code].prefix); - - if (g->cur_y >= g->max_y) return; - - p = &g->out[g->cur_x + g->cur_y]; - c = &g->color_table[g->codes[code].suffix * 4]; - - if (c[3] >= 128) { - p[0] = c[2]; - p[1] = c[1]; - p[2] = c[0]; - p[3] = c[3]; - } - g->cur_x += 4; - - if (g->cur_x >= g->max_x) { - g->cur_x = g->start_x; - g->cur_y += g->step; - - while (g->cur_y >= g->max_y && g->parse > 0) { - g->step = (1 << g->parse) * g->line_size; - g->cur_y = g->start_y + (g->step >> 1); - --g->parse; - } - } -} - -static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g) -{ - stbi_uc lzw_cs; - stbi__int32 len, init_code; - stbi__uint32 first; - stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; - stbi__gif_lzw *p; - - lzw_cs = stbi__get8(s); - if (lzw_cs > 12) return NULL; - clear = 1 << lzw_cs; - first = 1; - codesize = lzw_cs + 1; - codemask = (1 << codesize) - 1; - bits = 0; - valid_bits = 0; - for (init_code = 0; init_code < clear; init_code++) { - g->codes[init_code].prefix = -1; - g->codes[init_code].first = (stbi_uc) init_code; - g->codes[init_code].suffix = (stbi_uc) init_code; - } - - // support no starting clear code - avail = clear+2; - oldcode = -1; - - len = 0; - for(;;) { - if (valid_bits < codesize) { - if (len == 0) { - len = stbi__get8(s); // start new block - if (len == 0) - return g->out; - } - --len; - bits |= (stbi__int32) stbi__get8(s) << valid_bits; - valid_bits += 8; - } else { - stbi__int32 code = bits & codemask; - bits >>= codesize; - valid_bits -= codesize; - // @OPTIMIZE: is there some way we can accelerate the non-clear path? - if (code == clear) { // clear code - codesize = lzw_cs + 1; - codemask = (1 << codesize) - 1; - avail = clear + 2; - oldcode = -1; - first = 0; - } else if (code == clear + 1) { // end of stream code - stbi__skip(s, len); - while ((len = stbi__get8(s)) > 0) - stbi__skip(s,len); - return g->out; - } else if (code <= avail) { - if (first) return stbi__errpuc("no clear code", "Corrupt GIF"); - - if (oldcode >= 0) { - p = &g->codes[avail++]; - if (avail > 4096) return stbi__errpuc("too many codes", "Corrupt GIF"); - p->prefix = (stbi__int16) oldcode; - p->first = g->codes[oldcode].first; - p->suffix = (code == avail) ? p->first : g->codes[code].first; - } else if (code == avail) - return stbi__errpuc("illegal code in raster", "Corrupt GIF"); - - stbi__out_gif_code(g, (stbi__uint16) code); - - if ((avail & codemask) == 0 && avail <= 0x0FFF) { - codesize++; - codemask = (1 << codesize) - 1; - } - - oldcode = code; - } else { - return stbi__errpuc("illegal code in raster", "Corrupt GIF"); - } - } - } -} - -static void stbi__fill_gif_background(stbi__gif *g, int x0, int y0, int x1, int y1) -{ - int x, y; - stbi_uc *c = g->pal[g->bgindex]; - for (y = y0; y < y1; y += 4 * g->w) { - for (x = x0; x < x1; x += 4) { - stbi_uc *p = &g->out[y + x]; - p[0] = c[2]; - p[1] = c[1]; - p[2] = c[0]; - p[3] = 0; - } - } -} - -// this function is designed to support animated gifs, although stb_image doesn't support it -static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp) -{ - int i; - stbi_uc *prev_out = 0; - - if (g->out == 0 && !stbi__gif_header(s, g, comp,0)) - return 0; // stbi__g_failure_reason set by stbi__gif_header - - prev_out = g->out; - g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h); - if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory"); - - switch ((g->eflags & 0x1C) >> 2) { - case 0: // unspecified (also always used on 1st frame) - stbi__fill_gif_background(g, 0, 0, 4 * g->w, 4 * g->w * g->h); - break; - case 1: // do not dispose - if (prev_out) memcpy(g->out, prev_out, 4 * g->w * g->h); - g->old_out = prev_out; - break; - case 2: // dispose to background - if (prev_out) memcpy(g->out, prev_out, 4 * g->w * g->h); - stbi__fill_gif_background(g, g->start_x, g->start_y, g->max_x, g->max_y); - break; - case 3: // dispose to previous - if (g->old_out) { - for (i = g->start_y; i < g->max_y; i += 4 * g->w) - memcpy(&g->out[i + g->start_x], &g->old_out[i + g->start_x], g->max_x - g->start_x); - } - break; - } - - for (;;) { - switch (stbi__get8(s)) { - case 0x2C: /* Image Descriptor */ - { - int prev_trans = -1; - stbi__int32 x, y, w, h; - stbi_uc *o; - - x = stbi__get16le(s); - y = stbi__get16le(s); - w = stbi__get16le(s); - h = stbi__get16le(s); - if (((x + w) > (g->w)) || ((y + h) > (g->h))) - return stbi__errpuc("bad Image Descriptor", "Corrupt GIF"); - - g->line_size = g->w * 4; - g->start_x = x * 4; - g->start_y = y * g->line_size; - g->max_x = g->start_x + w * 4; - g->max_y = g->start_y + h * g->line_size; - g->cur_x = g->start_x; - g->cur_y = g->start_y; - - g->lflags = stbi__get8(s); - - if (g->lflags & 0x40) { - g->step = 8 * g->line_size; // first interlaced spacing - g->parse = 3; - } else { - g->step = g->line_size; - g->parse = 0; - } - - if (g->lflags & 0x80) { - stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); - g->color_table = (stbi_uc *) g->lpal; - } else if (g->flags & 0x80) { - if (g->transparent >= 0 && (g->eflags & 0x01)) { - prev_trans = g->pal[g->transparent][3]; - g->pal[g->transparent][3] = 0; - } - g->color_table = (stbi_uc *) g->pal; - } else - return stbi__errpuc("missing color table", "Corrupt GIF"); - - o = stbi__process_gif_raster(s, g); - if (o == NULL) return NULL; - - if (prev_trans != -1) - g->pal[g->transparent][3] = (stbi_uc) prev_trans; - - return o; - } - - case 0x21: // Comment Extension. - { - int len; - if (stbi__get8(s) == 0xF9) { // Graphic Control Extension. - len = stbi__get8(s); - if (len == 4) { - g->eflags = stbi__get8(s); - g->delay = stbi__get16le(s); - g->transparent = stbi__get8(s); - } else { - stbi__skip(s, len); - break; - } - } - while ((len = stbi__get8(s)) != 0) - stbi__skip(s, len); - break; - } - - case 0x3B: // gif stream termination code - return (stbi_uc *) s; // using '1' causes warning on some compilers - - default: - return stbi__errpuc("unknown code", "Corrupt GIF"); - } - } - - STBI_NOTUSED(req_comp); -} - -static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) -{ - stbi_uc *u = 0; - stbi__gif g; - memset(&g, 0, sizeof(g)); - - u = stbi__gif_load_next(s, &g, comp, req_comp); - if (u == (stbi_uc *) s) u = 0; // end of animated gif marker - if (u) { - *x = g.w; - *y = g.h; - if (req_comp && req_comp != 4) - u = stbi__convert_format(u, 4, req_comp, g.w, g.h); - } - else if (g.out) - STBI_FREE(g.out); - - return u; -} - -static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp) -{ - return stbi__gif_info_raw(s,x,y,comp); -} -#endif - -// ************************************************************************************************* -// Radiance RGBE HDR loader -// originally by Nicolas Schulz -#ifndef STBI_NO_HDR -static int stbi__hdr_test_core(stbi__context *s) -{ - const char *signature = "#?RADIANCE\n"; - int i; - for (i=0; signature[i]; ++i) - if (stbi__get8(s) != signature[i]) - return 0; - return 1; -} - -static int stbi__hdr_test(stbi__context* s) -{ - int r = stbi__hdr_test_core(s); - stbi__rewind(s); - return r; -} - -#define STBI__HDR_BUFLEN 1024 -static char *stbi__hdr_gettoken(stbi__context *z, char *buffer) -{ - int len=0; - char c = '\0'; - - c = (char) stbi__get8(z); - - while (!stbi__at_eof(z) && c != '\n') { - buffer[len++] = c; - if (len == STBI__HDR_BUFLEN-1) { - // flush to end of line - while (!stbi__at_eof(z) && stbi__get8(z) != '\n') - ; - break; - } - c = (char) stbi__get8(z); - } - - buffer[len] = 0; - return buffer; -} - -static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp) -{ - if ( input[3] != 0 ) { - float f1; - // Exponent - f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); - if (req_comp <= 2) - output[0] = (input[0] + input[1] + input[2]) * f1 / 3; - else { - output[0] = input[0] * f1; - output[1] = input[1] * f1; - output[2] = input[2] * f1; - } - if (req_comp == 2) output[1] = 1; - if (req_comp == 4) output[3] = 1; - } else { - switch (req_comp) { - case 4: output[3] = 1; /* fallthrough */ - case 3: output[0] = output[1] = output[2] = 0; - break; - case 2: output[1] = 1; /* fallthrough */ - case 1: output[0] = 0; - break; - } - } -} - -static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) -{ - char buffer[STBI__HDR_BUFLEN]; - char *token; - int valid = 0; - int width, height; - stbi_uc *scanline; - float *hdr_data; - int len; - unsigned char count, value; - int i, j, k, c1,c2, z; - - - // Check identifier - if (strcmp(stbi__hdr_gettoken(s,buffer), "#?RADIANCE") != 0) - return stbi__errpf("not HDR", "Corrupt HDR image"); - - // Parse header - for(;;) { - token = stbi__hdr_gettoken(s,buffer); - if (token[0] == 0) break; - if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; - } - - if (!valid) return stbi__errpf("unsupported format", "Unsupported HDR format"); - - // Parse width and height - // can't use sscanf() if we're not using stdio! - token = stbi__hdr_gettoken(s,buffer); - if (strncmp(token, "-Y ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); - token += 3; - height = (int) strtol(token, &token, 10); - while (*token == ' ') ++token; - if (strncmp(token, "+X ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); - token += 3; - width = (int) strtol(token, NULL, 10); - - *x = width; - *y = height; - - if (comp) *comp = 3; - if (req_comp == 0) req_comp = 3; - - // Read data - hdr_data = (float *) stbi__malloc(height * width * req_comp * sizeof(float)); - - // Load image data - // image data is stored as some number of sca - if ( width < 8 || width >= 32768) { - // Read flat data - for (j=0; j < height; ++j) { - for (i=0; i < width; ++i) { - stbi_uc rgbe[4]; - main_decode_loop: - stbi__getn(s, rgbe, 4); - stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); - } - } - } else { - // Read RLE-encoded data - scanline = NULL; - - for (j = 0; j < height; ++j) { - c1 = stbi__get8(s); - c2 = stbi__get8(s); - len = stbi__get8(s); - if (c1 != 2 || c2 != 2 || (len & 0x80)) { - // not run-length encoded, so we have to actually use THIS data as a decoded - // pixel (note this can't be a valid pixel--one of RGB must be >= 128) - stbi_uc rgbe[4]; - rgbe[0] = (stbi_uc) c1; - rgbe[1] = (stbi_uc) c2; - rgbe[2] = (stbi_uc) len; - rgbe[3] = (stbi_uc) stbi__get8(s); - stbi__hdr_convert(hdr_data, rgbe, req_comp); - i = 1; - j = 0; - STBI_FREE(scanline); - goto main_decode_loop; // yes, this makes no sense - } - len <<= 8; - len |= stbi__get8(s); - if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } - if (scanline == NULL) scanline = (stbi_uc *) stbi__malloc(width * 4); - - for (k = 0; k < 4; ++k) { - i = 0; - while (i < width) { - count = stbi__get8(s); - if (count > 128) { - // Run - value = stbi__get8(s); - count -= 128; - for (z = 0; z < count; ++z) - scanline[i++ * 4 + k] = value; - } else { - // Dump - for (z = 0; z < count; ++z) - scanline[i++ * 4 + k] = stbi__get8(s); - } - } - } - for (i=0; i < width; ++i) - stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); - } - STBI_FREE(scanline); - } - - return hdr_data; -} - -static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp) -{ - char buffer[STBI__HDR_BUFLEN]; - char *token; - int valid = 0; - - if (strcmp(stbi__hdr_gettoken(s,buffer), "#?RADIANCE") != 0) { - stbi__rewind( s ); - return 0; - } - - for(;;) { - token = stbi__hdr_gettoken(s,buffer); - if (token[0] == 0) break; - if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; - } - - if (!valid) { - stbi__rewind( s ); - return 0; - } - token = stbi__hdr_gettoken(s,buffer); - if (strncmp(token, "-Y ", 3)) { - stbi__rewind( s ); - return 0; - } - token += 3; - *y = (int) strtol(token, &token, 10); - while (*token == ' ') ++token; - if (strncmp(token, "+X ", 3)) { - stbi__rewind( s ); - return 0; - } - token += 3; - *x = (int) strtol(token, NULL, 10); - *comp = 3; - return 1; -} -#endif // STBI_NO_HDR - -#ifndef STBI_NO_BMP -static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) -{ - int hsz; - if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') { - stbi__rewind( s ); - return 0; - } - stbi__skip(s,12); - hsz = stbi__get32le(s); - if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) { - stbi__rewind( s ); - return 0; - } - if (hsz == 12) { - *x = stbi__get16le(s); - *y = stbi__get16le(s); - } else { - *x = stbi__get32le(s); - *y = stbi__get32le(s); - } - if (stbi__get16le(s) != 1) { - stbi__rewind( s ); - return 0; - } - *comp = stbi__get16le(s) / 8; - return 1; -} -#endif - -#ifndef STBI_NO_PSD -static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) -{ - int channelCount; - if (stbi__get32be(s) != 0x38425053) { - stbi__rewind( s ); - return 0; - } - if (stbi__get16be(s) != 1) { - stbi__rewind( s ); - return 0; - } - stbi__skip(s, 6); - channelCount = stbi__get16be(s); - if (channelCount < 0 || channelCount > 16) { - stbi__rewind( s ); - return 0; - } - *y = stbi__get32be(s); - *x = stbi__get32be(s); - if (stbi__get16be(s) != 8) { - stbi__rewind( s ); - return 0; - } - if (stbi__get16be(s) != 3) { - stbi__rewind( s ); - return 0; - } - *comp = 4; - return 1; -} -#endif - -#ifndef STBI_NO_PIC -static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) -{ - int act_comp=0,num_packets=0,chained; - stbi__pic_packet packets[10]; - - if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) { - stbi__rewind(s); - return 0; - } - - stbi__skip(s, 88); - - *x = stbi__get16be(s); - *y = stbi__get16be(s); - if (stbi__at_eof(s)) { - stbi__rewind( s); - return 0; - } - if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) { - stbi__rewind( s ); - return 0; - } - - stbi__skip(s, 8); - - do { - stbi__pic_packet *packet; - - if (num_packets==sizeof(packets)/sizeof(packets[0])) - return 0; - - packet = &packets[num_packets++]; - chained = stbi__get8(s); - packet->size = stbi__get8(s); - packet->type = stbi__get8(s); - packet->channel = stbi__get8(s); - act_comp |= packet->channel; - - if (stbi__at_eof(s)) { - stbi__rewind( s ); - return 0; - } - if (packet->size != 8) { - stbi__rewind( s ); - return 0; - } - } while (chained); - - *comp = (act_comp & 0x10 ? 4 : 3); - - return 1; -} -#endif - -// ************************************************************************************************* -// Portable Gray Map and Portable Pixel Map loader -// by Ken Miller -// -// PGM: http://netpbm.sourceforge.net/doc/pgm.html -// PPM: http://netpbm.sourceforge.net/doc/ppm.html -// -// Known limitations: -// Does not support comments in the header section -// Does not support ASCII image data (formats P2 and P3) -// Does not support 16-bit-per-channel - -#ifndef STBI_NO_PNM - -static int stbi__pnm_test(stbi__context *s) -{ - char p, t; - p = (char) stbi__get8(s); - t = (char) stbi__get8(s); - if (p != 'P' || (t != '5' && t != '6')) { - stbi__rewind( s ); - return 0; - } - return 1; -} - -static stbi_uc *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) -{ - stbi_uc *out; - if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n)) - return 0; - *x = s->img_x; - *y = s->img_y; - *comp = s->img_n; - - out = (stbi_uc *) stbi__malloc(s->img_n * s->img_x * s->img_y); - if (!out) return stbi__errpuc("outofmem", "Out of memory"); - stbi__getn(s, out, s->img_n * s->img_x * s->img_y); - - if (req_comp && req_comp != s->img_n) { - out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); - if (out == NULL) return out; // stbi__convert_format frees input on failure - } - return out; -} - -static int stbi__pnm_isspace(char c) -{ - return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; -} - -static void stbi__pnm_skip_whitespace(stbi__context *s, char *c) -{ - while (!stbi__at_eof(s) && stbi__pnm_isspace(*c)) - *c = (char) stbi__get8(s); -} - -static int stbi__pnm_isdigit(char c) -{ - return c >= '0' && c <= '9'; -} - -static int stbi__pnm_getinteger(stbi__context *s, char *c) -{ - int value = 0; - - while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) { - value = value*10 + (*c - '0'); - *c = (char) stbi__get8(s); - } - - return value; -} - -static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) -{ - int maxv; - char c, p, t; - - stbi__rewind( s ); - - // Get identifier - p = (char) stbi__get8(s); - t = (char) stbi__get8(s); - if (p != 'P' || (t != '5' && t != '6')) { - stbi__rewind( s ); - return 0; - } - - *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm - - c = (char) stbi__get8(s); - stbi__pnm_skip_whitespace(s, &c); - - *x = stbi__pnm_getinteger(s, &c); // read width - stbi__pnm_skip_whitespace(s, &c); - - *y = stbi__pnm_getinteger(s, &c); // read height - stbi__pnm_skip_whitespace(s, &c); - - maxv = stbi__pnm_getinteger(s, &c); // read max value - - if (maxv > 255) - return stbi__err("max value > 255", "PPM image not 8-bit"); - else - return 1; -} -#endif - -static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp) -{ - #ifndef STBI_NO_JPEG - if (stbi__jpeg_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_PNG - if (stbi__png_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_GIF - if (stbi__gif_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_BMP - if (stbi__bmp_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_PSD - if (stbi__psd_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_PIC - if (stbi__pic_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_PNM - if (stbi__pnm_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_HDR - if (stbi__hdr_info(s, x, y, comp)) return 1; - #endif - - // test tga last because it's a crappy test! - #ifndef STBI_NO_TGA - if (stbi__tga_info(s, x, y, comp)) - return 1; - #endif - return stbi__err("unknown image type", "Image not of any known type, or corrupt"); -} - -#ifndef STBI_NO_STDIO -STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp) -{ - FILE *f = stbi__fopen(filename, "rb"); - int result; - if (!f) return stbi__err("can't fopen", "Unable to open file"); - result = stbi_info_from_file(f, x, y, comp); - fclose(f); - return result; -} - -STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) -{ - int r; - stbi__context s; - long pos = ftell(f); - stbi__start_file(&s, f); - r = stbi__info_main(&s,x,y,comp); - fseek(f,pos,SEEK_SET); - return r; -} -#endif // !STBI_NO_STDIO - -STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) -{ - stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__info_main(&s,x,y,comp); -} - -STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp) -{ - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); - return stbi__info_main(&s,x,y,comp); -} - -#endif // STB_IMAGE_IMPLEMENTATION - -/* - revision history: - 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA - 2.07 (2015-09-13) fix compiler warnings - partial animated GIF support - limited 16-bit PSD support - #ifdef unused functions - bug with < 92 byte PIC,PNM,HDR,TGA - 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value - 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning - 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit - 2.03 (2015-04-12) extra corruption checking (mmozeiko) - stbi_set_flip_vertically_on_load (nguillemot) - fix NEON support; fix mingw support - 2.02 (2015-01-19) fix incorrect assert, fix warning - 2.01 (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2 - 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG - 2.00 (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg) - progressive JPEG (stb) - PGM/PPM support (Ken Miller) - STBI_MALLOC,STBI_REALLOC,STBI_FREE - GIF bugfix -- seemingly never worked - STBI_NO_*, STBI_ONLY_* - 1.48 (2014-12-14) fix incorrectly-named assert() - 1.47 (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb) - optimize PNG (ryg) - fix bug in interlaced PNG with user-specified channel count (stb) - 1.46 (2014-08-26) - fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG - 1.45 (2014-08-16) - fix MSVC-ARM internal compiler error by wrapping malloc - 1.44 (2014-08-07) - various warning fixes from Ronny Chevalier - 1.43 (2014-07-15) - fix MSVC-only compiler problem in code changed in 1.42 - 1.42 (2014-07-09) - don't define _CRT_SECURE_NO_WARNINGS (affects user code) - fixes to stbi__cleanup_jpeg path - added STBI_ASSERT to avoid requiring assert.h - 1.41 (2014-06-25) - fix search&replace from 1.36 that messed up comments/error messages - 1.40 (2014-06-22) - fix gcc struct-initialization warning - 1.39 (2014-06-15) - fix to TGA optimization when req_comp != number of components in TGA; - fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite) - add support for BMP version 5 (more ignored fields) - 1.38 (2014-06-06) - suppress MSVC warnings on integer casts truncating values - fix accidental rename of 'skip' field of I/O - 1.37 (2014-06-04) - remove duplicate typedef - 1.36 (2014-06-03) - convert to header file single-file library - if de-iphone isn't set, load iphone images color-swapped instead of returning NULL - 1.35 (2014-05-27) - various warnings - fix broken STBI_SIMD path - fix bug where stbi_load_from_file no longer left file pointer in correct place - fix broken non-easy path for 32-bit BMP (possibly never used) - TGA optimization by Arseny Kapoulkine - 1.34 (unknown) - use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case - 1.33 (2011-07-14) - make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements - 1.32 (2011-07-13) - support for "info" function for all supported filetypes (SpartanJ) - 1.31 (2011-06-20) - a few more leak fixes, bug in PNG handling (SpartanJ) - 1.30 (2011-06-11) - added ability to load files via callbacks to accomidate custom input streams (Ben Wenger) - removed deprecated format-specific test/load functions - removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway - error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) - fix inefficiency in decoding 32-bit BMP (David Woo) - 1.29 (2010-08-16) - various warning fixes from Aurelien Pocheville - 1.28 (2010-08-01) - fix bug in GIF palette transparency (SpartanJ) - 1.27 (2010-08-01) - cast-to-stbi_uc to fix warnings - 1.26 (2010-07-24) - fix bug in file buffering for PNG reported by SpartanJ - 1.25 (2010-07-17) - refix trans_data warning (Won Chun) - 1.24 (2010-07-12) - perf improvements reading from files on platforms with lock-heavy fgetc() - minor perf improvements for jpeg - deprecated type-specific functions so we'll get feedback if they're needed - attempt to fix trans_data warning (Won Chun) - 1.23 fixed bug in iPhone support - 1.22 (2010-07-10) - removed image *writing* support - stbi_info support from Jetro Lauha - GIF support from Jean-Marc Lienher - iPhone PNG-extensions from James Brown - warning-fixes from Nicolas Schulz and Janez Zemva (i.stbi__err. Janez (U+017D)emva) - 1.21 fix use of 'stbi_uc' in header (reported by jon blow) - 1.20 added support for Softimage PIC, by Tom Seddon - 1.19 bug in interlaced PNG corruption check (found by ryg) - 1.18 (2008-08-02) - fix a threading bug (local mutable static) - 1.17 support interlaced PNG - 1.16 major bugfix - stbi__convert_format converted one too many pixels - 1.15 initialize some fields for thread safety - 1.14 fix threadsafe conversion bug - header-file-only version (#define STBI_HEADER_FILE_ONLY before including) - 1.13 threadsafe - 1.12 const qualifiers in the API - 1.11 Support installable IDCT, colorspace conversion routines - 1.10 Fixes for 64-bit (don't use "unsigned long") - optimized upsampling by Fabian "ryg" Giesen - 1.09 Fix format-conversion for PSD code (bad global variables!) - 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz - 1.07 attempt to fix C++ warning/errors again - 1.06 attempt to fix C++ warning/errors again - 1.05 fix TGA loading to return correct *comp and use good luminance calc - 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free - 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR - 1.02 support for (subset of) HDR files, float interface for preferred access to them - 1.01 fix bug: possible bug in handling right-side up bmps... not sure - fix bug: the stbi__bmp_load() and stbi__tga_load() functions didn't work at all - 1.00 interface to zlib that skips zlib header - 0.99 correct handling of alpha in palette - 0.98 TGA loader by lonesock; dynamically add loaders (untested) - 0.97 jpeg errors on too large a file; also catch another malloc failure - 0.96 fix detection of invalid v value - particleman@mollyrocket forum - 0.95 during header scan, seek to markers in case of padding - 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same - 0.93 handle jpegtran output; verbose errors - 0.92 read 4,8,16,24,32-bit BMP files of several formats - 0.91 output 24-bit Windows 3.0 BMP files - 0.90 fix a few more warnings; bump version number to approach 1.0 - 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd - 0.60 fix compiling as c++ - 0.59 fix warnings: merge Dave Moore's -Wall fixes - 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian - 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available - 0.56 fix bug: zlib uncompressed mode len vs. nlen - 0.55 fix bug: restart_interval not initialized to 0 - 0.54 allow NULL for 'int *comp' - 0.53 fix bug in png 3->4; speedup png decoding - 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments - 0.51 obey req_comp requests, 1-component jpegs return as 1-component, - on 'test' only check type, not whether we support this variant - 0.50 (2006-11-19) - first released version -*/ diff --git a/deps/nuklear/extra_font/Cousine-Regular.ttf b/deps/nuklear/extra_font/Cousine-Regular.ttf deleted file mode 100644 index 70a0bf902e1482724d7706f7a0f40d94fe51f4c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43912 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 VEBwqml;Z2NCo|~pwK diff --git a/deps/nuklear/extra_font/DroidSans.ttf b/deps/nuklear/extra_font/DroidSans.ttf deleted file mode 100644 index 767c63ad000e3eea20f3cb7a43ba9f4154ed7a5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 190044 zcmeFaX<$@Uwl=)?IaR0Ts#9|n2}vcDk%S~91QLd%2uTQGp2H9bn1q>t0TC5J5fK~_ z1Vuy|(MF}AKpRnUpl!to(6+sOZ`-z{yKS%CinQ(22$k92#39~wDvLfsn=K8vzyGGp?sV7OH;@L}2Ie)u{vB}pm zX4rMrHOoWgH&%>fY@QWmF0?M4ySV+maFnr`0p#oF&Td}{It=K~gZkFFi&nM%YRhZm z7+abLV+W;g%+HFGK2B6|AG!vpIC6Y}_S+-J;Ny!_hV z{H`FIF$wM4b&J}rntkv2T=c)di2jttv#(vM^pe)2{QW2&S~7ca%P*(iGnq-jBF2CJygb2HWwLYtp4;vM#xJ%4$8mSfP@EQn^2j_)WD z=hu?%kiXw}@qN=Y;~YFtm?R#HI)=ruo{X8Azuy?!W11#fif7VEUQ18po7ryWW7jb~ zYO1V|O+&A#yqw9%m30sBdyr$)@6e+=o}!)QcUUX`66Gw4A{%v*q&vf;FCr{79nI!Y z+kJ*i7|QUV^P-X(^RQbCi}{~Jj6Y0yx_bQ)oI*^}on*(w6G%d$J)3Qj`?K}>JXWHc z$F5g)uvYypwwRx0>!o>YJodqOJ|253hFK|X!Lv-ZMY_N|cs2+7VeC!Vsf-`{I_%4^ zPs6@|c2Pc)RpPoevCH#VrgD}o)_n--zGEkJ@3GbTRXCTk6Y^PhLcbpOJJ|{82>Q$G ztkdn$o-5xV?|tm&*lHc}^=ENDih9{>9(Ip@8#}6lrW#zJuL*7U$37NqEM|K_vmfUY zT@}lf>pL&#cJYn6N;Xp$We4P^L30#)9a|>tVLf%3EK_%c9gtjXx8&+PCVwZc4;b>; z0eY_6CCVS5I&vS>-^r$d)->epmEUJf{~h{gEG&P@%s}3F>3!lO{}gB9b8CY4xITux z8vFIwdr}$s&ukTFD^d2bX6Z3jEq@&6KX^~ibgc8dyjYZPMSdUbsbVb0*#Z4v&=2|W zy)2C9mC{L8h58fqAG1pA`Pfsz`)a{=;{6r7@@{90WI=N1zGG|^LKa7u6XytIRhWHHewd<486jPu`dF2ebbLIy5Y9X}t?bwD>Vp`*YE@{b9eKvzj$2}j`B zlkszF{H#5175P0;=Npov==;iZZD(g!9^nl<7P#wnHl(uE1{yywNH~a}o8srI373S8 ze{=R=ENO(@?q@yW81nnyo(b;)bHKZha~$`CJ;HzYvosQP&SP&SWKTLzdKVvCdl#*{ zxCC5Dx)nSL=QOefI4|bc3%ntZeT4h(uzPeLc795@)4kF8iQ@14L_UmjRp%%Ai8$AH zej@Ga{EO%hwvOZg8J>`=bE7thF+ZGg={Ino)Ozw=8S?1(N5 zK2ko(+RTDD?-lp3lk)w{MQuVh%XED@KhuB4_9}{K!z=nCEFzzt(HQl+nMaJ7>S?TmOB!#SU+{%?YD-zqbh;U=4tn_p?Nmn(|0(zt=cA}k zb+!IHI<%SKm3{}x*RjV8=h+F`VJ|((Hk76E$Jsz*Pn?fpykr~hW-D|X!Lt(Zqlx7b z&h@V_oqPcH^HV&-j&U8(&19YMD5@GqJ#I!icL)-hH27-gvpXb^IR+=$OqCxM46 z&!iusEMwyl)rg&ZA#Y`V+R4Y`9F#u6HFo(XRtbM}J#^!GSz_CiHns(EO)JF*6gNnt zAxrG?H}E;;*ly`N;qxgTs8$%;hI6F?e}J*CG<*Vn$6y1YtGcgPt72ypu$N#TgMFFq zF~k$MgCFGot*jn(TXoGSzmKhygG?3o-C_vc6Nn$4hR>vZ7dtKNALAQzjJIK54gZ&k z-HLr+{JIcl@|S6#hf!3QI7^5=F?Pl$;n_S~XX1JX9-PD;Pbfc;cIth08xP&v z&0M5^A~uNo6QwHlp7aE3hb*=jCbOQj6OKXiGW}QZiG^%0V;Amb>|!0xwK#*6i+u!M zNUur$&@aOWY&Ce!^qIi?hs20nfX{v>FFJtUk7-A3%y zb$$=mgIQSF2;V?@1>Eb7u^r+J4B~u3hjx{fY_Ps3^e}!V`$Tqzu&%F1ncnDg0oqyy zobLopkc<8;oH6D^TLuMkfqkXA3BQs!C;SV^R@jicL3)Em`Rv3wK$(L9f@7987no_>z*mepStKaXk-l?nD`HuV8`IYPJRn zycUbAm!%+R>EUw)132YSdjT)kd9p2B$5o5diPk*aY0gHM$yp+C4=CY5Bug-zk|o`X zl;!q0Me-%ntrf{zKv!Oiw*bj!@ntz_^CW8<^~Jr3&4SiwL!E-4HL-d9UaQw^_E^Q1 z;jsn_XbS`j(!I3x%JI2qOX?NhEJ@g?jl`x}vV2)Ck%}x?PVP(hCiUVxgT_E9%j4~B z_1e6?tn{FtyS(W^Z!kINO!vA&Nm)TPm>$fs_zHY3i`D1#`3n3#b8lB5;0?F~0qzRA z-2tD=>k4pt(32DldUJwyZxL9L9!%u{7apj|pwjJ0DhjGzPcZ0LgT4%((-ZXgyulv9 zpxNgRdR>;}pf5-=2>Js-XVB>_@Fe#F{{n#mv(M#+9B9k(5xriLt(UkT^yCGCK`Reh zEKUpOy@KhSn4aZNfqwY?#NMFCg8~q{mZ(1G1=@*otJmoZBnQA0&OM%Vj9beA2YUKL zS)3;a0zS~>;XQ)xbZ@|ijeER7-ZS7ywh;#lxG%{4Zi@>~gF#mhNHgd)TLPd9Vsg1X z$w|R1Y{6hJuiNK=l9_#GA5<+A2%t(J=y72zq!iqTks$@pipz-#K~2CuXOWLK)b*$V zm&eD|9&U@@i!OZrKsHEq`&~WMxN2z%*8P}Juf&-YOKbUuN1=MjkiOWUHrT+}OGyM3 zZeZ~i#h_!dge4tWuj7&=(>0EXq+RQENV2TM(vOUCi90 ztq~N~Q~Oj435{`4lgd%jqqNq&b{~IEB}LNe5qX#AC+g#@ZOEpUwAB46)zy+Vk~nol zVZ4iY%R0SYC()K@MH@yUm(CisA|KhC+%WaV`n*%aUTi1xA6g7=f&y1wE4JPP9OyA!%Pq7>`8KXZ1TjPq20}Dx(4u3!SfVt9 z5N|Dh7Bv&Obk>wh6av~vdV&EUP{*lvr~px~pk-1N8VBi^HXbFeNhnN-xFN1+gw!PR zH4H)#sDNZJ#M>Y_Q6p$8(Ue|qG!pX+R1(FBPhA)k$P^d_2B{|v(NvC9oe~}!3^HL* zQxC-`tR_bh>dZjBQD>sRxG6v#!N0gd8FU6<5JnXkG#GFN`f0Edy1+?OIGhEWNYBY= z(2%rjz0QOiK?^z+^dOHCZiOi5N(ff3GZ4wdB$053c145K0$plb{E~(z@~KW&CR&fz zCv3)hKzo8}^gt#7RK|NuG}-;E_1^6$l&X7)pSq6M5oRflL8Dn8$DjeW42*>U;`C8z zP2oWkNdUw`rHmLVXvCcn{Rj+d{Xy_3E*VK;f@MPL7_HU_SYSZQvO$a=W$>6x4=Efa zl8KgJhbU>!HQ6IW=$ODDb$}#PgStjZY#I^T(?m<4GO-cO0!efv3{rPp4`@i(;wL?H zUO0iSc1Y-CAiFjr4NmJ)LKg-S8uKf#NZGrM56uB19zgBUBTOVgsof7^yOK zkIg`xU=zb6zQ?zCi^M88;W*m#1`HOXF_=WFs3|0%wRHJ0PQaxTG%3;czdy$*7c8Lz z+a2I%_MAAYMb#XAF4gojbTH-Oz+Muaf+UV|5>dugE zkfTTp6loYF=d3lN2w@uZCQ|5bo5r~AZ3)%XiV)h2#)Q8B2dH-iF`eFMFrsCm2O&S< z217!xG%5q=B*0Q4Zip*_4)sa}=z%sA;KF3WrCl&OeT6vo{cbQ5s?{3Ge)q(WHg`yf-&`P5W0a&*fG%@RYBJ# zz!tIr22Cc4Kv4xm$~qG~TpWW$3fh965&mc=PEfX@x1t!BMXEuGhAR@$Ab>@8M1Ugb zp>YUIpb}cbQ(;Uc$j#Sz@Wwm(SuNUvV|moAH^Wq5TaN7ksySC zNit#>q*6lP(VRjsl7)H`gW?#3Hj1S2on-p|4TD{Viu&zJ-5JmggBnfo2T)9{7&Js< z;s0w4LQ}y28V9CEVmMtGq^7UHAT;KGi9u2+fk9kQ!fiJUV#p*KvzZLInZ`_9$1Zq} zy95SF%}6d_?vG*6Z0?3ZleHTLjd~NbT*Dw~dlv?UjUZtm>CJjGf?Nf@kTJ8l3xmcV zV9<;<;A9jNAZjL>5*Wmd*@#?C7tCf1l%xnXxg3KA#Z34`r$XHSBL*QzA<`=`h}vK! zZ6E@Kh^qt!jU-KyX9CcPvX{=p;_m7H2!j^8fgxsqfi@Z8)1X6IfG8x6JDN1WGQeGd z9VkJ(G7%p!d=vbY7NU`I5dR2+W~xd?NBBv)5RH%`nxGRpGU)RJaxR7Q9-ZR zpw)qmWHeENX&!7owPg~14^j{cOm`NG5lFETr!bij7)3eJUL2$3 zl|UfD6Z`|M=nb>9yAh+AhyUq*unyoeMF#y~^CjuPb5kd4i5p^lI%WDI&V5dsBJ0x(Py zE_Bdju$VDcaEw?1r2zfZ0BAJGLMEa;LO2*qa?wVic{Wi}j4Iv{3PT~`6{szgG(+pq zrUk`8CH4Cgn<(DxK&qvw&JT~&D>->>(^|ww#_#!Ga@+fIviWR1A=vOi!V`Fd_nNP-W2w6*21&gMsy^h5BOI2I7rlkZhzT zRt zf}kxL2D=&(h)l4N&K5*Z8oU&u$BcX80k~j*3W_r!?GgqtVw8cJAmOZK5T_|VC5GV) ztfCPOqm)JRBo@mSYF=Pas2eB+?BY!c3_?OyY8kpoRdA#`*gd)v7=>0+HX$0Lqu%t; zdTe-TwRXp#1Cb4u&p?3LU{-95Hc$hD^CgK<(NnjA7A#rFJB#(_=KrbfZ z0)vDcn0T^9Wb|oTAcmqCEfkYM0bs|_AiS?09>**~9cYpmF*$gX2~Qy+SS2BQjS-hH zNF5+SDUdE18M?wIY2uZ^DQLVXof{K>qv9KEHg$7$wJ0R7@C=;bXdy}10d@r@Tc7( zC^K6q%Yu>+nqI~yuwWRTP*+eWBlHzb;TDq@lg$PfVzf~vL`R+xiig7RAW*wFMiqd9 zT%^Dt8B}1R+3^s#JU{FRZYO~1_ z@dM&C69!S+Boqz`W3*uyR-4iL5*76UJqF0DZ+XUT;W|oLAkcZs~48rWez?gwSCi;1+Ts|bjwuP_)t$XI8l2XT4uZE@$%GI|SR$m8NoPcaX0p(#1Vm}J=#3_5 z7G#Wa=)wY4fL|zyGhvWggCoYR@<=!pem?F8EO;d zae_<59h?!UBSQ)Vfq$?t)EitJZ5W5$PS7OJ2D4&y(#IGE2~AmH1?+I~LK@H^&>(b! z21<5SgP`7EH`uYhg(wLawA-=Z3T-COrdMn>j5UrykYoc)$gu*0CL5@L4G?2;IxNUT zSlHZA3S?-{l9vcZbWw z2s*I+7R&~~TTI{t1H?hYAZ($Dl)!@E8D@eS!_Z82@CFkm;d($X0a#!VfP$d{htXMg z3}OwIFbLvdZH;DuL5P>EA(9QP0q;l}1Th#*_To9@N0LVmI-18&5{?0k60D`5MBB*R zP)RK%a6_y?&>7!AEJo4|gBs_^x(HU;>{?h)?4qP0QY)k#?GRR6k~&Bhx`y_MCY=eZ znDFE}lNG9F#f*sXfKi&vq>p5)sS}GrU;%uIXkd>ph_Psh1+c8hA`GAuVm`YA1|NYE zwS|YM4=D&AfJ?L84k(#aVhBWM5p+?kN+YB@AQ;qI(J?Sa7=-bJ3SkyT8^+;qBrpgX ztS$&KfkCSgIxjG20v6G@&i zCL9@XXg1k342luER0}Za!15@lHklltiuyn(1+`3I0rNCKONAo@=fnnO6q-rSb{&x$>+j*QFyVme%r* z9J_j@yg23EF{paX8V2FyfkE&V7^LxQ391Sv*%4BJgHRmkzg;5`CJ7ic0fR(6u?|`T z$m;A=6Br~F!U&7l>{3E>EpM?y$INr)c85FsfTB*Y>x zNIfJHbWIy}f=yze=uF!*nP{v}Ado(fA|wORVna+wGPIg3_!FDmfj|d6%CuIh4P%Rr}(}!|8 zI~h+XxE%%`NH7{z6_XC(2ML27`WOQrs=!s5Y(~;~`qmoyM+X>&mMF*;!h*bvs!;_7 z5!e8Os!AWFScxIFI0nr^;eZnp8Z&`%;Lie}0YW&F+}ut)v#G$X5Vi_5Qo_W?h<0dF z0(zl?Cac8>bVE}#3<7H83DFg-5Nt|9LO{5PLNIg++o@A?zB_?IfCSyytv`uD2kL?=Rx2j3 zMhBPxRw5d5K!XGZg@J~E1qK~7o1^d@vFha*G}{S-V7<2ZBrs^R*(e@GvJ3VT24O@g z!7>Wji|5@ji0&w9;DiL}3L9NvgY${kATe5D3B*Q*vda%z5SJ1+x-f{&uvu^r@fmcU z7W>59Qt(C83?uk=tHJhj^3?NJ9a9S~)Q z!U2w)r?_LSZIRNgI{x4(G(g6BJn+3K+^1@ zjsOuWwInLi20CwmLAV|>({ zmP}5Q6CWL8wE!4&I(1-x&EWv~ia`agtQrO}8j}-rk}q^1=ySpn*sTO8v(e+Sfjdr^ zVGPM^cB*zEVp=SvxKINs>7dQxf|C@8p|A%tM+D^(`gF#|x zK+G58PejbxWndB>&q_1vu9O%$(TpXE_-4U}X#@uPbQw#BaL&lahCd-9cosx)}1O`EZ0|r#6CVf;!om+GkJ5SyH5j~(BGzJ(1!N^4>A`F@o z!;?bKNim?eHtd^ zagm=+V9;f9;oBOJGcf3K>1FT(9E8a=I6=4#|HzL7##&r}2{~33XF{C7AjtN)ZDyz4 zg%FemVRkuD27QnxqPZa+g40 zHfn_e)P#VkBif)U26D)RHZaPmBH(a2+$1SrpC;Wuz7dt(6Dbz;^P?N}3X`dAq&DEb zU~D8ga#oATdIfPRTcM; zB6JhzL$U&c&=3dK{UJsS1ravtfOn`yXJE1mgJ2%qBG5^`2F*ZcgbL9-&kC04oh|?l zdP^f!sS)@L9MLqIA`Gfl{4)qz#wv&X5(Y6sC_en84PHrL5N0QVL9@{bgD=M6c4I{w zpF4>;sl!j-$%tdnVRmDVM1ny7AU%#jxG|V(AuPzt>^8f*Fz9v@232qnCfDe45rIPC zFlvh%Gc7n7i_>AZxt+iuVH=yzV~2x7E`WyQ1{x{R;td!}Sb&8B0)aIT@JrEw*f2XJ zz|nJHPzBP!I^0q(ieQ#1xGh?t02P}MFrs@QMjjMrRk?Hikr-0?<31h!qg5g9TQsJJRTE4)D#1 z*#?noQ^6fXVk&OQTL+32T*ZH!f_D0(Awq z1PsE1QFjhFZ@1f~T5Vox8RpOdn+9wm57P(8z-o0uWDp{(J_1ut3SkicrAC&_faNjKmYFbU zHDLOUkCP!%1ijrcNT!~`C!^6$GN)d|k+hVO3px)Ifh1Z>96&>yMe#sDV33N6l)xYv zN^NC@jue-YMe4#JWjm~P?SzqeFqy-qfegM$e7=#$r8D#eJ!=@WLaAJ|mPRxsFsRs6 zSYKd}47J4pWY{2Cj0(broCqlK^VCL z7d2vs6fh;ErW|&U$BvZ>FLeZUb)YpfC`1CNF%{G>i1{K=Zx$GILFJ&}ZfHG?!{YT~ zCNGx2VKrSr@`J!2g(gl5blyf55&aWILN^E}WSlh!8Z7vyPJG|XiZ78e=Jo1zHmlR6 zVbBfVrp7S{QarHc2qtM#XY)W2RII)bAA9&zU=q0i8j{z8?vN;Y1k>OF2{Cq?17^(U zf@ubsR1KaB4cS2%Ids?*ayUYeu#o~mE{vMENUe~{CN^*m_2EImGAA%dx(qHzEdKaN4SjmA%kgoRu; z=GlnpVcy(e6V|5?{y`hyW-K;1QpH2w3t9_12t!5gL;#s=xC<~fVC?`H1gPO~jhL&b zaX;u5>?aIjGC|3z3Jj9@r{ogLb0Suy9?1MrA_PKp1qlL$WNfq=bR+?Y4NtX?W$9=G zO~iJw@B-tZXgtD{T-!WeF@28*EHGWd4^qpCO<<5T1F<4HcSAE^sX>Ke(+Rp1n-kX8 zX@H7=9EXZe2vA3**$i}BRe?!Fc47bs@oexq)PRVl;MK5Fi7a>^XaO+j@xtEYkL(Kq zPt}IF4NYO_syZ=Z)Nu;hTsD`JFo;zf#20{y9WECGus~Wg8HE2) zDT_#_4-XVC`~>8Pj-XC9n%{Y_et=t>%cc?rF>4Fpjuu{3EmlQgihFPe45|n+fI&M= zJQW~X%h6G-r4=#AMNLhG}Zaxk<kP#&if9~D}?m}i5Pz@ZmqfI%n?EoLBg0|u>%kC1@{2eR0R z&!83>2J!U+4;0UcwF6)fpe78G`=>b}lE5x~h-Ff>w?#lvN%oMpNFEp}kcUJaAZbfC zV2oz@Gz0>J7_wG_j$JGP`>_BT-yHa|4nZ5_VuPoqA-U|Tc5>OhK5c5P2?|FMnFFppZc0fP5UVbFz8CxFQj z$pihq!cvvjxWHtXFfJf$*aeab&l{*^i^ zWC?jgDWUXGR;Vac5*iR16siub3GEI2JhVSepXN^UrKP83r4^*jOqbG?bVs@?y+?XV zdR}^6dQ*B!=9}N^Vx65AJ3B#Hi0uYNyZJ#-bY2R8qSrvte}W?V=u@NU7EpAT{D}N6 zC}KLhZmh0Jcbo3s6qZtvvNmOR%9o&sh1?;3C?qH<4wc6#dIS_bc^O61;}ki&QPd2I zI4HW%+1dH$&R=y#*-Pv&o839Qvrp%?*!tKlv1>Z#bzapur?ZjG?X14|&c)LgPhC72 zyE(Q7?+?Qp%VL-t#7uu__)Fl=*ZpNRV}G{&sjB0PjVW^fNuq1kbq6IL^o)ee%&eAD#Tee28?6G(nRl zN%Vi6notsN2xeQm)xi5L|4q8<-{f7&TBKb{^Y~8w5Z}cghRlA(_wYyfUj8V5jQ?Dk zFD>AIMNB>jnYh}Na8a%sI<`POT^$F6~(=F?3Q)KrB+kMOSbet zfB`R{Gchx>Fe|e$J97XNPUd26=3!pEAK1?VEXaDWB$mv2vJ{pI{Y+!&EX*=kCd*>k zc<*m6>&5a|KI_d2@E+kJyx*yqm9W07l=Wl%Ss5#51K2<|hz({Htdd385LU&8vT9bt zYS}PW$A+_dHiC_0qu6LRhK*(8*myR9O=OeUWHyC0u&H=A@pLwWHL{s(7HeX&F``@9 z2DXvi&bF}o*)H}7+k-dRJ;okoKWC4#C)pEhKl=qc$PTb5JH(!1zhqCdBkU-9h8<(i zvlrNll8s%>npq2*FFBwcKVwVTLMg*llcw)SIhv@*b*t9S4o9Z4qJ@(W~yusyP2(L+wnFjFTS)cOJ>O;DUyLbE0wV0 ze1PPKBt4Q>NYl<%Nk+*kIoU1j4z`Zn$u_aOVU;$syV!kf8%DU5?PL$J2iZUQ2tJ-I zZ)K9*g_C-8B6L-?cYaQGR%S*xJuMYe1xybx3&NMQ@b7W-uQd5J;o7E9 zG^;79%L>=k^``sqY&@9V?LkvCgh#cPmx+d`-fU!DRx*N;tyh$cXeA?ECAk_J#0K@w z57mT2(UaBT&`~~ZTm!D}tPW2NML!qUqr|l?OWfFSla_`Wp_;(F>QIz7g=(U;*UZ~g z(^TC%pC7WAhlYo?n0x25LuLyuEx3y2gqI%TITc)7NI5kF4oS>tqi&;eX3gy8=-6=$ zHPuOJX;XXW50BczXbD+tsAw{(42>E@lcD)hkj`!o9m;=s(;Y`)q?+=q&Ee+RGa91u zY}DN(*KFFfA?nPF=7y`Ix!3(A06w-v^TX9O(L8E(#Q3g$MqKKWNA;O%IJD_&hT()i z{|w{k_GEVaiIS;)%_y@LlG?PXHXN$m)U;{#(ayDV!XY)h>5$dBX=x2O%*HlEIi5dv zds4Laj;T?#X&xUCA8hUT5mEQJ=?zgSvoQ~d9mc>(ko>YX30%hN}-O>IhQ2GUwX4M}Oy$W#b; zYPg|gDk&N`lzRr1&(VpqX%@sw1xYEYxi~YUwRv4UB<4nkiTebvp);3f z4^L!=HW|YsCTt=}gyRh|P(D1$NQEP1P7E7ZCp?F1XNN;75H0Y$=};s>Se{3)-4q_) zyeT}PVUQ>d3$i-tI_lfSM(`06t9s|dm{lDL^V`N9ityVeOlx=+?*k3pHnHI_UOqRp zscPz>4CFOD8)7UXo=WtT9#WAI-B3&8abpzalb($*wpQfo!~=1E)ltsGGp!Jwady>F zNqeRy%1L;p)1F1dv#CgsQeYkw5{A7d)J*cZVd}h1O;bt7nGYPnA100A3UDV}afnNb zHEIsGR7EY}DtcZ?&nva(3OzT3tD<-%WbgdzHmNn?uLHdq#-^ISlRH!I{`TQ-r8WQL zO<(e(o&O!l`@2=G{ix)_Nq_A8!=$1Q`G;Jd^auHTYSFKF+sj|PEL}JfNG*DXH$AiV z8R=-}%aO8Y9PZjr4)N53g$FAS%3}`BI@oqljvU0({o?|usXJ%wl+HZJ<-8p{bqBv^ z$L<|c`;K)xB>mCOzeR#OOqSY%+h5u)$$8s&>NfuHwu9TG8@6$gyM7yT3-7JGcg($V z%fk{DkXR1NhnW|vym2-LO+`_q)b35niBCTUvceh4cb(JmL z(Q>dw((i6Q(=5p}$T7`|xpwxfyws*y!%}CBO;7!HI{$1spE&)N>C*7&eBgBcuW9^? zX?)={K4KalIE^dr64xX>Sf?wIC#A~VAy>)=@h>z}Ql}J7k*Uq6CcC_~M?23vHQ8Xn z`Q@i3iu;!%izh0U+VNxaQY*)f89QsNe7=rJ1xsDI0G|_V$_W%U9&Z6Q9-Il~{Wor^mC}S^ILF zFUzBQS#aVyRYN1n&>+L!ZoI_BZjo|lI|o`de75XE1tM+9HZ{YS|{=+&yqsNzyF;DEWa{s3{@qeeW=$4}FSo8Ea*2n1OC%FSGZdHCl@C0qFT!7K6q3CQnX~f?a0v22!f(EGWiob*KOs*P_s7@~{yTmjuD4-{;eh@~>{zTVwvM$)zreFz z@vV*hjOX${Nz3G1d6ayEykGv4&Y`Q;P1oJ0dm3Mzs?={)TuO`bwxQB6*XT6fZ2Y}x zuxXX)dDFM%1(v>+-S~WBx%DaQXSQ?(7eb&qoIa=+{T*5mgK^i1_E_1xz*dgpr&`0T!gzEl1^{yzsifmwlrf!BlO!Ii<6 zd!+YR*W-<(@}#?xPA6w4|F&mK&r>N$DJxPQNclRo4%d(#`!e-^F} zKb>LBD9sq0Y0V60-kAAZmN{!p*50hM*?HM5*-vKwDW_M?bvcjZyq@!I?&93_xjS>8 z&V4KQFTG5?uI{zI*F(LY?)7%Bk9%Fr^8jqsdHeES%KKg3*?fI|&-{M*5B5&(-M9CM z-dFX$q4$>F9~N9&aCgC@1%tET|50QpN-gSNG`gsz=*B+wJ{f%m z_8He_UY|96?k_eK-(37a@xkI(i~m^sRms$nWhEO+9xgdj@^;Ce`?9|NzJ+~j`_AmU zqVHXOAMN`>-}n3eci(fR^Gny3ZY%vo=_{qbFa1Y9eZQ=JgZoYBx1itJe%t#U==W;B z5Br_#uk=spKd}ED{Xgj+EAy7+mklkOR<^9{ma_ZH4wk)M_K$LJd4BoO^2z1%%MX{o zS^i1+`2qF;SpzBtj2p0g!100hftdpb4jeOZ&cIaz?-_V_kbBUgLF)!RFep0c#Go^S zz8gG$@V6C?ip+|#ijft~6*p9Dsd&8N<%<8P_*=!rN>634%E6W6D(6*RSNU#aU}QpM ze&nXe_Q-+AuOlBuz8+#9k~O4!$jBjA4Y_W}<{>{H^74@14f(uESCv#%TvbcQvuv(Y4pt{%V+hSn;q&h8-LBOm!xs!cGW^BiuMIy{Ke)c8epLMf^*^hBy#AZ|*ofQ_eMYPranp#6 zBLgEtBkvlej>;WXHL79Ml2Nye+Bxdb=ZcUs}J+G&l`9-DSxI-hQu?t}}xV@7bs&Kch~x*MlAzSMZ4@pR+w8b50M zr16W!Z)eV(**0_K%>6U}Icwmo&9gpf8r*by)7jZAv;Q>vZ*yAa{BBO?RV`O7zUoiS zP0f3opKt!UCDQU}%iml6*_zy%(VE}7u(iGQTUfe#QeR2Dq_NUu_ zv)sFU>GE$^+;olinpaj1S^4d?H(q<|wV$qXts1gw>8b~>^IkXSy3N;pa6P}i_w{ew z(Bplf_P%lHjgQ>;#*Js!xYtZx^YEGrYp1W>bW`?Cn}2${`Ga+% z*G*eD=N8K?x2?}uKXCo{^{wl#TmSR*U)?(F*5$YE-r(JE!-fxTtGMl|+itt<^hW!} zf{nEsXKq}v@s3TooBncp%k96vW5gZD?u^{|-dzjt_TPQ7H!MlR<-T*?X~yUKTz_(zjplf!MX>x@0`5z!JU76$o5dhuAaM| ze|Yx8pYE>Sz3*okKRdj~xo7sC(~p!q^6uVS_wL+#_|dFKH$U3>*wv5y=g+Hue%H^> z>?_!}Vc$ECr#!y#@e5D<;>jsbE_`y$lc)Cg+@HDsw*CM5#k>QK1E&x6JGk}WKci!! zM-BxK%{}ys!-a=mdTQiTe|_rg)B2~ApWgKJzka#sm%l#ZJF@b~i_iFSznJ-A z{};!;*!topFYS2gFE4%ea_h@q9>4upJ%6?5m7G_e|8>r)EeIUZ3`Q`|EeU{@Cj;zy4pZUwk9wjs9YX7NMPW}GWm!}PZ?*!i| zdZ+fCY41Gr&NuIlc=x&A6#nMA-@N`_?tAyX_tJZx{FXjAm*{uzbY?_BGFIO6BJ^q} zlWwWJ7OyCxC>Ni4)zNpkkzH9_Si%eQ8cUodg(ZE8+-c6V{@9Pp!!JBDPg-?xgZ{|* z`gyv)qRlOxf99J-n|?OnS;jlhMcigjof=#lyeGIjsFUqG@ESKAb%5^x*6FzELAQh+ z3co&u9!d(;j^f5XMR`0dm&ko9q>|zk$?LI8;q(HDk6l&r(K%0gK~j&xbi7f&ut!os zx`*%51n@GX zk`l0}SezP*i$N^WT-d1o#a~|Rbot96BDySzUzZfpDAK$bg4&mpn1Ja7D#@jMgWfGZdN&cl(|hw|#!(T%Z*d_V0QdEG`H zjg6&!W9%regQ8sDxl#Tv{Q6FBeA-gUo{p6CEzIS)g@{s=rG zB*Ou&Nu8JnGj3o*Y_|SO&IEaoRHMjfsSB2PJh_7gxeNLm2j{e>Wu~P@?9RH>)ReJl z+>w@=CK=QEy4#KT@(sRgfJ#r9ZFNQl9V#hw5|0XJHWF|0#0{9|0&Aeaq{ki5v;RQ$ zvf>VBIdQPDq!D_D4a|bJ8NA_AC|q`Fid^C>kV~P6{Yy*m0~LNlR#vt%MK<(BuCrf1 z?n#mSPP`-Lzls~zPux`8+B7kgHl?YhaO%3rz4}bQY0ReP$A?yx-BI7LVR}K-lUG~P zI6dZa=2Z2WI)T4fd-cTr*1vvea`kZTSJQep`QenRNlWU7woNECJss8eO5GgHRbtap zt0pY0OY7e|%N4ubK1X^aqr4Em=&($kitkym*3QqA68!d#37?2%C^^Z6@h4Ph^0s9_bNwHH6rz`q6EQvb=Q~uLAJd9cD*quAa4&x^> z>f6T*Upg`?Jbc;c5z9tp^ZoIh*TTrDUpgY5GcvoAU3h<&oUfA}eU#VpxvhBPhu4{h^&2v*DpbY$RrRatsUJ9K7=93E7|U1lC1ZYmdZ>=qP3l>vribu}^pGKa zT;s<0L|w_0Vwn0`Bd%sPb~y1|09Nf#JDdWIq+3vz z3g}Y-44UFDhFWpE?8VbeQZY@_5+={UE9CwqcG+hNz{k|Iz8M22mn8=at9ngt z-Y{U!#JW&yb>Ff5lfzX_vDG=F+J>bL>YZFXb5p~Fb<>NACoUeuo09U1nsQb7h?Q6tn6Pq0WO3t|jMyDL2UU+QtZJJxDL3}P{@%m-B$dv+4?u>^<-~fK z^@=3Ftba#;MlToY+wk?RZpIcLN0O-({Az@;CnGBitY%wb4cPeDF)0u2xLJ>gO|gGz zI#-FO_J83A4J(CW{sl;N6VFN%_y=$`Tp*9ns9!dE{~en%hb^diV)U~545`oRe}4R4 zTS}7ZG3&~ z`fc>Z3C=2G-|XyW1-}z1+O*W%dq} z`r@6&IEvG~zII(kB{@m(uD^t=Q%Lo*+C zNoOosc6iM-2iwa_+78{gGP-=gMR!Wo!cn6Z)ug7@EE+XxVO5Is;i1@n|Ejh1S3Gd& z5Dy%0Z8;wM@59^9+&7|rYsdC&XSUYYZ#_dYI1EDRcl1?eYra~GEKnIo>5ke^;T zxpdY8HLW=_7F;u=>A^(ZLay-9mBcXR;{_9z4?A>p$SrSfT6}!cl(!mZ+&U$_ z)wpDJ?V?APlvVc0bGP}2 z2nU5cvcl;I60_YDR`=^CrCs&pn!4&+UtL>r)%5ZB#Bk14y~f-yxgfePsj{-%JFUNT z_~K{Tq51Mn{TJX$tF7LnizFvK7^Z5_JlLg=!gO$z3H@xZ* z>rF@r7cX&`bLy77qJK{>{gQtA!!c4F$#a$jE0(+;=5L4jbEF$;Fcg%6=9GC@Hk788 z@tm@pQV7l4>9HpgeIw zOZoUnNx;{)YGS{Z1*D0@Qynxh7vGmFjii)&+gPQF0Bng>4TVBdsPBrTBtx(EOoO_@ z&?CVd(!&zr$Fv|yNBWj9X8i$jy6>7b#Pu&>-E_KyA{OM6B5pX)ny0sU%0@N`HLPrZ zw6*2H+WJ^#LJg~z2sM;z=fC^nqt`+W75z?|b>`3hV`WA~fu@AdkP`lr56hX@T?rRf z(FjE}p=%YsxgwIR=B~}XCwF(QF2%gf^TU85f){+&vG9XIRf{Sr5$_G!1XPS^Rj zy=;5OCNBixJ*9%ige zD^l-Zl}2AFBiiDM%!CJBhPgcgT37kt!jcjmz%_-6nYN@p&Hs9SzFui}e#$5LBk z4H$c7=bz@)=`C^~xPuGp4j?OnGYG^v%5nmNeZyW$65A6AOC}t*pv- z#ooO#QkO8}uUBq@SDC`*v9?HMgTE;|)z8;tbANViZMI(?-6sSYEQl=N10$pP=zQyR zm%-JX>~N*JUUI?ZBy)o+*_9mWH$jfn49CLT@yg?3B0sZnW}|u>i%G{tICC6+cG+>v z@(ZyjhYa<&h~G3@cZH4f0o)^gY6mVMV%8}XvuSd%YFHOi&cIgY{e?ihX7hxdBCcf-0F(loG`eVSH zhusp%Q1rDDuk~=rBM&!X0f!qgwYSTNZ47*^;U2>~cr81{Y5~PuXHX3WpTn2xEA-v% zd)W7p53jAq;xS?coixiHGTZCydc34S*5Pa7mBp3ig|6~Eps}oECe07Z@*0<6=>;%> z2r2%=p@f16TGZtwKwN>0wG}j(y8GfsdyYxLC!`*+xmy({{zb=t7YHbu`Kz&k`eWy- z@%8zAuD*kYq^4F4E^z`-upuWfE-ZZ`Mo!0f&F4faEGg6U3jbL7T9N*PK%CKQ`cmgw zr{tWAPeJeQBdL9OAY+=pxyTZ3S{2}y05=8#EThTqN^e4Y@!$d$rK6my-(arZsD48c z1vG3~2U(T01j@Yer~-?)@rX3+bfzU@x)c2FwXdwJ%C28rQ?qJX-yzpW+hR%2eKqmw z+SDD7eZd8@x5~kV2d*DF@S5l~Q+JQf z9zALHz`f@l8ad_h^LrNkdd%p`t@`Y7_y2z5ogZu)9ro{W`0a*8uW{ewk8#gyOY(c| z3>85CNKO|ZCo3d{`L}I4n~R?w=ALOvbHLqXkUdRUvKI4iq7FMj89zrE#%CNf@ut<@ zaM)QALNiTAV&CqI-OIN>@ZEt~uU6f7bj2Hcpukq?(`RF!K0i}`WX3OJUmdyk{Y^u^ z-^eqFZ|Gfq5xrYjRV2$}L1HO(5MaEEeG!4HdIp?{Vnn`d#281QE% zxfW6c^{*8F(li?+VcACP@{1Qu(zh31k^C1wl?LmN?2QfDbMd=wJ(}3kh!fp8WZo(B zwemgiqvG2}kuroa_-O%$rO<)G#N;qA=>qpZ&T@%OyTOlBstXJ#@pnaoTk$z-1- zla(aQ8@7xjWPz|42nh&b5d>U7>(EHjy$JnwVPdCqg5{XwlP0oWJ~16IN&q1&VzrF!(L zFObx!HdhihE5eNqS%T=Xv~(Obe$cR;TktXPgGQ&}$9A0@Lk_5oTsSgDLx1I(O}(01 zTAEqhmnE(#x0SQt(#)Z<(g8up_YK(P`~f`?41W|~0Bj03)njAA_DMtnZV8)w1*k^T zV(2i`+ryHD{ic5N)*IWu^4EtK4IF2tZ*KbWl4SmZCH)oGKfPl{{k6~BRCdYqdSB{I zNgjzia-7C>&oR&Ak1_Xi>&i;LX3zClh^TJ-j|UeisKL*M)B7mD$@j5EjTl&;u-bgu z%ubnE$jmb2K4n#=G+?FeMO7+E(fCoE+k(?)nJ5c~n3f2NFYIsjxcuhHk)e|(#e*ls zM@JUH{&}CcmYy{qY;zTV)?&5LWG*#}+szM{ziB>imV3>t)ZAolH%mb?6Hy|jPZ3{% zCVpb{BNZ9S@WMbuGEgraBjNCDHU5&RrnLXr>c2c&JwS5G79ynDdOHL&m)`CXSB<>) z*khvOvB!pr<@<_%oJ9s##fDnl$1E&H=16VT%_53_B;f%1Kt&>X z5}m!U{DOk1Yd$lCebKrDExHhZBmR%u8}S`&1=I7bsK;d>f9;J_%l?xmuVc@@KJt-x z^2(7D*pPxpplI$+HH%N(VE@0If9^0gs{wRaL@-fRpgjNjjLH zeDJV#Ds?f;%`5CzopoLkFg?f&wI&~}hE+batG5{(NoFxg_Drn6aeR}R!AY;Wv>M(_IKTMptNU?a={A9- z$sR9_mtsLmL5uzUVHRJYXv!<@Tu08^*d}=llKV{`Hmc<^_A*(FwBz4Zn zNVO`$+)EPs8!z0W96!HAe&mz6(zcqLTG}o-FKY8tESRT9=uwL;MUd-VI4j;`UUtCC z1TbDPifxq)ea2PUZqcU8PKqYUOxWYCnG{s{F*h`G=5(JFB6$QinX)BqkF8NdxwsFC zPZzUO#cXpiixm$Pi&;yJLq(ARtLz<6G)|=LEG=RBcKE-nv&xp9!+(C@U*G>qN5?}S z{ObdMJlu2s^_t87?aC|v?egmC^+&F}^5G3N;xE6E`ooJGaASEMeU!PLzx?tSQh)sB zzPIo1>AC;yeYgDQy*)km{wHBfH&`5NY611kQOjIQi;&7j4%apQGk&IW0?}FZeHp8K z*1<}hN==va-a+(^;vAdq4(%e*sGy(E0Y(XKfrCuJ#-#{3UjKzN_uX@nt-t99UuYib z+||E-X~mJp56i}-kL;Q^0uyoL#>1&Kp|&kOU)o1&nOe!$GJs6G1~sn;YZ*TsXQ$$9 zGhD6lfw-8vG;653e84M51{AB)AjG&K^rH2IIW6s7{Xfm#%9g5uFZGx1>$`5vx8n9< z$N#m&yZ`HZUo2dHp!rLeytqRY|GBk3jJ38R%kV~Zk-_SPP8cyuyD+$Ic9Ad8L}N+J>5uxu4GrmA|@ z*0V3Yo%-s#NBX|dQ$VJ+!{V}$Bg*lgyuSFx{^?mGTf}7#MP{#=om`~`a6;F@TKWoZ z;W#9cD49p?eZrdBQ?;YD;$SUH)UuL3gMX;TUZO+?@aefa*sCD->~x_e=< zdi7UVY$RKfx@RT|A`8}jv3JQW z1J&h`2Lq*B1{)X5YzpUh41NJ~f`>+SVAu4*a<$rOV6Pcim*I>-v>8H%N`rJ%_r6a2 zBFW_XK2b%~hX|nvwF(!DYs76xk0jZZY&!@88IaR*4z5jvykLv^DVhK?)-FzL2d>Sq zxaFzTaw(M>P#j0NY;ywg@h_DV;Cr|&-F=L+yiMMtUJ+D}Gxof4^Umk@%zEluM=#wuzX(zA7dozd{`UFvzVy=d(&HDB zM^D$Sytzj@f!ULWwI8$36gH?fG#Eqg_CdCpCz8vE<3Fvsp-X`nnI&e~VL4@yEGnXV z6w;)IQ5!%qQ0TeQp2X`1DoRKu;ofoxFi6lP8ZQMmCY`F3U!hnN&G3M|kAouP3@5j) zu3mcK#gyl%l=lS|4V2ie6+z7bc45WRZ_J(hjTPD+=~BS5L^ylgmI3X-2Aljx-@_ZL z9$0>)I`EbW^b^4ypqD@neH_EPoPsR)2K2M^!_W@pf~{N<1&ZEXP~g@}xyTo0 zo8e_Wjk$3}1e=L~Tua%evK?h&sI0O~w3e}qU@pzjnd=T=wr(3{>NX3A=O`#huK-?g z5gC#Nwg4Sc%-v2)fLBec)WitVE8+HUA>|*EFuzhK{-cF)=1TDN*E_L75@JRQqdL^1 z)sxnl{)trl!n@Xh*NGBCHmB+3mr{2;owE2)djwS)yq3Q{o%+HHXHfyc0;6@7$BfA5 zM;bP-TV7b$ciEaM=}KI=kH$B|>TBZlvCVZCpvhg>TXEUSrG*76H*Bg(Q^X+F+9d2! z0|wOkGz#^Q8!{ST2Ip;P*=AuU;=Cp9#mXYHCS)rVL?D~t4l}AH>97*tMQ96Gw{3Ef z$f7XJBaR6lrKMZ0P-9)H$@w{cP!C!gsjnqS!EA;BV7g-1E zd?vM2+&;2Lyda(&d0mW+bdan?^jr_@GlZ*D@B46*s)o#D#y9osK0Q)1q5ko&eNdzE_?sVi-_(<^m=$z+FKqi9DX_q~&v4a9M*A*}IN zyyGe<@C4U|8`IBvUrx<vG_HX*l`wUg z4pAd2S!P4%3^@RAeuk#cAw&e6^S9NpYM7CJiv{B%xaQ0VOQ{RJ;!7j*q}?Oa#JBH| zcRYN@`CassBZyRJ#8dRpTVav=AKhQb6MKxEW-?Pg6hG2^$PluS_8k8i0ultcunWqC z*qFMU-F^0K>S^64cYnfVYk2a+-vgE;gr5*0I5I_m((u7BWv}9(#}JPJ!8qPP(yJ5u z^@7rK9mufL5SFX)_;yL@x<*B zgc*e6XV0>GQtKaA&fNVmtcy%277Jvr@+@q>j^k)5hL3atd6TgR^k8Bsh|2%b5IgnN z)X~(xiUnlL6wi)?p^;ojJuP*PlHlWjXI)|Jq{zbr`0vtUN}U%Tmk>RI^a#fG$!|#x zT^O|l+^SK~W$d&fWgq6KSikSbEcPl^3sED{TEupEB*(Rp`STLCw{4{rl`i?MoCQmI z{I0y7o{j*?U(0c0J}57T?W0=gRqZxb+!k3_W3Aa#BkC%XnZ6UFuc^6ad(vkEo%(#4 zi{f5)cc5gx%@(lbcSE*8{Q`JH&%r*B-BRr#XFfse;g_Xbi(}_TRPtAe@Gt{}qR}J00qB0e0S=&*1pzr!i zLM!eoZ!O7+_H6Gxax6nXduCsKc4gkaqK4v2Z&^8F+fg|0ny$NQ>b$$U&ePC5&G(ht@3^aHcU|4~ti--I@A=Bx`=;l44;oRS z=9Qnm@mzuTYk^!^OY-50d@U=58Z}TT_}g+9R@W5XZ+X?Ml)+m;t=EBX4X8vfEbtYj|y1vAy6 zNYZOtT>MTk+f>Z*>{!hrd$%7YV?=8n)8*x51-p&5tg*G_maDYFL2@GbqbC*_egaom zi)Q%ced^N-W6M(J#KUc9A9(hI5MQSAG~|kmhLjp03Fy5bV0=AZdNrfq_U(7SpNiW zn&raRRj;{PSA+JS#Dl5-)PKR*413rY4tF@$J1<^-IeEOP<#^4 zVxFX&Jj<04}I;W8o`WWMh2HGc@M) zg-@dvCWZ+mfubUD+&I%CLmm$?B@O}ALAvllPGM}|)_!-H#UA$Cvx^&o$NG2ni)|Qudj{HSR5;Y`BSQ|X+`qnliBrst;ZrAiQ;7&E?c!`-Kxvh z%X7E*BO7OT>{?#SB%?P}lK7DU2)~SCVi4&(ejH~V%T_{kqY|fBV%oN&W z*6YwOup-q{yL)2qa>b1t)v!P!xIXQ&BRd9Lb^Q4AE#>ZLz@8{8Z;|J+;^sPYPH8Tx zUm!yJ=~Nbff>Q_!6{;7d79wJfwJkGCk}`YqJPU$BvsK@X0|%;s%TN<@a4_&F=cf#T z&dCp+QJL`g>LUJ%i1T<}a-(wshZG9A--RwM(bl;9xAWQawl9w92PTlxR$lsmM_De1 z>V}^2=z%l~(k-0_51j{_qS&mqm`&814Q<9=D@vu4Hi6=zNpy9Di4ARWjV=k~&V%cr ze$BNVVhY0C|j2*7`cOeG(Xj+ z%NnUm{aM40tpa`$VpuIUC4?Z@Hr6Xc{vbZW^*?PZX!S9U(~@p4&U~4$T1`ZZZBLrm zJ*J0E;yx2wW7=jCO(wU{R<^L>g9>)0f`ux&D@1Dr%ka9|+`Z)ypHH@S7X@t|E4rZ& zwSn9y_9|@xB+C!oEo2MA7q>)DBELz5=;5J4?(~bxuDrf#-6cbn-gpLv|xtWLZzA` zv}G?u_}HLtr%&RC#cP$jQK%RjHRZ4n)>x@Y$i~NU8$T*Q>QhH0jRAkQb|aVL*-l6Y zm1@A36c&fo@N40B!jd)2bXiH`qEMjQYV&j}6CwgB|C+@wt)Zu5IutG;Xgo?TpLxS~ zHm!MlN88MQ`7VDQ5%wKCxR?Hk(S2{;(a~|ooBM8l+*=juw!3YppzSa1R!C}ruthtn30sKsBE0BYjgDJz z)9a#n;w3N^z2;-q#4SzC;&Q=VJ}zc8rzNmmlZAvV60^8qkSf*H-4$sm_m7DT(%Tiw zZyiXB2@tqQPQV;Q%)zG3p){lvwB>U_$C7j}s>=80Swp67zpYHbY``GM2{>8Mf$V#c zIO7=?#}K_1uZO&own$qfv34?|LlXi|N3$oxf9G-H0huHVO%-SE9mC&W-V(X%;~%m& zozwiGJQ9Y|d?W)ia0{)f={wR7B#~}^EeFc4H^EPqU76jTy)#>~o7*hC9@KnvImi={ zcs4zgYO;&K1qN0z>Cz{jPIM~n3nYEnIZeLA+V`;Sy`LmP~d1l3@oZEEbexe zDS0-7MWfj21nyu`F8+=^nW$bC8ljWIJoh_reH_!rDd&48+}=| z%aX~fx=ZU<-MVPSSCfg>eQiT4Jq^p}B)4>zu=4I}dx|1?50i<`UEGu(tgfmK2Ak)u zm^o+T+`^K)I|HRNr$=fkVu9S|_CeD9!lQo@4=8gWqji7V%Q?X>MRn@(r*Il53g)hcv@0n#0l7QkL4NsO;O=E zY)6UA8-EALw;zBu@FMRm}mRQc+{)Dd!pI`%bCb$*j(pv&)GN_b{!&sK?q2 z%m6dCCJm4Uq~Te*6F|BRrKQhulO7yHV6>Wv3Y1IME4D4Q@9CFJxw&367R=7gHNEt7 zYM(rJ=5K_@eM;GA3jgfNvDR0Wk03Z74_| z1PwNt2e<#JXeE`jX7@%}6gD{3g{ymMHp>p-HEPJtHbf|L4F$xK%M8-{J^ci01iL1Z6^><=Pq zgfWa=u54Gt#R{9I%vHoy>}n=1p%}5*h_7W>D0KPIWw3u_uy-?99X!{1)$L8{Da-D1 z{dT>$SkI>E=fcYYw??H|yxn}vELxFa@|KakY-A^m%mBk&ld0V#7MYlWo&};w59crm zHzZ;}Tj+;zw0{foX%JdS+5>_F$Y`2PAyf2aBm+H?1&Lgq zgPPADOS;jcVb2t!+|&l|0@1r zn~*Jui;J!=ykceu3mCIW){X?k?36(~Hu5(y_XcU!zAs;RoiL;9De}=r1ywEZDat=W z(Z58T*1y}})s0v`e9H#bG(g&QvF}6gN6Lpf%|Z#I0FP^m_5U^=|4a3M#lR^kqs8Nb zCP=bfEmT0B1^_1RBAXFqLa@JOm$w$p+dWXX`-U5K*A48RSJYabz3r;2w%ICMB4&0E z3%6Z?IKDND9$2)7&Fj3PEzIs_=15CrYIxoDtjw(I5y#As@c* z5=}8>sKG9H%g7s~uSIm_IhyC#{KKt-(-KUz9?QLmF|8Io8r*`6WZc;E-8dc+K=yGTD zUxmg?;j0u;;mjt}>PT7@t0JKlb zxi7xhwC>BwE9H^f1Ev0^d*r zkDKld~>a9A*pi>f@JFEw+B3wAHk?nr&2rKPrbp)Q*V4nd-+3Z&uQ|~LHT}YU+NR4!wZ6nky13l{q;hlS|Au$CF1@! z8+ICCqJI>*05-j<->E;1zF&HZaMEeF08ucv^Fqm>Kn&7E)As@02p9gA@?Q8K(t)oV z{kyar7U$W>X}V5rR~BXT%n28E%xRueTx=T+v%}$IVKKby^fGp88Jjal@XX1`;4V3? zHB*+!2k=e_OA9-cMV>_+#j?4+yTU~#XVP}a_=@L3!*~&{W>}jk*$AEsBtPIi)`{m2 zLMXv0;u@@c{Lg?r7TZz~BZ=ODvt;U+=NUmv>xpRd?~hoW$y6B&#^=^0jW5?~N6D zq~iDjwcJ{GWpB&MSp`L*{W;O5Mt?@=v6u2yGjBQy+B~hh ziJ}BmRPB~^f>pZ1bBH29Dk168X+@F_XTH8)@bD)xL&8)|N3dYBNfN2NMbT-~qD2jC zTSJjE;m}`gYfa{P88y>U;2ZNh~JA(>750k2 zB5iM3u7(3G12a8!jSb%Hs@mqr(0!}pb?fe5mH1-Q^qLhHo~c`L%hyk@U3>cLx2&j} z{C?x=qkq`5=MP6$kG;x)vIW<+cV0WcRG(=#>_#I7{fz4$U9F)?HrP92)>tss726Rz8dLJ$F?l?L z2xq7$|Bcn^W6|FTy3@|z_2;G2mY1%U^$eY8q>l9J!@|c)6>rwX6zrnlD@>-6_2UkGEMERPCZ{ z{-d!QT@pkYP0rEnk8Yqa9LMN0Zari@YL#?a^J!VU`@+XkVC45~*F6F{Nu)FUMe1^aD`))NWMH4Cq0;^j)EkbthuzP+ zrD4zW9?|1w^IaB?#r=ZIlI3!t2f5&V!Do0ucFAzZ3BJ?5*L;%xfXsZdPY%w0PAF%m z%VCacdM;?menk-6ez(h)@roaVt-hcy=G);r;5+2Qk>lQ(&G64CKEKajsJ>j|ocnSi zojD4})6U!$T1ZM8Ay56}v&Tby@G0G1jeBjSHsRU5N~!I6hMTG%A(Y%_6`{H)=;=Z{ zH6oEi5PatUI*;P-l1sZ5Tsnt+*y{mH;re*efr=l?kQ^i6*Msgo!P z$=P$8c2%}F7MZVDT+r5Fx3j_2Vd;h&Q_ua=XONA4qRT?(%ERDq|4WpGtULcVbVkcU zlm#R%X^}`V{Z!pxrdpQ!O=IyPR5y6E5}a5RypP+gA*=X~^#iN8$;t$%;UN&X)f#zR z(NfGvzvdZqbW%YNAzXJS%Vxzbg_*Ejiv{@3M$?9^?34-gKu6m&QK($y+h(@Cp z)f-A$B=2vu^EKc*>r*m(K1X5X-LhXf-nE*}@}P!uU|6I}Yp4_Alt751g@i0D9+dn^ zLJ7qLXh#UO4)CUeisX!yIuJX1W-nP%wBQSi=4@|Fe6e=rlFJ8Iu3Xle6^Z$qR>Wrq zT4r^W&0aSrBLA*)eYR(PXY;DIB5!a{Ug3gE=FZ&GrG{d;mg0gzPl3;x*NomRQ=@~B z-?G!1Ie^M05EXogMxy8-SU}^rTlEpP&mD`EAUG&7uP1Vy{I@_yPfwo9-?L;v4oT6E z!w2GkttNnM{XFtDF2v0q8oS%G0&O|Hxjw%H2Z+g)V}N-HegiF6fO~Q1YD(WdBwxbj z$n}D;u>3e%wSLq5D`w^#zteB5ynRh_JxYv-?D%oEcfw$N=YrmflER|M!jjZ!9Ywos zNnMbKVDWGQr?7m#ppeO(adQQ;oKDvc#{swz96IwC z1;5VcxD|zEEJ-wgGTw&t;d3zxUVwan*^+674m77mQpb4F4NiU0`Z$vJ*?qU&<1V*a zt88uEzKTRa-*t_2|EJEa*r1a(NK$E4cEsm29J?yRR}9${BD*-3orF$hLEKNc%eDii zFgi09i+E1hAsvvA*;@(slK4xr;a%YuINGmrdubdeg9jgynn9vG!bPc+%HBIDo551( zUXE%q7w!^eZ*y~l+g@b9WRSS;49H9SAuo|vv*J6xcepy6Wq@}(46kO^JI0XbH_GY2 zZ>*YZgjxTL_-rX%)fX8@Ci^tS{l)V(&PuHBEG_QXIBWXlon@(M?TZ$+w=Z1OE^l0L z-Ll0*^+8>C3-LS8vIiat1Vv1xj-S-ddv1o?#}(VZ=c zr`!ydg9MBROtmw?&g{6&@Y-K%@8|#eYior>Z7m>{0pei|;-3Y9AW~5yy>PV@2gD*Z zTg=K91?VU2n4N&xh0OxffQ>;TP=FK!q@RHI77EvZmI=}$8g5bokebz~BsKuI%?+%( zfiqWRA%bjUo%&Mrq(UE%5}h!1?V%@rpko*;>m2=UOER&OCmn-a~v# z;}vu-)n06T6T5BE*0C(``rdnHtMe%fd`*MDwufhdpZv6Cu3*~Io{otu@Ob3QCDY=A zw=9{pmS=%apIPc;v5Oc2RuW(GFZEZ6g+e~xiVIqHU*zc0{1+27I zz~9dpzg4&muN}h%V|8ih0YGQDWuF1PbZoS+ zUI=5fM>R`gu2P6-U01O-o{*n}y`26H9qSI>AXKR#NqpbO&iYulkEuQu@-dX^fkf<+ zL?M_)uoe`ZCKalgIf?@3I;0`O1>!`ec8ShuwDd7MPOI$vhLhzxYn;7K326jbnas&D z@t>q*2y0w2T)7{pA;sVv&`AR}^MJ9-$gIYrMll0DyOED4TTmT{;_1)D5+r5AkU?TJ z7qA=Rl--(6r0?&)Vej+L!;;7?MC6Y^HfMy9e8vA!f|_p8NJgsQM<>Mt(ksY*b&vc( zY&m}oyK@82)lR3uvKMi9u(LPdZbsHJ)~1kC!u9L|h{JT8b(Q32hd2pf6wlG+^iq_j zmnZm+f+-b3Ap60v12(To^m6g|twKWEQI?Hgn49VNywR+E^e>a4j|^iuKMkEIK*MJJ z=!Y5wVDE`wSY}8YKTZMDv3aXF{@_O7Ju_3^oBV`FF2H>;;BQTjrsWYY!d}JbZF<69!)5)bc?$NzRP4c-VmPgopKSvN>{qAxd=~rCj5Xm< zm}TemS!_0DSrziz2C`9~0>TqY)E^bj3ZrB)qXcCZonnch)HA8) z)`)Mg#JbcE*z`52Q>oKKtR?lr8nXG_FglEk#|wxIp?zMaPAd+UL7|O3LgjAu9U20OP5pH>G$_^?(18zlrm43e|1Lpg(oU1#hH~? zwo%flw0_CRGqEdYQzEMJ_}!PKe)R;;LT%g8dB-YN@(fQzEh*e_;oR=mJEd<2LdZeA zg|T}t^ycIuEfsXmGu=4lHl!)Hg;NV>evl%DbF)p8DgEN{TZI=e9=9vY$GJ#m=YHO3 zQ0{e;p^prQJ_|b0qK3_SPP?E*k1eV6xD$9i&%L!Fz_nQodywH8I22&E0JEDY<2J`WsPhk+(4gF;Pbb`R=NDaXTC5)J z>6pCD4MHxmZ+trE_T;gtIk%F9a&A-4LGB+?&=XAuo_WjFqWq?YX_2B?Gv}1l zbtUSi%`7XKUhJe$`tzOgv9-4?EGX=_8g$FEcywV<3Ou4rC(OJHhK*q{ZYP=W-QmV~ zX5QGof5zyokdR0sOknt)c;n}dW$pi^jU~|Wrq6(@{CW%vHvjwD*d~lEZl3#TxXN2& zV}qaFCZ~&#imsXQ>&NW%NQ*-GJf1|dd}=<_?uSd`53gBqa6{wBpmOJ(RSP@k7DU^- z7FONz!|8b)16R*&+um36{S{r~8B@}pD|VRJ&wcg1EIu`7YGMDv{)>}NuDq&lVN($K zRr8lEnnAim(!Yt#rpqD(^?hLj!@LBK^~*E zQGjA=IM#52a+z}>=H?n^vYlk+gTqF7id6eJ1hpBH#%~?1#CW;|Z1{z%W#i=0qc{}e z!imwWJ@r(2G=Uc~r@$V452Fh>?iw!Z`DlIzm@!pUazmUKtznw-MPU=-JIi$uXv2-d z)#@Ba5z6|7++H~+FFPkMFDDz-Qx-R=O|Lb*(;>rw%=+h4t)fP^kVA^0t1jGtWYRGv>y4? z2oun%%=7dRO~KaU%-0^>(U#cy$hx6}r5V9%`$mPiZxt9>DP0go4Kj0?CHEY zSG3RDI42x#+t`5!^p-FE;=ZmKJD%LO?Zg*ao0{dVr+eZ+j?NcFUG)S|5Ds zm&Y0|pI=?EWcR|38~UnVBE1Q_g?xJAQawbIZ2rgEUWKvxVqT@mGnFE-mc&;SR{WR5e(gUtsQCV86U zF*00S|7qBqW;CqVV}{=2l2}aSeq!|F;ZV&K8CDX8gpa`O9)k?%L2cGS)m2%}@*d63 zwmiB>8j{2!sR4F99!^+=ob4$IIUJ!9Pj+$8aq;(XLfn&j zFA~c&n{#84a4cxC1Y_dc7kxmo?Ny`0a!kGhvTZ*6uglb?Xs`&fZ9&qL?RM!i(C^kP zERLzM*JAI)Bx{W6{7LhoilW?TP%h2u)*G{73UE7YrQI2nL-FFd#EX-JTRH`kWLqvj zXwffYo@*W)12d#1+3J)UO|Y$#W0YZW!^&B^yAyLL$s)0(3h$@S9ub^wc3Ysm9CSV_ znz}NWq<1{$qITol-AOI&B9OD;l3ka)epB!6xVYEuIP?0U%SN`_ZEp~r^Ehu#yGu0M z{a2zH=I1=@f#I+}(>saMFCM*hP&*Y-3}5UIf8JQuo}rB;&_d)h;Bs2juvjk=Es89k znAeHX^TYm_278SA3OwSK{{-drhM=!BsKHp$xHxW$ zvuG&j^20Y#9T5EfvTm2v9qvY*OHC;m&+4sCXPUqpGTAFPDe1(nFPNHY!d6iZ?^tq4 zI=z?YogB|#!O1Bc((%dZC6f|QGK5s!UG}NjCfF@LYram}tk-{=-%%nX=D|#ndTrk0 ztAr~<{-y3&a3*dCWb=eL*CkN?pJcw#VV8S~?TyP%$|j8G5+a-TTa7o>0(>N1GetJz zu=VOV>`rc{qubR7;NvE?w1rWF{N6a^&YxLrdt?vYmFVOh{< zc1BrclnK$OK(`qz(O8q^sTtAOVS21%|=Rc$0km3B+KZ8tuUN>R0}OVvxV5# zLxo(T>8Hi#mN)SE`zD}6j~h-yC#`Q=*_iol0{Vdo=&b!i4LU9nW-DR~iZprYBIxy4 zBaS=jKL}~)F+ks$U-oI-m3J|kaMz=IeH?2<*q3V9&kGfOKK32LBWd`>fPZ=H)7T%L zgnfrjgI++;OW7)s=7x>y>CxK6gFc;8qSCK*Z#OM>lk!;;$4H|2&%-3ZB z|27&gHi&Nlf75Ys`Sj_50B2Cx&$Jy4Q5IjuPqmDC?h(TnZFv%;c!!v&&L@MIS=@0*JeQ; z7i|_DqaRONAKCL6>%-5Bwmu!dnOGk~eCqlTm-;I|D8*9ok5$vQ{ zYcLa@H_suHUr)!{U*wRb0Z4Vynt|x#{nsE92iG8X3a_Lg!-&ZS>OKRqLVKz~?!?{W z8kSZ8@QKm)hu3`;Y~oKE>@M_7(QIDz1iP%}(^zxj6oM08LGRGSEHw_It}>KYavc6*Vcki&RIPbU+ka!CSPUH6EJ8Ob^u>ULYfC; z6g~=N^4f9zK>sK(XitwXMMIjPnzh-?HY12;GaOA~A@k<>OxfD@^w;+H6Ia5Q@*u4J zPDs)45NFAmeR>lwmUYz2P%6tKS^EUrs%*=E$8AJlv0id|@Q2w<4zy5)bdqj`2JbL& zA#P+tUmL3MNEQWROHMGKaR!7sn_xq=6rF=|j0aD?^b*zFd`b3?49U;^55Dd>{{~gx zl*{i)?LT`K)-{|9p3@%&*Q{}xgtqX)h%GW0*%^_L%Vlh{ntJnG<}Sx6%NbODv)DXx zH^nH1P;J3xgM}LzHpsn(7!SV5i$!R7aY2gWUM8n9BmA9^#h*{7|3CQPakf3RXQBwe z!E_OT59BwA0iGDE1F#JD?If2KlMLpipv7UF;`?V9~p(1D_+TUC9W}J z^jEPlq>X3d&SGZNftYlvS}^)wIA7IZ&l}B4!zRAUrt;O%KVozV=c^j*d8yaZuyq6* zO+6;Vh7|z5C_052?9OrT5^+{>DrY6DgV?}Np$5A%1xo?P+W^?2Wr|$@eWYek9o2Ez zJ;H++jdLP+$6RzcC$myB*lvFMIylehDL@>tY7{pW08zXrPDfmFKAycwPiI=gv`gqt zuL5yuVKS#C8!ce1LR8Sj`Ttr5Cb#y36c8Rr`Tz1Vs0~pl(9HD0 zJQ1`lRFH2t_e?H3TgwjBvYoYTpq8n%EL6(`oD&tWH8=oerx*vS1e^9Rf`t%wNd0gU zZ3#J9X3GS%P`wCoG4WurK0SJDkFu~w7mXHP0x$a--=hkQ)`^W*rEjQj51XAD&%sO{ zPc=!X_JFnT)JEYVB0}ZiV-gbfy$_lq3{E$j?24Q{8cIi z!G7P9S}V^@{jPbauq^)=+m&*U940Av;$DPwMl$y3YOEaisski*Vs!JcE>n;v)=u~) zXsky680OiP9-qhdbG|CE&2VOHM(arM)u9P<8Rx6?B&?8j*VB`*j@T-`Lcbh;21X5~ zn%D-ujvPMfg#7~)!Nz# zhsWXS#D*q8$VRk_jM^7TnW_ygmt{%9ZMXkTA3ET<(6eh}!!;aM)ca<3UN zjnyWdf}2c|&8Tdv7&9_p#$z@sSeRKS>HAEAag{}p&6zU(F#UkhL01kHqUPa8l!fv4 zYPw_)i%ofx6v`O4-LO}F{&^b$7jX69vwDxhJ<9s%ODBKbnK~o3j2Kp2A|8<(BbObx z;h9w9!|bEx8-Us9-!Z=c=4TStsZFZ6+bkM%3i^FYvdL&NWk3sLPboiAM6E=Tgy20O z*=7(jdNWN%g~G>WhMZfFn#S9YOTkoa?mxfiIinxhjngg}3)fyW?=jpzuUroeN@3-zhbQaEMFo+y5@E2dN&DmT z{OO9@BM5D#Le5%sWJ!6ve$|0V6}Tr?O1`GGwc&;uDKt@&TZ?X84!M4snkPw~Ow{*4 zhTvey&JxMzZu9gO`)u7ITej8X8Y==cUgwCMh`@R(#?DXInsG_MSbT4y8jzT-fHbMB z3+e++DhecR94m-4UghP&-BcwAyT&6cxU^DDvNNNZVBFy2VUm%=*%#TbdEIN>5!Ai* zLMK_O)}b;6oW5DvebK1FA*?A2mZ1#4VW`wI(3QokSx2+PjI1oLW56!?1}vz_FFU>I zGUtf0;kEe@V!>V9RM8UKOlc8XlL8*WtTi-2nw4iFd<%xcv2a0qVWIBGh_Q5OrwsDW;OqBJ2|6HJ##R5aIgyPYUJ zQqe7G)(D}R6zc+*h}FKhG0jhn}c3T;}y zZu7;SNwMkmH(q)D7e6_(l8WLzcz0S7kq>i@UQ4G!*g6((1cMgn@x9?dMATf8nneyg zUCQ9pwUEw*u=OVzPmh3Es-A#_?(#8PAIWftfd%anY{(wlIIk8*kB>tIy$(V`L8Tpx zB8Ym(9)B6*{29Yz5HXH)(Mgzsr(19maB}iErr#JY3QWQDN?>Xn#}wAI(arp%u^i6V ze?6RsKBSYd<@K-mO4OxSqA7i6sJJsW*G$Wpte^0jJRJHWZ5@80t-}le@2_i~GWH_K zh?M(t8ZwSB%WJNgGWsIOto;EEavdP&Os|_Vb}b}%)a=IEX*gfcu+rLn_{s3JG+eA* zAI71A5XKRBrd1p`QcO()d2#QiwR4yaTJ1@Htrw8x%rNAgfq|Hekk`T9^MfTgnyl#@B zx7qW$vVuXAE4K?>SEm$Dnm{uif1a8Gr>iL0;{pW4DV3BcKOg_n)s(oQ;?otC_U|97 zsl>!o>Y}gH#D{eG)l+?`Oa!e~$)x9<)k=9RO^_pYv(h z{O;Fack(zhJ{rJ;K={ts6CloutnO1Wa`XfX=X%-`7Ided z09U8TlArQNp5Q*K6XSE}5xpAUF&B)5_hIjkV3b>)o5q`bRVTDjmT;I`l({V#XH=Ks zr=AjOU~OPy{JE4?I$oMP$=X0CTKP4{6n-xnOq@M(&`@cwn8f?>qsg&<;LxvO zC1__1fGye$6S055_aZMVYyZXs?TMw42`?+gYLF=ov6=8d@64Z!tub_csP2Y<277#0 zAhk)_JX`p0Y!w>QxVVAKaw9s2Pr{r=*YbIiQj7ceXBsYU%yRHE#-_NXibICpT%3kX z5soHkwV#5_?Oz0$tk18eSI`C6S)Va_64v0!@1$W{0bA#q630W5?_{i5$4wg6RzS8* z9t&=VeG{KSRHIWUP+bOti?Y;0F3H&@^k$j6b!gE}syMftAzp%d?C|J_i8{OX$F&N( zg|T1~6?UUe`Ph`oy5~Fblpo=S{Jlcmb)k_Vf}=PXWNi+&BP+{+BKZ!Rqtc-|WWB>F z47!Vp&5`aLJs!@Bn^JCEn!i&MYW#%-I!1L)nbyK#QrDx;ECcKk50o$5-Wh7i@ihjE znhKp`HG#)5{<}2mLV}Ps=GqjQ>JkTI={=D-hQcnRB#Is=;+fKQRIOzbsi;9y_>>AH$h|;er9C##x~<( z<4Z6nyd|*)DJdLK;4s?%ri z#t~Hp{Xir@P5A;wso4ut;;jx_GdtjT-ysef=z!)Ljhi#4mT?PA|H(MM;m!FKOQuLeZW;qxr3BXigpW>FhVtkwKQUB ztjC{oJe`v(pj2PSgFI8IyE)D-Jacg5jR&7*AH}DIn&wwm^-hmuPVNG@$5lCz|M_&H zx+)Q`%B)T(56&6%o{zA-sq5soy@PY&T@8Uieb zZ0^>!8Sd2IYnq#D;!RRB@-BH)0QS&~9aND!Hz+))Mi%b2wgy{ctx{|2(%tPkwEAi{ z`*N-IZB+|bCRVcPNna7wo1cbY%p$5cUsU8v|)a3ZmF%h+v;*#Tvn9GMUE>~5=~d5$10MNju-N!phW>yrYFrEwPVTbWqZ|z zh$LP#V|)qOKVPr@;xt1&PgvGUth1NK7j}LGDJcJRWqWp0q@}m2dVW(ljQy&_eqEEO zLjT8xs)X*uq}Bd-+5d+c_)12+2OHSX6;E$uO>J{?E&jm*o}$bseka|m@oI#KbDacI zi-^YL!&$y5{xKd|%enO<+IV)2##5z!DCb*x77IC(cstK2;Ls1IN2hZ;r0G!omsB^{ zC)P8V>sNqMyP+^i#+Jf3{mKvMij=kS#j}YsNr^m;s`S`+f}J*Y{&;074nH z5kxa0jWvQoPxZXZ!olm}8*1v-$FK9vn%RWvo=r1nd*!$CR@B$8$n*28>O9_Z;i6~h z6!_Ino1EsIHmhy`Jtz3HUY+tR%F{;4#@aZdC((^2E*vTFi zq&pJnMqdYi-in5X6?w=6_hVjt3Nb?$yas}Bz$y(;Bp+yAO9Y4g0^LOtBhMWk*}RQymu$QwDs7N+Drc7Ex5o2i<-L~GbBn3DcWJd(Z}3+Y;Sq-wt zdj;u^L#8vP_f1kI3ZdXh{Yauli2juN+J`3!YAaVws-7*fjhI7~ZZGcIASw}*XW>3b zz~wN2i^aFQl8VFKN>#!V)-LM+Oyr|hz0MlAbz)jSMbIJ=YtH?2yqDNmnmAG$CLeLB zDt%Hz#961DROLJW%X!0WgYd~M2d!oaZq=aMDSXlFkiKN3+-+LSAEUnrg@5xN4G0M* zW?vuI4cFv(%Pl@NuxeFqtiiWy|9j=7io7KwV{KnaJ6ySYa9lVQzpnfm*&GdO#OjHm z+=zfCQKH`9Rt{KH)WWl6(v0#vjgQ7)^+rq{C1=i=b(Az?1D&1q-J{airIw_cZ9Rp zhi7?qL3i5EL3XRryIr%=SS7VA=R7nMQeUA zU!?!eY8< ztm*&n6%v5u?||hz<%AH09iMy|de%GgKJcs!@|U%7T8gN zA)|g!U^q7_9UUg1Wu~9p;rP#x1nT1%@rYJRySB$>gUGt)U=xSceg4F3+SE$1ToMmg zu$>iba|P?JK)HQpt6)L}%de;~8W9yG!hHdFX^H(&gm==x&sV<18Ytt7>wVD z?9-4Z+{f_#4XkO~bi;5qLuJE0FXT}i*{T&O=%@3Un$JS{(_AEL;CFZ>1h8v<5_A-8 z3#sBIe2@OvxUNA4SSoza{jdt^1R0+f{w9dW1Sax|6~PQABEj@leN5k_-=vrIsy#a? z^~tMXTSEaXC<>b5$6L^qqKPdIIdXO*b~HhL4%Idu{^SD~^}sUmBzY~~DyYA)M75*f ziB2>v9h}k(FA61wF?5C)ux&zpjzee$qeG1jL(;fZ)KOzNos2fj2$g`FBaSM$=d`C% zTSiT=DL`})i|ZlUK-nlPl-HjBKKsE_%k3qBl=%3CV8snL>`|&-o%_hr5u^CQ3Z93a zo;%i}h_4OT{rTEJLr5`s3#enF93Qj3RNm@U{ z0W~LPdEYWhEelcC*rKAvF>hX&X;Kt}k?IcQ8Ci^rE{CuNXN30!y$y?H6BN=!6_eHn z8IBz4;D@4#&@A~jA`k&o6eeAfgjAH8j?4RBOuZefu+m1p^#c3dQ_{f|kF>Wxvh>0r zNJ_(#diVm*$}zmTFIz`ma_k!I>U$W9nv(G8U#3n+TMs{(j0I*w5A6(gI)f!pubJ1_ z6)Ta^tlwJrKz&aUab_R#9sQ?b>DuI;VOZu!Cw_RM|CM~!@`H*Dimjf;2m7F8_W-|tg? zG`#%&=Z9K$ZNFlE<+*c}^RL*xt7Yi<`(6sKZC7t`%HaD-`-?`+jbxrBj!a=}l zA-D%Ly%v%HRXQpVHmhyHHK?=Mmvhj__8QssP#}!X2vVitq(GDddo9Y2Mo&e>+j+bM zau}@9U{ut(mpX?EgE@m4CX*pQkR`znO+gQ7Guvk`4ORvVLxn9Vmzu8#Vs40O#qmm& z!_X1>r{BjZ7XY}z6%e(_-*!U znj0urc^J283|X-~mZhe=r3E2VrAd@cELM;xI9u?3fov*ZdQ*X^z*)Lf7jeVD7FbgS zU-OwNwzG;Qsy0=L2D8^JW|$RBvr-tymJ9QY=7EAtvU^cfhjyp&3iHI7tH}-n-puJC zop7DrTn~>e07##XAEx+{7P|LGw0oUZ7;qLr;2 zIX1AnCxWiiO7Z_=?M>jDy3X|Bd+yb~@3JggvMkH;F5AKzUUadIC2X)|V+@$ZX5V87 zTL=L|NT6hcgoGqyb17xAf=j5AkTj4qOVc!g{FAg_CT)Rf=}f0-U^K zP5PhteV@ULWcljcbKdiwcX{6DZQOoh{lZtDdw9aWL&dwEez$M`SI^I#`}|k?``&$e zSMi~J6CQr<)rIR%Y;UByLxh(8Uod%$?kC3m@js1$Qw+oXG?qcOV%im?6KMm)GWces z860(uj?kDW3C)+zX0N?ndhO4pSaK6$$*abTDTQNR%TO!qwRcFbZIoV15lQn$@k7bH zA#xqCbm$l)OQ$pOA>F{B8A5ZMFzt?$6pC=N(&7^d z&HSDHaS*?xkq$60v97^MXP7nw`qoxCwQCM8T)nqMr}4S=AeN#k%`^m5#tE6(kRyHDUPd( z$yIVMVzPW#9+uk+qPppkj7V{W&!lat>g;Y60+C^&3WvGOASm(Ds1Z%iISL-3RDtZ~ zlUQkN29`p_hG%L}Y6_5K9>DI0+s~Rxny(QW`;o9ravSp-dw;N@;gLOquS9NnVO8&; znxToCo?cM7u%#fQwWA{|-q++U>%F6G@sy5@t%2;u9)-7L{)6)$dcmo%|NO+tgR3es zyd!^9jN5!{ZN+}?%18MX#WW}&U{BYHB?|- z8`DFy+n_QPwmaoIxg?^Yq?WT?!!5c673fIyI{F)pE>&l=a$36_i3Vsuso`>{ z5;gOZ(MenBo~P|J;ClzK;s_z|0Ha>(MZ)(wGE;P~8{GkWqW34C89b>rnL=)JxzU5d zQun=`TgT;X+I??CRyT4YXHIwAo!T*{+s99)HnUUX?0IEZ>lEan*4rwG^K02hmW7EBAcpqSMgO1F)m+wZzFx2d-x zJi9&Wt$uRVn!_v0vLhV@`Ay-p@yqshm34Pa$%(XVkFH!Bj4iC?cRf05Zg^sz#hBtX z4P@q)bggfwn^Bi*)Ee^Z;-$1hliHeQ+n1R=WlEtKM7M8L0rd&Xfkq8;U{Nd*1aDJn z26*erOl7Cacug!9*vGDMt|9@jcOXu2fQ4APK%!WtF)~U&3`@))r#F^dU>YP#5{)zV znhM%c$A5$$+V=9+$vOJM&RbfdJ>y;W%zVeQDfyW;L-DLBGk47{ntkBCmHDBZ-jICr zqxWw3;Kc)X_7%@uDf-b_ygHUwIHRM*n-PmOq}u|SUZc5wB>oszn?`;WRcxjkJ8u}QDtSJr>c?I zMw`*WBw}U(GsIy5Q+pAEWv0;I`*4Kzj?b$MZ7hxYaLi-EeeWWw`H0TQ>}@ zAD_sdv~;3h7sBz`sgO7nwf zAKG{Jp%%Gm;_eT2gAvY(gOAou^BZL`#K93|pfu}hC+9RdGn~E7)y}=nQ_eF^m5M}d zoeo*t=m6v<>BKYpoqF)2&F)7D%*~`b5<|1DEVVwjcw7o?)+LJ#56_!_U862R220}z zCK*V7*rJ!IEqdiIY`&@8zEsT1wA)iH7Lu#MKMwSF<5C+_c@Dh>Gg5`r)Z*Uay~Vt- zm?(-^vA&TjvgZM?UQXK9963pvorJ$ZTNfcgiTooa4D}N)k1 zbhksU(3g2H$if4;4JB@+{C=e-Z|1H!!{y~wICOOebB$OY}?2ibPXgq zr`)pq}miZe0zjM%HVT9AD#;|eKqQeHx0}c)J zraMdyGUy;i2dq6h|L{R=c0H92_~@8%D%@1GM}sZq>~2pF`|rRbwz7RE8|sp+@!RbY0J`t$~2tQ60a%V$%I8=xq%A?!t8@}1P0gzvHnBkTV5WRS=25T zX4$+SY-~tW@4j6q-_vr><}DHmZF#jpP4CIRhm=SUZEj5_DXxqF4#3*PG-z98JSE{ zc|3nj7U{tZ@%xSwnch#b?Kwhyg=v$v&ilLLc*-5~D<c~#Wc)>7SbcXvMdy6@Dz@us`pzw_~bzN_v)?wpmkl~3Edth!?U z&epxZnpv>m`&8B~S1t&PG2%2-KA>Y9#nUMC(>*2+$xp3LMSdr0N;#Lpr|_RIfJb0P?d!Se&@WRalp0$;-*o>w`sQZgKt0afx5;lruPIn-nhLb@kZifx{?W-JODWj0PQ_jtSJdZ9s9Y%_ywoPj(Mk7 zWU!3LxeC%((NEi!iuAF!f>)TMimvkfxHi>P;y@2R2Q$9l^umRp8&9%oMx$VOo|*`f z_fP=@H!~{H3-)RN#7vzArX|g2v$}ZIOFLUKDq9Qh4MYlE;Th}1AKu^nz~YLoy{|7N zZJzQ;`RFIAJ6IEN|HT>BCbWxob;BZ+Pj=TcUlB&MQ{(b6 zvpkV43(S9TQP^2FeZt6qvUnyDQ&Kz%Fc9Vz=Zd*|a|d%zfnOolo69SFQBP-%)@vl$ zafi#{bmN#|eU7O$APEJ&Qgcj_hom<_1sK|Zma#!XB;j_Ng|5~eJ>yi6;vo|xdHTM$ zRvqhmZTIA%^6p#e6_(3u)io<0UlQH6b;qRGj;&i8pZN7X6P1Z<^3Spf-}~hO-aGQy z%?IWc$>n>fHbyLXKXzI*qMNbGCCHXVKTRbsrIKe-$$?Y?LsA}y6;H2~)!J(Lw`#wt zjwM zC6bO~v7MyyVE4#aKAAU_ynjlE2OE?8vHPChQlmGNaUvt+HKv!h6c#lWIF2o7FKj7K zr_aAipD*pbw|m9iUXAx|TgLu|6p8CZB#vTv!QesCJz3I~lTkjlo-E3@AJ;|Rn)@ln;uF;*hFAC2kQ%x})oN|5 zwx(WQjJvpwuSIyB#Wj(=BNW^F4;h&uJvK;>g2l$~6uV_ItF9X*+Gl-NkPDa=GzR;E z{Xs#I`c(=UNEuAw*P*sM#nNr%?8SD`9=D&e%kB0-D_LUQXyxZxNd%pI0S6&gb5Clj z(q->)2v%Aq$TEDeq^KQAp&|HyN}!-r`~*W9J)qZ6(5h6X#9AAmWRSKDVF?_XH31b57EOJtha{ zfJUHb(tzg4u&qY>aZ4E@93spMrse`ugA{``CgVwiEP|_N;Fc+Re%;7UxwzrEH8TfV zgRRr%RUf+a#N_GETt2w+t+v+4gYw{nTaWe~y#2kqVt(gAqtl>7QJUkK!^HN^O$B+6 zXB1%$SY-|BbQH8s2ah4c*JV1z|7}d2*4~q~EbD@TZhFXG`J>`2Br6Z6@4Y_`h?eCA+S*VoMJEXZ0G#sxc@ExCw_tR$NhW#1AduO;aB+WA*5z1P6M_; z)82M_d0CG!a5TWH0)c#0k6&>0TCDlKP~S9)l`Qo;PmdfB!BSf{9AEhZ9y-_PTdo^?lAYIVcte2%ET}cZ?I*_PIihIU61a5Jb zfEs&~N}Y6*BQKvg!N*Q~>)lZD5&6)_BmC0q2T!#KvQSiu*io%CMb)jG2Cm6IXFp8C zuWV$%HfZD5AwXy24BbYK6)?rkr_6G*dC*9f7&jXExkf?}d^`tqiQU{|(f43FEP_!< zZ;N@aSh(vH2h$u>anLvzQw=oCK1N^gen}ym7^5PD?Nkkn{Du5=R53`}Kz5L6gX2kU zup5Y3stqVxMyA$$O&j3V)UQ0ETn63o6Z&etobxAN9mK2k1(_%cNY)!-Ufxagv+Om^ zu}^r1|0U1!-ERw@3jEUo*$;Mb6M9%j1u`B#3UW2F+vr_Q`t(m>ZQ+^{6|&npv?Wjh zq=|AFbXKEX^^zttbNz4}Q`Td89wXn)l%=%3vNsalKT6Cw!Qc66qMvM+4*_^$!uauV z4f`U=-Bs4;7O|)YcA&~^r`*xT^q%zo^wa4wh1T4ySeWMSF=~%$d89zinjWP9Hfd?w zjnQXpJ@A;u%#!j3#eMyDl7*S1?H6n#hxfBh(>fq+n(fI=Lpvjk-5kj^x{A<|9y1OJ z1=ZlV3qztGbOb}38J7CpqBg~y5zfgXo)VXA;Ekf+&t41&5H=?_JZz=71AiX(UwXh`{AkW7H0VVtSI z2NoT?(-PPLxe#a?XdF5VKp)T@S0|@xg{mC6Qmz>sUO2cW)HP*7ak`9O^k!m5;*sE%gm7Spge-635vI5JpS-1Yln z>tgi=^-i@=p^mDjQzKsy)&C7872V6YP26rysN`a(!4fz@c-ru?fq&FMb{fcZ!xFeATw(W7A2v85SkjoQ3qj^902s*gp}d~QKm|uA6XKdiV8lE4W|MO3Veo_f+xWK zjKKcK zoY_@~vPOclIJu82_Q8lM7OZKrv`ea=swS(g+pIjbS9+|1)jD3D(fcg=`7(wYmCxr2 z74(+LT)j5ab;mY_Sw(LMgNEjjDnbwrN>YyVO1ot3Q)`#?E@h?E*Ajg+2pg2JxWY%_ zSzB7B-!-?i;d>wKzUkDo{N4o%ijEDQK5=qz_I>k81C2f7Z+fO>cJ};rJEE%&uc?yt zPP%1Al}@3pnz=F7JFrg7EPU3Pm7;%e*RJgk2V;wB%cqX_G?Z`gmglCF&%2Y(!h6ul zCdh}ATOqn_T0^&f5wNKQ^i>(IVi)gF^WDycDNfYH{M(DRlo-CB6a5-%OrdtDvmrxz zi!BAu+cNN++UBz5+61Ld3n7AYFc;)KkubhU2?>eS3i|@?96%1(T?!?d{7{`-UQu4* zC;s=2AnL@+WJ>-QpFU4n9#kVGzXD_YxzxIbhK%OPvg4PV1y|L56DCjjrin^B8$Hvs z$C8?s>SbiRDPhLTSN?Q7GlkQQ)wR%Uz-Dn8`1(GTS`Bm%ZL`WN@rBb3>PSdO(EI&i z4e0{vgX#sFN*B|BVF&O%t&*3iK$HVcEgIg1MaGU$GwnK$4=S`cSi_Yxo(?D$-P4c* zB0Ko`$O)X7Wv7v#fb8LTq!L+AXCL;DY#+ws<>voL1?si0#cJ9nqI);`uA5xvJje&W z<@v-TaGtnl8%UJFZAkG=KBLd;>-PyN6!;509>LaY)?4YYnDt17k7-#be!8Jx*1)Qf zpibXm&dBziNZk1kOqVnNz)DGKog1-ava1L{tkZRfElEq!GY{aYo0w$@twm25Sen3E zNv~&}ZWOSn>Er9LPM9}#!eZWhT%QOqt=nz&^`dXaAa@B0kLo28V3Bl9VHoxMd7Iiw zb-K=K&HUHYzoqiO1fd%hWD`Jj7Bms!(B($~5@Ra0m_kIsv7||*lvGAcPtnjffUa!o zN?j@_hmuEdhU?J8OLipDnLTy&<9*@oKw##$vX1)7w2?1=0m!RHjqc2XRtvfzAhf=@ zJm=8nn9=x(&E+iXipV0vztW_nI@M~gFI_35(ECkdw=h3z+5OWKc`RB9HUs*0P%K)t z=o7jDFze>1S#VTO#+U>gvkBzvK*D)+%_jKdJPsuUr|I6Kb{;-uZww9&E2t@Oc;vHD zTL3eC81GEa4?7nV)2&qakPjPh@*yWNIf=fzSF>6(pczED9i4UqJr1m<9=Y76MaNAl zkhH@V?TE)x#w^JPp0H$!7;i0AKH&YgpIH0T`P4guG1mRc>JxldK~YK1T{HRU$VY3} z<>c`1U^LVMhMeHOd&T-L*dg6cIoT=S4|tQXM81($y92ld6N&W$%m4||YW+6-Dg7D! zIla;dh@z~UP-}??cS8@s_~@*RhGs^Cb#OB!LrF4%F*(Zce?NGF_tO88kwgt8x__|_ z%HLr;MsAJR(xoH1Zl{{;RPR?GRtq$g#;etGeK$u}h+Aalz}bc3{J43wc^hooGv;$< zrO`~3)Pyq`V8iKdSh4E{2LpoH4>(xZ0LQK#T|s4daPaCd$1I{WR&;H{N@7o9SGc(j zF${xkuYxEPs-z*uARdwQp7f*Xa)nAY)|6BAsBbjoBpow4V`CkrG7RN9-$?c;Gv*#j zJkJ{+dgOF}#R!bK9~92MYtE=KXE}7evmnrQmY>F04d8c42me{Vbrw^Xiq!7(MP8%# zDKD>38)0#JTs=m>JbCDHw^A_nrjB)TBnNs_6<#gw!2oXb}3I{m~+6bJhTZx!hbU-?4$B=C!=$cQ6G@1CXEiyWs}AAk!|jNEsmxUaas z_+s&uVtKJ>w#7`kZvDbgUXKIdW1|T{Ym?p}=q(vNaw*0nc_R{Fu@rVD3j#l8heu6(lXu?zbjKL1EukvMYV1nJUFd*t)`AG&a$?VHObOP*M{>WRh0 z#f$L$$t5NHZy1t%;Y&mqklf=3zWAr^6>lg0^cA_n9S9I6~Xi{A|Js)U6Khxz)%vCqktiUlnNBj1qq zufEp2wk4D({j%m9dg`$XVwRr;z!7)6 z9@6V$eJ!e?0}2XbYR~jqpp^S-2_nqMPsO6^TRdiH61`@_2?&U|4c@nCSqo@Jdod&0$ylTsJHwr?g( z5THS1F2w5XTn6eV(34AW`?{yc<0rGp zrtIC>e0H`w5JxH)CDJV9#T+OJxOEMV5JDuCN;^P^Nq0mFo(e2H;=>$BKT-Ih@Yl^N zD(6LW0l{9As3LDqy>ChN-rKjKR8$6JTefG_%EW(tQ8zo{70Q;bw$-|% z&1vF_k#}du5>H$5Ci1!|V&YfEEDEM&h!+j+5#b6kjalG0*awtkyOP9}gpUfH==>-% z^0)(On@aXI^_Hoy`2JUaVMGXYgnqeS@X|AKL(=NW)MM5qjYm&=TENwc3L=|ztF6X|X zMj^bGq%V(=n0}ASi>to;928>E1}PZZs3*^}2q8ua@sd>>8EHMzHDN(RCgGhACyt#` zW{qzjm)JqJBzEx5p0oc+xPB!3vzGkoqc^8w7a+FJ_^TE0#_3$agO|UKdo!b+-U|m> z(_{qEftI|YeNW3D){=)&Z=p3P!2qekjh=cDfKB=x@n&rd;S2>j-z%-OV+ViMN{X$k zt$VG4(F!6^surncFd7UNXcVGXY3ybhL2B;X9rHDkhXZ#G#}WfLQ0Ic`19tOx4#x1P zKTb%P-*bozyq%aqKKwAza46Aunw(C|c$+Wd?IVAppKyl?M?Pkscn){kh&%6KSj8T3 zyu1mW@2l`nH!kX%&hUz7s)fF4l2J`^bzS4#mGRS6WOvo0RlKo^sH&>Wp?J1K6{oG5 z5at~{w&0`vA?bLs5PH%PXPcbj5l4M(mVg`G3!|<%)dbl9;gU7A3uD2xE2G<6A~{n! zy34xuE*qZ~Zpts{h-8rrV($f~i*TAb8wRIQ+5OwlBt#thjE z{Q$FJFX@$fy21zuGL8x}UZv)mG@Uw?pfxIZ4YmtgI_8%m<%5Hb)wi0J%+0n!KuI?? z!5^R3jwJpaK%<4j!Xw`d@wb7I)ScM5|EsO~>3Qz&*Q*8d0TyDZHF_(htbv*(IH z#5Hl#GEZj`F%wlc#!MVkrY3Wzk2h8uTa2@eg4*aZ<{AZ~*J2#!YIJqF1cl4t%0|mO zH8HbQM3@U}NuvsErjjTg$%}_pVP|iUh8U>(Nxjdo-1L2g*=A8DzTTDio1Ff1@Ha%O zcUX-w1=9C=V)#thZm+5?w~WO3L48SeUFvW@<}{kwP*Z9$msC&i@jtmv5@(4ZScx(r z1oKL(+57HO^6Cux#R|sz;UJ@b#Oc9OTE+lbqNdr<6%Bx6E z=6Fg9lPu(YLqj8H!5oeA<=tqsrIE^ z&J-LD2h0Y5!opnkjx)rX3^h5cCiKnt9yJst`33FbdXmGdIUHKO^40P)a={CXJZNuC z!k};p%ritDS0qm|nx3G6LD8B**>EAt6+6K}kfcta?o$C@yB0J|}X#mDt$ zV>CeG0*T-Us@cV5Vr1*YmLR8XN_Xn?)=97E-qZ09>;6f{>vR@>Og=q7BcB-a$y50k z^Z9N0q%WU{^a*c1uSktqy7E%EY&5-dnu6(ZjozVUSbgda@`DV5e#Q(&ym8qcUz;vd7hXt_q*RupT2HBd(PAZ(|nL_w53hI;;paSM=8nNdSe zbArR1`TUY-fbfBJtV$l;$)uO;*wFB?A@cRm06nB-&2%w_X=MlaOoRm9GX*&8G?gx@ zody_gZ|b&Gfq**Jr4r&6i`K4|#Gb`Hk^)HciDnzMr7&5LLmEN?D#A?SFBirqPstk^ zDu_>;JHGYSj(lu^#Yc>31!?3{x(__X8Rk&u+D39%+L?+bcF&8&1}-|Jen-teqb9;S z^&RR5X~2Of5N{yZ7MK8FyvR0eR=!V9z;sOu6L|#%Rw2j`m)j8okq&wZUB^~?bg=>6 zz<+F;0Ckm7fWTLYlT?IwZ$461X*JO z#UCJPG><|tCekpO-F0=K=CIlGgv1`cI5!NEK$S_81KqO?gSZ9pNrl-f# zd(-!(pG%iT(h28?YB-%q#}Dc*(d|T$i*Zda;#_i=Nb!^OE*!eJ-sp(aBUef)QwkA; zf6@93yPLX7m_H;P9n7zQab4zP2rp`8*YSLe*gpA%WKbs_0WBl%o6sv#i@IV?V>Z9* z@yDjzHX{TbF#L5%eU3Ttv^f{?V&)sjsl}^96ek@F;9^RYwyn&Ntp=-=91(MkA*!E- z00}wiJ?%Z~z2cP(P}jcSix9U3y4quwhHumwEpY=g7+6L)2{xc&kaUNEKfn#Z_f6hF z7_&^1F3fU5&YLX!B6$b%hlDSNhK6mQQ*VIY$LRQ}mc;>chz-A(-U#*TM*SNdw3sO7 z+A#ZW4lNo`Mzq?!*FESy<3=}Z0|uL_mjkXmq^{fj`4bO(a#sVJWv~Z>pB6EbZ0=^U#U0aN%eAqvi4XYU9Ai!> zhrgI}C5MmZ5ca^Ni|RW;vE?vn;}=cj8Ph8!zQ9DZCbx-KP+!5Qw|kOUR+?^SDg(05 z*5jJo&~D{em!vm6Hj3gwPiJaaQJXpwfk*L{=a$buxV}l5xHvRKteV({fd%vbX;b4! z?za2(Y~8l!zO540xPJTVw^4f_QMK+zx74-V|MB-e`k11OPt*IP=feHi5oRD;r;0Y- zY*wZiqlRf7qo)ty5dq;7>f^Wwu{0@ZF`Ke0oj1i(QaBejFza6dO98jT^dNX~SeXPB zF&gSXLADg+0JNB%(td#=*r38Q6@Pq(_zOEH;Mze4s0y zyfWIlsXY%Ge2{b&Hx)U^;vRa6G2f2$e1mU?6YC%LC54)?z&f$uyf2}64=?D-3#Xym zU2k|BaP*lTN7U`?EcLnCJgKQ^ep8&wHRWdH3c1EKZY+Pf)Vu|!H&%*PVP5UsGM0LM zOqtNPv~j^|@|UhLnkNa(Z|v!E1FLysvYhCK4ll#6Q)=_1uOV?A6L2(QHa2`BA>J%- zHYO@`!dR3<(k_GD(Fa?$nPyHbUwTaV#qFNzN)HS7XfvDz_G_p5sAdSyTLz5Dcrb*M- zJkYcS#)42mq@bsuzu;uS#R8?xmY*dl*?=Z9iF z?$^dpP{s1JC~q`c?TC)~FZ#(gKZ*E>35AZ9sI@cGZH~)N5`1uJZ~?EnB-DIJb~B=) zz>aG?g*^h*#Vnp{H%IsVnA^e8a(d|M(U&M0lG}X~=0*OWU(=IYa$pj*()lg9F=I!M z9ZfwL>}ZDIS_<&VceiA^z8jPA#%@eEY-n>8OcJ*spK2QNRGAbRxPJv{8;yM8()7ZJyD?*o`HAK*3x1NrL&6)w5m_^dK+7PvH!a-1y;g_#Gf4t-$@eHHOF_aOaJd|YkPFqSKsYq)Z=G((gs`QfLEgafdLQ zeDw6wkOusf@_+nS%KtBa#a|gtlnAX?KE?=@T%MSMurho_`H72)D-b&VM6!gCP@YF> zWrq-yW3_%TQ|UjUb@+(TK|d2Eci(e2-8D|(4HAb`>$rgE>@g69QP~5+tCPypO1V<^ z2+=*R0HT6YIYQZDFIr*e(lP*Lz+ea#jdSfbrl&eo!W)kATW{N3S$oHh+seM}s<@Pq z^pHMslAI=TqIev)K(C5%GW;CP ziLc2f?n{ie>=n*{6|!kkVxyPtXP1VjipbVWK=~>0E>E*}LEHoHM41Y%zRz+ad!M_E z^nJc`j*fl{9lZ;4(!u5=Urb|j0`|;4dB6N5653~h?2~hkXs_M^%uQ)#5X7U5pA}!K z9I5HX-L7#(L2w5SmECs79W|A=ZrN1fz)6q!=09TBc5(B?7%1)bQdYYjcb{9Z8f`tc zK3l)-r0ulrtPKad>k)(Q5st)(L>P98oI#<$^=stPJ#M8-1oA-|nW8rev<4j#1KEu( zmv8h3a(L{*jl4Ye(RIr>c18a$QXQXi(4LycF1MNsC$1O-}-_KV6 zEV~7zRq?o<3PC9yw=`@T$r&B@=tB8Mf4E*Uc+fI_hn$QR8J)3l+ERXWZx9 zm)yc3_i^`IZUIxzXSj<&ebEcQb(>pZ9laBJ9|}7EdkyCdmka{E9e&J>oF->!vX;r3 zs4<~dfZY$ojoptVa5%uEJ3@$q9%G}oa_ye3lfvuoX{=0+6;H_LW}H7uVSi}B1=O(@ ziG_2B5y=oEGU;i6S5PWW$y6%g_u8+tJd#WswPd-LbZW^&Ey+fr>6BW7()e;DmS3l* z2nb6P zKd$(!BJm!nz&Fw&{Kh*h6NbIVJ>>g|9uM8SbktigYCAV5uHl?yz&Yr= z<4!@PKV{Gw!3Qm~kgqJ{52FlM3oT@tg_K*GEWG8E$%dR4Y(UxTa*YOwb@Xlo_Avtt zkOT5TfL`P_t5$c?Vm9dCG;%-&s!l2dUil`Hl%w}F=H?KA0KK==Jovi1T!TjtN|tq^ zY4U)5^j=4A7*FseWOCwo#b=d?<79FuM88(z-tk^=5Ad%yj({i6MfU1_qD9!(#Jdyi_)YA$LNnltzV8m!j= zn8l$k&1izohl+oD4#i}>jYXjeaj6iP1$q#d+@BTcDlO>}0|BwCq_iuN#eWf97)eWu zEQ~fSjCeeeg;?i(SAHk|9DD^j)Vvr5S~rQ}>G`J|M*T1pO;lDkXE&81{fe3tMa0250F8N~>ej|mu{~5*CEE@4=`jzgNXYt}IU#PwUMn??~E{F=f2seqF!|fJli^n^E-0V4C`eXm`oPj!0TqD*D z)(FKpVh&$dlao_ZC)g$)Z|;fowDt7#^!FSE>h8Ga$J}v~EyGr96Kv6;nJ+aAwYegS zx|G0B#Y?`SLYFXPd`UUvQodgEnRp zLLTyDP-m2mo^^uy_TL~s_1(X{9F0Hzcsxqp%>puH((1|C{z+?ETh>eolIN4ZdB>06 zG_P(+{$_IU3OD@elR^RiaJ2og$J+6yV_(pG^W>n6|KSfwGl~7+hby1o5Q%Jfe&xz% z*Vompe|Dt#hlj`{_KWA}FPN|zQ1TTTFjxtc`F@KCbhFOP= z)xoVL!@|29825f81IXr-=mi5XuZpOiQXN%ESQ~}nPfww8Ljh1dY!@yRlBggk`yb}} z9g54fqD`<>NjgZ``Y*p+pLn0oB~P{{4kZq?lEm2nM8&Y@2~&!pVyNz-jG<-N@kPUtqI!A276kV5Bnm>$;d~zK?TJg zaOxk2O3?3su>O;Y0fZbVCn@aQ9}xyDQu6{fC6GfnkSWUuC8ebA)l^iDhsS z?Z^k%edMPkEAi_W2M75}BR{1KrDV_U#ATuYEySUb;X`!PjTp6G{vNnGcZnvm-rkoV z^c!)8`cV+=rju5uHpJZSQd23(4R}PYA?C3K)@PfuO}Xpy^m%>R^#nsx-LCMxfW`OrZEr@!w9kY*`Skm0egg=+_WGYzl3Kynh2!vGAV#gy}-Z7J@kK?OzPd-T&847>R+hJ6K-$~^Djqk7o`^7jh; zd(-pX)pP4l?S68%wQi=EZ#sNHo7*_A!Hy?>GkteYDFkglDpH5AhHh3lxJgVY=}WVi zj5np&Q_}D+>k3Xe8ti2qrV21Ka(M+MHWmR7%lF@ubz8YHWxd^E&tIEq$G@zywE;y| z3b$VEqVtek%F%VC!C;9sH(y#pX-R1eOlmJRie{EtONAM~2Md5>kw=lHNhpcD+L-0{ zD4p?0*$gr3@y92u_~@f?iF?M~_KQbC$G+Kla`X6+pD=dILr1E%Go~P&EwgEPjGXM4 z@{^BuC%PuL3cF`Ly?x5ayYiu`RRf778PPTE_w9y+M1YoSX7wyPk6V;Ex(RyulI>6n^iZ7P$IYa+q|giI(P8&^dIDuAXoAQm>I!e+PGXy-&mGcw8$ z7Q_z79#=N5oJtCVS+ep~)x-^R8!TinF#-JcD0O-u^Oc8Mc2!s3Icx3Et{L`25Aytj z1C|-PUcPzWKwCV#Q63z(V9%`GMuRR@ZOwJ;KKgP->cKScq+M@p+U@kDJBn1hxBPr> zYktWCUeFQCxO=aBE&p8p2BgRdd|iy&i9QK@Ra44wgTOI`*1WoDZ_@y{;$&w*pk(5k z3}_(H#LG%Dj~iv=qU?%{mo$<|@rq%jAO#SpBsjmV>Ih71-Wnlnu-En4jtO*T|Lo8^j{vYeY-HWMMwi!>p_BnpPf+X!@;e)$HTp#-^X$03Hm z66j?LMp#uL^-hv7oJz`2VjXvtN~15Ms>mZOlw~(9YZ|}2y|`#z$+(`vG;wK5`Se;} z+3ee*=B$bZi!*Ya>hjib%0>qou}t03T^#8A-hzKMr|C8sJVx?m^~$Lwd2M|Y7aZQX zG&}KeaeK8-=6lUuIx#P?+}ApP6Xfb$;16~~CsC=YfE{;2yxBnP-CR{w!TC%akb@j~ ziX+9Ghj(MpjHIpx^6Ov=$`lW9{wHXnT8X0l74`U+?6}%^3|1b*Vze z@GDbqpBW0xynX7_?K6ssW^A9jX6@QFH?LYX;@!6o^B3SRz-yz7&l%hg#5vqsNFSQs zGM`eMQJhln5EXHS;8hTr0)6Vvn0cZwn-wUb^|`M=BvZ(w zApJ}<3y7UY;FlM?YITMV&^o2?Gg%6%L(hpiJhYiXuVuGLg^Sd~!^Gm459cGW9HMRN z!Ied4R@&W?(}CYhxe|KZgZPOEe!yqwsbED39OL|~@C#&V|69D~U0yr^>?1odjqGl4*=2GeS|8+Z_LxgT)@JJZrKhJ@TJuBIAwCpJ$!*mcQ(C#JDQng`iMj%% zrr%PeG~?PCS0|(O957ToQlA$@BCOykVTo%qzv=dOc1|pqym-U5$eK6rYaf2wAx@c5 z)Vyx)l+0Mx)SLGF!dg9LPFZ;Rq?#1}+$Vl<(}IDmvuo1Z_Irahx(dPQ#4 zqA3OZ-NbIo^E<4*JZIvMxT~o+<3Gk4XLFko@I`BB9z9f0O)U!ZM_xqq+$$6Kpo@HE zCcih6GiEYqCIe=Ku!%V|lNe{hUNuXLP=@9OjMG2NuJ|6VxITGB8pa&GVvU%CD^7Be zOJQ;*Ox_BU<6$xoCJ%;5Z`F=40oGq6CCxF!dg0GZW|x4*bAG4!^_Wq^4h%}^*8OATyyWeI~LWpO|<4|Uw=>M@LG@PoMz3; z{cjDgEts?tjl2hNj%Wupm zq>TKR`NM1E6EDBgH%iJsLU}&l1-dWDv|5E|=DL-O)SS9lElTJ{AbwAYMwHspQdAY~ zBq4+OI|_4TSYNCIOFQ|@vQ;Ct6SCffO)>o6GUdUq=i=(kz!K0}H7zhtTGg!8V0c5| zpQCkqFTp|vdA*WV_o|IheFDm18OqZLE|W0?_IO8jI-_?4f#OSn8qBBhE{VaOI%d`} z4ED|Z>X8AkUcSbU9~l%LOW4*54+!};9~w~)Kf%13#r!T5MyA6SD;2%G91W@N<`ASO zT^woQNF_(mb3l!;b1#q=@y^gq$q&eLN^fDu`v0CjZ*F&bxG_7czSKjOPoFnu zHXa4D8%jV($(hibQh}JQpQ{l4rofp1Z<7&)jL7uQyX{16Cw7x3!^3-AM=WVdq(zxz zVTBPOW;uCCGc<`kd1rsulahLsJ2G1wmfEaveb7`o^S0)!7N@PwPkDkv(>Ez>YV|&~ zIXI!S@ba(b?(E9ds`jZ&0kN}K9>l{OdQOtfFy#XnVUz=}#f0=prb(oTvJ~bEVXh;srn=I#@WJ%biiS|2B9z0PNLlbu@`>+! z#k_~=6}S$rl7pU3bI*2mMTcSf>fcd zRIO6!WiKeL7K@pC!Qd4_0^ctXmQklQESHqTh*Tj^iKEg_abqx^m`TMfs^m^*bINSg zN_b0KcD;oU5;n2#m}3(ErE#pntw!WO#p$T#=7>o2sO2&xEMdj-oc4;Ah}t-M zybNkjY2`+32uv@}nkX-gic_fYk5|5c7r(%xwH=G0)JpLpDcA{H0pVrT>CkeIWQ34} z)q*UNsF|FoBX3S7y2RBxvjv-KM}n?S<_&iP}BfWd0yj zMwXbulcTKvlb2Dlq#q3taP%2Nuy&GtrOJ|jtr+vyZS1czMduBF>?0y$_qh7USo+iG zC-;HEiQH2}%;mrc%^!81cJjrjg9q>gqQPm3QR$-5^y2}gphAw~KIB-Kc7Rr3pkN8; zFKO><9TPuLl+3wz;gWl1+DxwW})w*Xm1D^Xsqdz_rlzPzM*~P6fSEh~fcC8M5Hoh5EFqDOTAr zg}0zQeSV_LHMw)D&*qvky~~Hi1_u8#eh2I5=R|V>b|rMvlg5<16dexh%*pT2rKVV9 z$K>9^inRF(1-leF_;uk@)Nicf`w@ZGQnVZxEYIt_Z4?~s6)9iDd58Lf`?tac^V#HC z1hWn@i|HJLTfIIB;&?gQ-inVKQxXpyKtkgCPyN#mpL*(t$wb7;mCvlJ`GW3s9pB9F zk-r9=V@D1zPtBj#Dh0vWo63i}XItH69H`8`|qBzBWc_ijmi1?ni9BSrm~pgDD_k8c?H;HP;D zO0_aGcq9 z!SieL1(h^Y%ppKmNjh89J4hCEQMb{CQ*SKM4UGu~X`?4)c{!=CUC~x}`1_Gf1*tW) z)hW|@dS>ba!GNK`2bKN0#a1O-n;k)2rjamvV-j1e zEEv5==+OrIK!XgFYyA;Ul4xHF$sX7!A6ecW+h~k;P|tXdx@Bs&zB`m z;)?&VdExNauv|+Z?Q0Lm&tx(J5Ua*}lyTJXHZ4$r^Q3^^w ztB_HaHVjJ?z<5oz{b6E&WtR$vAPzKu1ZR+b6Oucthz}y1WtI9vpq>rWPCCZTZOU^5 z$9XdAiqrC@EQ{Q|-<4PCbr<=e6MN=2$C_Il!3v*oLj8l45lcp4YDz(db%Oj|cSUDq zpsqB>Y%Q#qm{&EYK5NI?yor_hW?Oz)U7&JmMcT;H>ZYb@PjN8AsK}f`{;i_iotKra z*QNOj(#k6!RX)tzW@K9^D{!@#Sz`f zkI=k*&(EDPd4?-DoSGG@hTrSpIuqNKZ^*yI$*x82%ZVey3(GeM-#-M;hDIzS@Nc5r zR5Z@*<8I-$b9=epi!;X+WTaK5OmDw+b>F%r3m4wLb;auTQ|)Kkh4#J`EBe}nIlJ5L z>A8o$=bpx#EVXk^yrs8=Z)urOTf*t`>YM7aOLy+s)3<5K>eaXQ-rCn0i>>b4*2mB5 zBYjlV0!m%1udlbewe_xByuG2`NN-=SthbjGq@`GNRb@V<5im<^6KFgNwxD02Ug!e` zPXkL2`+*iCQ=Nmp-|Qa+1<}{g-zI;Mc({Ifv=l5r2a+3g_NEG{I4g~6cUGMNO<6{5ihw&Yl4!XDB`_@qTx^v9B7wIHV} zQjSTM5-3Wv(`LwS+L*v@AJskxRVjpo@ceM+aF_5W-{b{TN@ne7&+nezk=fC>wK7r{ z?3mc>jy5$$qm4~bg>ATNc)IY+H=%;M@soGVoVcPnXma~)$1;n?he{eJlx>PvC;nVF zX;PgyX%fZw1F_FfqxfmQ0@k7uD4$muo*;>zM4STA31}S+qH)L2XGO=gaqGqC6n%rK zj;mHh8yZrpqivjtm`v>h?IhAp!qL$VAer&py0*4f#DG!!LHVfTxpGBrYi?_$JRT#J zarZI0Y)BGS5ncAMED{lTIi7& zF0~*JkJcfhIRR(bE-cqqO_^0ZxvOaTbEJmn#qDqH=zE|mQ=`>*y(#6UKwx2c>BIsn z9@~ps#~(Vx^GE)&zaiM(KXd8#*SA>q2p_F{c3tg^Smm;g@Li7a-lq~@zPGlbXUoK# zIWt>Q3VlXRzd1Fnv@yruHD_L7UURvZ05IgNv+*sr9B6M?-BHx}_}RO6Q@aKqvKYLX zOm2_pK8h44&zdx6KIbEkFk9cv%zYm%5o+}LIIo-4P3ki&ju<7_Ap7{4@pb2Y*NqDe{sjyP1ht2R=T;s}+Ax&C}JN;$P@8Gfri2PNsH)>jkt z@AIFxJUy_xAg4BHQ>*S5^{k*4Q8)GS~|BDlW=10GPZg5OdW9&uDmQQ4QuUwzPMN=jx5_tc zx^?{g9j!h}5^)ufEl0Kwd&u7!FsPHp4kWFCMrs#Fb-P)3x zp*D{43F6fVTPb$YosAC4(yQ_J?A7A|6Th`E?8qPUYHsAyvE8-#S;UQ3>t8~e%xjk^ z=_?t}_}r0Cg~w4dluc0|i1E+jUQ52tRvXr3j=nDOF>(T9`aScr6Cz$084}R%S>VgC zSjW_~54KNCEh}Svo{@vx#t}HGagK-_@nVaNCP~nL8Sjov3DrbvM?U2%;JaC2Ba9bw zY&%dZ45ieAG-v9LV$@it-$Su6#d48>CojpB3c2$hpz+RsLV2sP;3%ygHGf8P)*fET zD*xEBmh%<<+RhRrTQf4MJ4%Z?>-_7)lF~?3Wr>(L5^k?dPp@nXhuiSIqHSDRO-&g- zF|vKKrTk~GY4sRcy{NVq8$^I>&8bu})6}L|YHGe7Ax0Z^szR=l>muehbB|dtr*olS z%%OQu68eBP&dm>hK-uZ(Hk6!MG*qX+1S)=#Jd(kyP1WnX9f{xFa%)YMH{dM|jh`sn zJ*JiVEv;+4lO07VR*NY$Ef8e9l!#U+UKx!yz{Z+H;|(-wA;*fsPstYeJym3N6%nyj zst5>7s>nGn8T1nG(H640g@`T0*g|6%G>B0qtr5#%(JMdwEmv-1S1uO=-+kd)vU-#_ z>4pnqUcu0)2;d~nfUnRZ768ty&X`3={w(#9@>AvHWI0(~PD159<-89KK+6mxl8R;_txIkRozw9)qC~6FF+S-H`vhCZ3EIRRD!tR`T z|FZdD`s3GEgTdT?@F4S^Ts6GZ);ME+!^JnR!LNl(n*5pkDMnfWZ@0ofBM``USxP8u zLqwoLl~%Q@YG2jiDmjWCE|so)r9A0ZwZcs4>+7Q<#l{9@$GAC};#eP&wsj1zULX6| zs#m#k@?Fmj^KO4%cz$^CGaV>{Fubm6l^t_hBZVWvjy-#})2Ckf+Wp`=JE*-*=M;PM zb@S`}Gj3ln*)#E}1yuif=FAzW6u`Z|G0eie5yM-ZVbElX4Y0iqcG$rVq0Zh>ysmgl z@%dsYRm_B9tyl~W#ABed&}UYZExPY<>a<0FMs#&ye)m8xIcQ*P&aFFi?8!bD`u!858ixo zSKrL9zHz7Y?8UCb$D0=2+baUGF08#25$}O1D`^E?^ zk4oAQv;?O1-B>et-;LErR}S~Cot$@c%&5K=?Osu zLLD>v3ht0U%j@n<#=ODa8?F!0Jx!C}yW~;+9bR5bBBuJQ5m^#Il_DC=K4mA+i*9rt z2SJp>;ofQHQOxT3)Lbc!3TU!jenKV+(iN}Tv_8-u0$JW zRF(D4oSIizrP8D6^82wk;&9^@PA!g=qpc_XK;uGIHGPL+C+?;=;Zl$q5WM*6QUl?D z7}#PEs&jubzYdXMR{azDrk@-}V+@5Sy6K*2Oy^7A5v&|nU|H_~mdWoetjh~EXj)y_ zwr$E=C2eIv%oA02Vo zkbcZCy5ssc5u(&MTRdkahF3jFzdnaw|BWO0V_1oCJ+BJqRs=R7hHAWrsnSeD$t3V- zFCD2WRj#r*z|aJnLuY6bCZlsO>e6hyF6|q*mn#^Wu&)~zAd)c^45eKjxpkoEwI;T^ z=|GdXqlq;&;r z>={>|a^_&ypj-{Oo#AeMNERRM9y%ohA@1Roe^^I{E0pIdhDhGw1tFkf;MhRJM;m1p zL(0#BCL%}~lfGO&Zb5l>`_A5tFWi;r*!udt!w08}*L{2Ky{~WWNZj?p#@?On-DRn9 zQ`aZsRX5&uW9w~IFIU~xe&hW&R#ha|D@B}I@}?Kle>`w7efFO=*45P1ZTu$|J$Qhb zUc8BSxtMm}>3bje#r}DP;Ob9LE-sw6{}&J3d-}d<*qiX7dGV!MkZv(1B(MhGIh#a@_^AAELV7Nwn&qFpg8pNAmLMl=34Zgq$}W z&-hr+|A5&e9yeTx&@HmeQS{*Tp%F9o7`K#d$D3_b2rX#DQ7*BK=^fuc7b-Rzjb4+2ke;?-=^|<(Y!r~VE12(VMprNzyiG)43q$^@$;x5}h z?27o!^FSx?zYyTrW^)7w4a;IetOgB2hR}FLLC=uAF_w%mM>Hk)&|$@`!2||cwg<#b z8kVvqXo!UkQ5W+Mc{h7HLLf6_;kla(Q9-q#)R0hWJz=1E#Se6ww#3WaF3?&8ivaf3 zLk%&}!f9mnHU{aFY}_$+M|yj)C?h6p`CS;J zs)aStNI3V+Iy%aiv_VfkgevH;!1aV($&Qys3ylDdoz^f#Fp01x%K-zNF1)fRP$pRx z81diJ?=bIMr*tZt-~H|=i{lq^^8%d-2BrM(j&j+2@WEBAE8ulC5CeZD`Y%?Sl)+$u z5%e7eQhs@Pbu@1ve{oe@NR`MzQz%uSpyd!a_rp>?8h>OP<#Z4W3CD?Mo8BTrTn$~% z0lXIXPg{_VL8cr$?0d2Xu=k8*CE**8vSv)roDJXAd*;kp*!I-NPxdM4!^gny>bU7! zA3ef*=RESKy>k}7$fUhGwd>B0zjY(uTCkN1&%(Z04;Gd(VR520lGmm5U?Rh|u&D&Z z3sz&NslPn8*Xz_GiXoY2d&c?_GCg|I2ds5w)#Q!!7VExs2On!@ut;BEo{%iRs~Q?f zqovu>0ee@CjR$nDAheMC7e2GK$C&<4B3-e~-ulf28Dfj}z*ip35?l0rsj2Y`p0-V| zY}c7rwtVmAhCiXVp!G_-WVJ%5q8#Db#B`H^{fpsO2xuAEyT)G{#REq6b;dRd-x5T- z#cTtT06goaZ$UJSDP{pgtpMmmOzTWrOec^*Mtiy3UAghS>_Y_7H<>Gd*lS=^! zJX}7LXm$l$Xd~!zis)h^I!$IWh>5#5h~wlX)LNS8Sg{^~#@G}EjeeL$X82Zfp2rz*6LeG zLcG}?uw0OvE+xJX;u;P+p{IwA{eT@=uLNU7_VbRS zSWqU?CnCPk$uI5*%pO`$P>>qx2d%NlG16tw7B{@F=GOGcNoGoK#^&+Lf9l$F$4Ag6cgX9c{yDlf zU2d3kEv=&X637a99OmOh?KgF@d$g^?`HI#Y0kKS+F0O#4DOM4E48(xRV|H2H7AKk$ zzn)PiKh)?=uwrs`a-T%el?UpiYl*ws(t%o0u<$@f9Q_fIX;-LN1y`}?nJ7CRWkb<* z(OprgC&~ou#a8H-%LC$NQ3bcA*+5*q5GT=lLdm#5b@4%>@pucWfOVjG3nV#4+i>u3 zx$3gz@+Q~gvc|cy0?ull+&`*$uckl3Cf5JGb$>?xbR8s4$vXo5L#fMph%;7M2|bJf zPjVvR{Bi;NaxRWmUfhi#+VQYEiAP57?^4}WDrdT zfR2pCDU%d*@s1+d=qWEOrbViE!=d;o@?6-+c-06$tNCt*z9aZO)@QvN1{+UI!NGLL z2w}!oD;<3jV^PnhoTmOSq|&?O>FI3?x6EnIx$}pcJjG2t<8xll8Q;@X?AgRVW-~^H z*=w`!UDRe^zr6o`__HmGcFak)vsb!Ot^N^ki2GYpUFi;KfW4UA?}+t}B=|M07A&$98^0B#rYh*p0m`OPL4ucz#7DfvT#OyiIfzlq z$Z)81SE(2-?I{&wB(J0?5bE<478f=Z9w?N-hi(WPdJHK84idF;iANGK?d+&7Nk3B+2pI3wCwuyPo>l8H?Lnlxx&Bc*d|Y5&6Gy@ zfZRB(rpR+AJ905?Vg2Km%&axD#Vb~%pD@*SFB_l!E=x9b#hoL+7cI_sS5x}1csJwc z2I9rMYNQl-*dHgnUkG2O{O9jd9Y(di+qX#%+SCsSy>y5L+Z-Qzc*N zVc~=T98#FhVxwO`M{;qUZwsm_B_D~p0ZQrfRi3M4dn=Duiit{AUCAtl0psEd)fP|L z^OfkrGEKE&L0e5I|My3D-wr=m7e|dNE<-XnXnAsV zS-F2fHO2Z(?y^vN6WZhKPd@_oBJWJD1>^tk{u?wvY|@WQ^|zNno7|^l*c66B#E}~Kp7+HhOMHJfdoBAcLF~hF;q;4ND=o_2zWw%OXk!D=#W^xacZMlmHLGX zaRqx}HnGGpxn8o1#}?Zm;Y2}bcsN>OzDI10yC zPh5C?Z(V#+ZOmp0H_dFU?VNGrwB`5qL~55lxq9A~-s09}58iNP^RD&-%W|5V>O6PU zFKo(fpL|_;xY}VYaQbR$syuyPoE;x+0e1IEk1JA^<15T{pi04LQH@89E)5t!v8-#T znfebDcdeMxxuhcxt-cmd$h7*Zxz3qCv7^l&ELhl5IISgSMwc9;zpN!{@3`@{sWUcS z(JlBaC)wfJoyyDe)CkO~|7w=XwlkJOeq( zP7}@eWi3GF^;$|meDAsr5GsJ;S7TH_JWaC`b$Y9+D&5WVI$~o<;IErktvU+YD(Y^U ze|>aPr`=poTH%h&UOe1-!@5LH!JJ)dn-_OifF6F~Wj6WNRTKTSH5INq>K8TTwoSfH z>EjdREv^qcYNy`NI7%BoIDX2lb7~#A#eQEb#|~O)pZie@EPD{JRCUfNtDZNl+#Tm+ z@}t!Ap#oE=y}8btoq9wXm&5Ks3nNsDZQuxm{d#9>Jbna@oRsa;g|(IspS34ZR}?^x zmH3%BI~`{rk?x2O$Hl_jLCeze+#$d-R8TOUEtE`!g`RLql|7jbD+nR*1*)6WI5cQ) zgH<=$TqPU)^SP+qMl-tEy2)CJR!PeGv8kUuzuDJ2vVG-Kt6B{g_ZZq%J+)@V6RXFY zq{XK86<-%WxGL*I9aTn*onQXZop=7|%boI`$y;9Bu;IlmlWAm>^{Ip>?gk@j6eFt- z`$2;mOT^9~b|RsDYJLu~Jq0<*Px9F_`7h;*YJNDs8vLR8`5v^=&^(#+k3KZ0WM*vH zk&WF;P=tYC1B#u2XETE1^~$6VC4bVf2ky0u{LuWBuk5(jAx^O0cV)f@9H%31KZg%# z%G3MzKTVMY^0P%C8A8H9qReQp+Svs=@;Ihl=+-A9gC*p%!}(0V>7M*l{^opx(TrZY z=z3-nhJ3QwB-stTRVtPjRnl-bnJ4GDHNKuhvS|{yONJ9~9#kw_tc+E0kYEjGs8@(0Y*k^e-K$%`*k`Tzw|5kLSn^jsx17c@9tm{5cVw zx9;I14H3b2`8l*A(;o8xdLI$b&J5x2kY5_iZ<$eD-CR~mvWS(ICa|L>#PbOjPE;p4 z66h7k@)P+9OH;FUruiHIi@F(T?P_lBR=b(n9qz8~?&;p#eZ2c@_b1&ZqX*0Rx|Zr0 zGfJl<#|N8A)fkp?AiI=FTZjsmX9#iXasjuz0)LG&MbKkAo1NUbuVNvfV>fRYMOiTmI<6YI*Vx-nHii z+_FLT2lK3Nd_O%aFEQuVWJ7n*n~2p+Yba7%uemu~-EQgMN4{Qq!wuIL1m-MU5EXB_ zP|~|~pw?=55GQ0sqHG`GLBP0gnuUEs@8E6}Zj^^HXU@MD#TRAIkw~>gPyBGy#9f!} zR$evKLdQF(!&(it&WT4Ro}4J|ng~42#4QuW$e^|~5y)ZI944DQCehf^*q#dJc%{;! zlu5Djnr+^a4n`q)&$P)9qY=K*_KDR=h^#E&3cxm6p83Fb=ZiYBjYDUv#1j27Q1ZVz zeaCBGaLj0K@3L=wWBb&p+uzt~?`m(J;n?)rju{s=Q<=YWa%1gOXWteo`rp#0O{;C3 z?4;6v@q&N@=I(}jIttTE@P zt8PpNMXy>`97{qRFbDMDF8`X92mFk`CJoxWNHPTcE6&KmV35Dvy6W+id0b0dyJ`O8 zYsa^)-m}Qm-qt+cJowm}aTm7@Z?d*F)V12~ShMzaTWeiIt98?`SaRF(uMW6ct14Su z17AI{al`Qk@Tjc3%{BPI_cwg^RJbA%DG&eTJJ0+>Bp!)WhW{aRiW(bD&=Y~y{gQ2BsZ(82jdE@flL|?LR zs88zaO9{)h<&ouEmhW1w7?+=$$z~p(b9#`Y| zISte&DOrP+RyQu?^lWb4Nswi1sLjo2>{cX6r9vu7&D{{8fzt*7lL-wE5BUJ(V5`^H zYp3RGAIv`mf-s7$SI_EoK=2=?ZK!T`8Tfk++{pa#~IP57DuUp%a zmvZw2I7IORWnz(JR?w2FQ3q`DU-^`dt5Sf=o}SvdZ`q&80G7|0HOcRvG;2}~M*+B7X%)+uHA9)9!-*w0XM_83&-2SE6QTobn0!bY4bq`HeiGphLL$RB`|_*$v3mXLDliKRdB- zvSfW;WvzEjJiaoSdS>&Cjx}HF4=2VocsiVA@wjW)Un-0jRy8AK)~3XyB=319uLayVxlSY?ge%tmicV_zmSK&zptR~#oAcyi**G_DRk9} z{NE(yjdJk2%kc5tU^@E$Aw5sgE?C5$Df=PqHWo`j=7POkeW`|hsfJakh8+~^N z`FEbBe+HN+4Zm<`2#VJPLk&ywSYC(>sq58HIMfl6dP2jY&7r-a;~^y!YN)A3c9q>4 zW2<7UFxC(g+Z>)<4Xn`9;F;pN)$=gA@icfm4R9dJI)!qrTr`%KkJH9Q#?_3IG?iYr zQO(StAytieiakwWN33!1P&$HYn05p;;&Ixd z^~vX{8<6lUU7-`w-;(Q>k7cL5HkOqC z_PoEcKRd~v-}t}A05Gz7srxfx%l!$zbAS@{8dY9vTF$Wu8;Y!ph!L_Oa#4vBi4+|w zV#;97(!!{a%0r(YpxQK)L-J6O4r}8kE7i&oC>e`mOc0Wov@=z>~Wke0ak0*bAjtNEc|-=mW5rlmaI zD*vtm&FMo$K67PlT~jM)P?+$U{0r%<@*dqu!nwt?iyFfE1rITZN=7grok+OsT9?NI z0EoxzNE`=)&=xb$dLICfh&wn%H-klmA1P@Evks;pH|7vKLqr7iRN|~{8`rh1`NFog zs`4dwJUClZmg1CMvKrh+RrrA%VfLZ?uK1Rr5mjlCgv;vaKtcz^Bpp(ZltOq5sPdn{ z7(E4mAl_pXum=-_$RXH=Q`)QRfXi+jcjxV(#6uJ`nCo=916AJcFq)@des$!W6D}jc z*hN8dWO3nu0@ABz(BPxSXU0eo-y+oas9m8PB_q#U6&Pz3n9zOn6;#$e$bIy7y#7tX zM&W*8FWy`aFdAbtF>ukcQ zvVTtL)S{kQ)AKL>T8#CKK0+mHSxKQf*| zecvl?f*sWGdPV9KdOhF8N5(!9|CMfIcIh*wMq$9eq#o2-hw53RzNTJun{0q*)D`bVgBl`E z2!$%X8dY*HxL>^VtLKp;!uNBDVvD=W;P$zT-ICeuPYEtV4*q0_;MZnDz))t8j0PVP z^01XaaR)XgSVQ=R@3iUjC@tkJL1kQ5S5KwilvBVj)>CE({ZddK*bD#=P6QraF@od^ zEjD6qlp>LLI!e|cFIHp_a*ou#`z#1Am<*`UPu_WT=g$v3nI&;3mk-JzkT}GrH=~>| z(6V!4_sk2^5D`6>J7Mya@QiNx$mi!r-b0h)> zjUi2~;~K{TIN8=Q0M5rAJI316uU!+q`P_4t!JD{i>hBW(ewEOh3lr^(0jg=58yk)t zkDZNOih(`Q*9p>${sM1OmeeGmA9BK2*rmD{H+76?hyyB3Uy^))EFyJ1n6_}!oV)QP zA!{feh=E`b1UkJ6pLt~)JaFk<#%EH)u2F2J65TQKi4M+`AKUR?7k)mbO`k|eEiQex zP$1l!=m{#hhTI%ez-Yvp3m9zqgQY@?fZ{-5S>fqIhAv!cAv1Vv1NOzSKu+*bF3ZjJ z6c`SZJ!ex)o}n6R!Yab5D;RP}gtn!iGRnjVkq6I~uSpcr@a0Mtm-c&JS;P5b5NhTa zAqn5#ir(xWg$@;uG~8R3%if8m0$kR7srjv+FCp% zeB+vR^$q)<-6vbxh8NF?e0|o@;3$KxqHOElS9r@@u;`+@l->^(zDFzi<|P^$v1yb? z^26cgu4s91ZhK8TE9af^+UgtYs?~;Y!*Ijt2HDuqP+geRe40ZIMR}j+ zk$`ttWc4)W1q86m?n~P5!4m-BVm20m_sM3ELfhpCSn z0Z#F$_Mw^Me3S{6k3O7h^0m(#8n@u_wc`f*)~wtRo;a<0#l)}}oVdEz8C6%VS=+za z6R2p56ohk|wRGIj^l-t1%3#;dx4&}e(u%K+oldGB~<+1LkR{rkH zPsv)uij;nc6=?@My_c|fB6^N<=*cc&pKuP!Ko%p}v1nHxRy)+a>TwktXjrwhmj5O;+*kknODP5|qVeGm0rdQMi^sas-GXJXC!C>)3{X zLV>v%pTC|I2P#1e0H06@lBQRNK;IbALBtLnEIe?5DbhOW^TQqN+@AEY9ce1W zd?PKu>m|O+rHP54M>86YO2MG3^h7D!j8>GQM#TT2kOlPQi%aq%DSt>9qOPtTc1gvT zvmhvwO?JCtP8lR+jO++BfpzttbtmZ9K?}UjFe~o_#q*J^6it1-3vq>=-=%{zYM|5AXTP%WVvPw=6L+WrsI@qbzdIvda zEfgHW#!5xldJ1nn45ez|GHGk2R=NlsQk0mk;*ld5M-1A5Y%mbgu#WH*r#_gRpB?$# z^CQ1|ON@^E_LOLOUbLJV`7QhQtB1v3j0E}Tr{c+xaoNw2BV_TA4#?@d(V%vQ;APIl z>JqJ46U!W}4zbwWWEM*-%@z@cvYh$Cnwj{Q#Y@ti2I-!X*h><7Mq;}qww(O=0y2Cgc~st9OVslD^yK~NDW}=#^bN1Ez5Cg|*U~qzp4Xlg zD@WeqpN*n-*)OzyH{=JJ`vejr{QdDW`bs=8+ebqa#J%7VAgu=DXG1G8%CU4&m{{ zN)sQa>6GaMlVsu}GL@S|iT_qQC4B&m4B@qUULRw-%nDi;9kBr;d*)ii{ReL!&)a%=bptUU{QP8kA-nFCXP2h0J8}du*Z)kXNE=8?@aSWjJy>*4WAp zcS2^iP^U{1_VionXSZ!Uc5LG|HW3rXK0C!0FB*9l(`DGtZhD>_7+FFyhOxykV{YMz z?>Q4zXBWYYpT~Dzfj8HLaG|Bx#azZ6?#JEFxTUbW+TG!ntboP4RRc9&^jK{+P1PdM zPP7yC3SP}C3ZS?g@^10&^PcdY^BRo~bdv`WrrRW1WmV&Vcdm=n)P?3uM@K*lv6GT= zl7*5PB?5Jb*0B;@6EQY7_<^yvf)f1nnj=Tn-1YHm=_Gsibo!5XvFA4FbGC_1dx_c8 zzUi3Al2aHZc|W9D-((2h2ugvDf9++~B_*ohRR6AFK8; z%?I3h%4RkT02gar8Z9#${U9nXi=<>GjIS)*H(4@crVQtY_WRfIOFkw{C?*pJgub+N z?}^%8@Fj*B!vcfL^v*l_BID}|g>LYa(wnktjI6Qqyw2~QgzAKME1S%cyVE0pa**Z@ z$xQm5XhbRuMw*X#`u#S$W>>XFg8gt1v`JNS)Es6;;}?%=^!9)#Q&hb+>@nCVxXn%H znXZ0Z`La_}_d13ckAv~vpK0^#=7nvrgrs^J1ZIZRFy?yV2-}q2rpen`(OcE9k?E7CS_{sVr&4`643n zno!TtYG8Pd(VP?jIh80i1xJPy9tuJm6x5x*;}!{%OBAlK%DD(3LENR$DShx-dWgMo zI^F#}-t3;Xr;*oaYeI*6apboow_hNVv>$R)g_{x`sH9@-R(212n4y5dX;%gW=YKdq zbBZUNOw>?#fnc>$=I4cGOsSx3MTwNdf-!)bn;#Rv2}6juqYO@uA{ze>X#?yAV<+wMB%)AfzslpwJK9kTXQ+`72JZXCy zRj4+n>@0MOZ`17^#_iSM=90L*UCw<@z|1=3e$9SCOnz)+&lq1aimEYetOlJb;BIDw zVUl_jhM#G4g3TuuPde9d!(>G8CV;d-!pq@%2W}Ss&{}re$XS58qeu7gYAe0*upUhz zX(EZx1!>xa`H6Nj!#S%UCvy(>jp6~meCQA!g6DG>Q;fnpaw;5XWduNJN;NT)$pj}t z-xIhLaVxqcF~{2LxHW2+PCLNpZNZI@Kg-BaRH2Te65LPoiyd0o&vkHlB5IO56}0pf z1gp~TfG7prmADJ{azZ_$o>vuQPSHyXPzEXav57rnddVcJrm(5nBpFO5!EQ0A3OB(z z>QC}XCO9TMLfj-jStwNUr#IJrRF{|-PCt6NFlZ0%4W5_reMqZBNG00LR%Qg}abzGG zEy@`*m4SewaG+>$Y2J_u5@Vn=RD3y$_P{cT#fxI8VkuhWa{E&D5CS&Px{QOeo{Njz zEiNkZ1Igw3bBDGDZ1E?Tw{wbW~d0)^TlrOgelq2}Lilje2B+$oQ_Z8~Dfx=*D(uBB{*M z>SSU1pb*g_Vq>H+lG6bcUccHO?(gYO^>6Oq+kdFvXpAFYeEpQ6S&Go6wME*7+Savg zX*0C7p&l!mCu?;zDYr2NZVbX-RHJE1T`S-7s!=k{hl?g(6iy`ThRO~yktrXqF{XT+ zjyW3(g3>cPdgP{={y@1hVniYUlnzS=c25~DnK-+$skdlaIIpMp!2NY!7`OXZPxj7y z>eB<0ZZB%Il-AUHZ+m8S{kV1e7S|N_3^otl-F@A*MXj&-%Ey6pLBu-Se*xJpA)r(~K*a@9W!M+0@>$ z>GenYcihy}yl8u}Yujy0N}`K4-m4?|UX%ADlWj*{mlfOL1#gCo;ZLz{sC*JRk64=P-rHKbsB^>fcXo`s{m31Y`f|(MGs^qdO%CNxUYjhclUirg z&c1nKVz{p=zhP>Lr#UaTH58b{K5M-3x>i@|?p4d~ymMrEd6CmU_tBqhxci?Uy3t$0~ke!9tB>P z2-{9@yujFox{92L?s9ST=_EoC;5xvMxF@$hb6p=;LF^gV3|2>av+TmEw+h3F*07zO zv$GT;LSjU3>M9SYEX@6^L+A=BS}fK9L&A8DP9ui1f39JfVWUCf_LhpsgTYG1$mO#X zv~CoA<1QA~0#*SXtT?PtM4dfJ!G#$W*W(mTFObsd6hA~^gz&w;EPc1M0DC{(-OTfL zcF4{W_M}~`wlizzA=7cwX}DH|Q8by(D(p#x?L?kgF?I?=;yUpR`thKzA#6HLpjtPS zd|xn#Nr_mmd5j!*SrCrls3cE<3~rcq{O%AP#HmR)#!pPPJpGE)n0{sNQCJ;&F8-R_ zBSQG%LvH3>9mnBECI~=oyo0-SqeHG6QI*aE;KgQ-QfD5?>C&zUCq#HS!F%4z&Y}UU znDp*~vmo_&S&bLG95AKG%GM;Oq$(D#MKroC@EQo5LS9`52d(3V@qwd@ie#}4aFzj& zhaH8u07tRw^-P@hLVEr8-_RmKk7AU)!H5RjGf*b%SMscp(^ZQX^aKJu3l>+2wHKbF zQRt(B(Do(*pTPA22REVsGJI^idAFHuG;cSHe8%mlvbUNI2E=_u9kbN(9hL1;nMY+X z{WMgaeX(+X&4I zhQ~1&gh`@&28PL*5MeBOX_C0L2nuU4$ol^wJ&Bd1-+MXzb5=}@hi{4he(~<{`_tcM zH|(zm!Qq&B3cwrkIvjr1X*eLV?c$>d;UY$kLP+u>vL$;oQ$8R1H?y61mMY!1HSLmE3>7%ZPKMIXQwlNR;T zwEZ4s;J5tA)G^DB^potS9k7P4oW7&TXF&@$%SW)HRc1)s+o>|@Hlqqw^m#Knj5fh) zRxBpF$%bDEX8ckyqZrg+aF{F#JBSjWA1l9BK8Lqa16~xwS(x3SSsm;=|~x4^-+KvILviqHjYS_qC%#W2<=gb%NhSh&~2MH^r3M^gvK z37IfC4tya9j{cS5dD)GIJTr1G>Y0>2dU#{{sq};2XRoCPUT58G)(_Kzy79hgWSe+V zJT~$(v3jJNbR`B0K8!W3verb=JUg2sG2&H-0F*V}#>#BWY74@aw@yO~Yl8%JMi-#- ziS<|+-;>$n@-woyQod8ZPnM?2vt^N*m?-ayABz`6=}nQnEVA9=0a08cZV|jaENBW8QazCRIyZLit2^0CfS+82!a>$ z1(_kB#523(Ow#(JZqM{V%8MDmuXzOregiu3%pWt~(awiY2pkdmD{NQHBQzUP3#P}^ zFb|KV_n!Xz^V3jb_29Eh(x0V2JuTLY{`69|XXK;wGTL9+ku;Y-&L_hVX|wQf0(7b} zwjp#QJA={Fh^H7`Xwd0A>!b!=sFyJ9hZ+MMLH=Q#3ts&kr>4(WUQJ){r&{TaH>g9S*UR9G2%D2sqPl>ao?R2t7N) zd??2;Fa!F>o->`tF=w)LO5u!ZDCB1kp{WR+6QChLKvgm;Nt;1+Sd#FxufBWzfa7p0 z;%TEh$0?CLq)q&VlH+v|207nel>?mt92l3Ak=j0Yy({Iu&AaNOaB zm*e4n@QydhMh`%*wgKysKy@G$7!K?V>Crn{JQi?V;WbrFgC<>gTK)RGod;*K1wtgKyd z-@K6*#p+u&kfx8c;@&8p?Sh2SK=viUgIIk5GyrNoJNJ`ZrsWRhZpoGG=1xn0z$7JI zE>QgF@etBwJ${tAmpBkk98!oIsdr|;1WxJ3jNTp{)nv8@I$IG+Bkz&+g{z^;*WWTF zJpe?+c(8OC;9!md*V!u zABta!OQ0<@#f#!aiZkWObyuVS*#)SjUiX}_39qM(8ErE`9gQ9172Ir9Jud4L26dUZWAKr+6OEFqXwLmo>z>cPGf36K-(#@efXy(I!%V!*Kw zTgAc5-C!=B*Ktf?dCz|ZM;Fd5T}ITJvxK}{aB`A7eDztRh~8uwyA{aJBxLwWMpEOd z=f8BFyzQ$l^CJdFZEeueed}WbH$AnseWY7?{L%Wkz1=0HGkfO_-Mr1peiLk+=b3iz z8(YQUn@c*pj<$m8+SSi&n9#ZPdu!Lfa@69^b3N@2xlGdgPdqYZeX@dL1mkhOla5qz z)XcQtKqyquNQ%;~wujrr3V5_dMGd4V1zW()Bo(w3*oGQ*s#0SlCZ``^8=U?3 zJU9I3RZ2Xc(I$B0eNZWM#Q_E!%7w==qS;%GE0Ci;jE&nUHVL1h)|xok(SU^sArSBL zNJyM#v~jiaLxUezpUGVPH8{ikYEY!&Y6oXp7jQM50zln-h?BVpxsi@wP>BvY&0u;W zUO^O$-9!ujEWLS!5= zr5xnz;8=#T>aZJ*sL-)pK+4l{rY0a9bt6ujcw;FjaT-sL{LFA=B$%UazVNI#>~xGA z#_>ToiyLNt<2P5qZl1rbjZP7uZa%^(5(AR0(`pKu#DbU>2G}*0r=X94r%M6)hNX&z zfxg*WbiC*+FgQjb8qMp>?=Oso0=-tmDk#;PUl3OFz0O{TB?zAaRVp-0gn%-6YK)OU zI2auqxoUWIp-@de+weQL+>?z!D7sw-AZzHLKn#?7-L zv&)VgVUL{@S1O5n&OA)8n+zmp<)cHDnmtVcU<>;_Mh6dBnS+^&3Ag;c5k$FvOiZJ~ zs(~HorLEk0sA|F>24Uka( zlDrdn?06oFHoi zE|BU-k*c=uSYO8Z_5WXTRC^oX5y~_X5Mhi?@YR=1juHy}a<1>Pmck3p_+#@DV4BU% z^$7!kD_k(gz>syFbst(?%KQ-azyP=UoGF9BmK(f~m&$edZ9LxjVFzt`FuTXNUv)gF zFxG#>y3!p;@`t52{?zk5cK850d`-W1MtZYY0x84y&3IjjL{ShfuO|ex&AM22I0Jcs z3m!EI10$Hs@p_R~&1569{w*mZzco&}kzw;6dt>#|HC)@H`>yHRUO1Y*8=UfVf^If^ z3SA5fdyb+N58Rh9ZN?QgwJR(jLfM7zuuU_&+-?UwYK4)L=N<4kwP+-IA}SKEFC_fO zgoZyBBSS3`3@oChbRd}7)g^#8*6VUz$Y%^M)5VbJ$H?jditp&~*T?m>251yaW?hT% zv%X^kq<}~loL~U#MnTn41P}F18on7Og~~sqSbD07>N~!R*yj@l_7wBHy6e3I$B=gr zk?2iNRD>DRJMM42xLY}T;RgBJ`u;3!42+*RDZg|21yNrG${Sb(g~Im4fXSGXqeTj0 zv3y}#Vf0Yscm(w@=Ze|sVpda}C{7mdE0)z_*#GJ@t-q+?0&90%=NNQIR!7hgcSsIL zzEh1P8*--P^yf%QjyI<$M>1(S9C_%68$jSr#PsyQ1*ZzZ*s}`)3JEw8Eejk`2-Ly4 zqeB-bGE$6yx9}569yT~VE@S$S+tYtg=%=SYU{<@&?NAI3w+~^&_h|7*TfMFAO|Fro zc-UUsJ|XwwW`wId3nq`N)10;K6Qkk}^hI?ItBo=cACT1siRe~aRJYp1TrlJa*^W14 zhvC@^F8xOOJF?n%&l`i-^ftHI#1=5)6lJ^KWUkd;Ii7uGVI}xT`viZ&E{XXHTB|T` zS+<)_wxbSS{R!p0?5hha|5ebhALqpN)%Bg(t~&blm(s8}VOzigMG92EJHr&@;S9pJ z`QtYb0r>|$wo-j;mo8*1QYS1@gYU|I06M=vjSX=%hOzxxA6q5Hrq+#N_lGBiYZVtf zDdOLno~Q=bmSb65jqij*eLOD56IQjWXiy3)EiXz@pkgxuUIB9$HP6V`naRE8bUlbk z-~_6pc8pl_y3L99s84w9$0Z#_rA}*+28x*uXaEF?)C}N z`^LmA&rBYCWX&Yw#ords{)$q@-DS6B_3P=6zVmGQ;~y_&)hSR!mNm6*#+;xn+mTSVtL)bp^CJrLp8*?T~g_JFCf>CWMm~U%=Cg zl+{(E;DHqy1rp|2j5_XJPx%@#E;rF_VF>J(YmeSNebVjUT1vhxXqWfEw@t#g?S^lA z%QkD;6KuUfUNGaU|Fr$ye|}^Z_h?VRqYb(K4xi?WMVEaLJ`YCdnD`;hFm!AhW;lS} zO7)~-FJ5}63oB0&yOSi=l9Ii6>9ZrH<5cB}XTVp1 zXM=aqJsZ3Wc{b2wkp+oHN^lkHzRl=+;2Fvf={Ksy+j<||-4`=i_ zU6_a8@OR;OU}5E@<9sY4o2+wHeRia6mJSLYea;j-r;oqS&-C$Mnw@!{$@=@ehv(?v zVEsAR0r~sjB#6M@s1yc+p}|Nbq2+Yt1tSpzF73WSWm&=A0=CY+#V&T(d+ez4ut)Mz z`9aFIOnG!WHgV15b~lLO!b*IqhtIH z9yX$mbtpil1Tg#TmSgvHPQLfljO|$gBVi~+29R)S4Zqim=TW5C@f5%>p(PIScs-?_MA>-Zt-yO z-eM7@kJ!XbTtNN!J3^oy@vUa1V(nixTQIAS}7Dl+yXBVewS{L5E^X@EIH#uhru+NXu!lxomkjJ3ibS?6!?^yR zNT=D%R^DyI!MlxII${I9am>|v=M&Or{_4=qCo-BA)in*TU!lMLsHW-fKpM^8L0DO& z>$5kj&$fvE9;43y3yZRz^jWCWbyGN~uNo{hzWBp7RJo61uNn#X@qbi zjf2fZGfRrD6hS3etWZEm0Y|!is`J<8W8kliF}pHji0fk*Ia1K1zxwDH^w+1en!moV z@>^U^BCDVwuvoMH4x`uW?*S%0rr-bd!ctuuM8*Zxd+m4N{dV*bT(8drTA$K84E)JE z@azpA#Vfj0h5qb2glQP6ul%aH;~5e@4|IB9t__(n6wo`E0+oIqvC_w&+t9qS&MYiW zSUm#!4*}ad>UzlqZ8W)IHlPuB5AvQn;f^GnIbFtqG2WbWp16KqEbB7Nj5pm$cZmNaA?oDx{yLqLYS(ufm zi-W28o(QJr2xa>fb$b$W)hMZnw&mgiYGY-HLvXCv;zg=?{!0{SS z6GIB5DG}n@$^41qTR1NXm>NL#uCPBS>=z1a0(8KD@-G=vqS?(7`=i8uEwNUVtca@& zn+)PygwYH$4B}$(R#Ch`WR2of1i3_N3n{4v8~cNe{ldnY00OZlz(#K+n8qsWCaXBt z%G#_ms8-pnxoh0wF85&y`7mHD{^(%8b}({aSE-v+@dlMOs#5{Fuv@eq+4u=n`Jhz= z8)U0+b5x69^(vrd&j=I8J?Amx*2^nc6YKF``zhHn@i>1BOMthXz;E!O@!ugy4fgVb;#8crWIMK9nG6hKlaGW=|`v*TYPTo{QCy0zHw+T`|jMw)=v_b ze?DXUx~EtwIBwyzd+#Ani%v<=01{E56UzYii0orK?lFe59+d$(<~l@coCO1HNrT$J zh8y-ae9|B#8j=kn9vaFAolENrQ~p@2!{6f{_8<43^(%gVj+9q9WQJc$aRcB%5cvdD zoNrNNgk@Sheb`DqhTiJ17`>Cp}lhOD+_LZJf73hx2)sc z|Co5+ySwjvdD+5>uKLi(v90s(AFTZ1mnRRl_@!hzr}zG)Z3|}>cT@%b>7SQ<_&&Fj{_&zT|g*=}Qb4%oUF*MgQBgLd zIYO1^54^K$dahoR-sEIQE<7}0<*dr81z$<=BJ`jCj2_!j(sp9 z45FpDF%pkQjFPW@plQj(%@cP{+&l4;iI)(tnHZT^Gf|>m2x5n?$0z!Hi6X<0QD|Td z4QGw)ppo5fWI6ygSd(gZdtF1p%MLV&ia@34X+Tg$dISMFxyM0_ zW7}u0nHC+(>K<+?%V}D;t!E5>`;6ri^EYl~Z>B3rxYdj4@Dh@+l%IwN-Y#rS#JrtC zWLj-gZ9u3E1ZoAT#MEh>JzgEp&WvZr$FrL8tb`7UGC(F%C9I@mTvH&KYc`+FWsm1R zlPhKmvK5fCR%i;y4tSzOPX&>zvZ4aMQ(sbCSU4my($X9Jjgf`!q3LX(AdE7MrH~}) zNqyehWc!Mtqt&UMLpSbP+;}B-dg;u*fyOzzRRB-O z_$VQ|JI`${p0Q?{PO5G$n?TNhFblEZC!kfe!rh5}b+E)-fPXn`U|rRgDzU0c7(gpA zp`M)pbB(ySo(c8DT_df_*^(o6uWhyxg+vk-w%%hYz!TlNV2n z{1xT-eB?dS7TA5C@?7-;iCo*Xyn;Lf{<($Dva-s~NO?_pqI{@aE+-{%sO~OwX**GU zrutm91frf3iAvHNDyXcAUno$LXASIe!!rhvnzM*jLy%jFf=dO~p)8w{8WqY%8KLM# zDmJI;tVn2`0mDMB{GV48FA2mcKC$(_vE2Gs=to6gM=?-Z@dZo%oIW@zCJl~%kfXvO z3*pj7=uLMNTJca~$-9PMf+_-K%I~s200%x0@`H-7>wZu?X+}qvKU6!A5AyYMA$BBm zGW2#x5<WAw$*YB-ARDZVK5UFP>sIQBPTr3rmqOPF| zD-Uy^2M}%5nfL~;f8ZMtbvQsxvjz&@I)Xy|+1w+YQ)9QAM(M94B5zuo-DnrpjrDEvu)wFgr?8pM_v{E{!*feKpr+c59z3*fvos0_L#6l<2oXqKVy3N7P z{MqH3%TJeoQZAW8Asb6N)f`(-%s}T94&}_qX_vi>OwDW^*GN$Q>27k(bmiC`yGiz=Tf`=a@{0PQO{>g-0PG!mOEE-;W)6tftyXM{S z;PSSSrGNzNImWhMJrS%jo8iPgqT`_9e$2@KVed@tJNFWIc4uEK!=c#%ftF%>Kn>xgy&h3b zlK*Gzz0bKf1E_u0U*G>}{Ibuv_uRequ-4jZt-a6QBb@3P^W4EKHyPf2UazA^I?T4X zGe#~Rxt%k-?i#sgWC{~6N@n^qhc0H>$)A(C=c^>xF?hTX^Z=5J#Xt_ z^t^T}<93ran`HTE$3B@V%lg%7-cyv0Sa*_E<;PuFS;S1Id1tY+4ycg{Pw54TvMfP2 z=Q#6bWas3hXCJ3BX7EOEMuu85@$rdj!$dXWxb(^iIVU;Jn87FY>zy>_q*NqH7MaPc zoHbB?&jygahgNWe&+*N${gcb(GB51n=13+K;Sc+Kw1YJYIp zK?h!aT=_K>h1pBbJMoBy1*7*q=q{ME<0lu)JN&AjowMU-S1%qr{*qzY)7Ia#@`M{U z95iY124(m9t>zK~>us&jENZzds1Vo-@FRZTO? zx;sjecg;@mKC>xxEetrsSwCZeNYAjI!_+Io-XGRF%##HID~5SJhm9Dbr{l?PK8`cE7spuk=%GY{k{lBkLCax$qu<4%Bnm8{8Qef^F5%PZ zca=H{QSWSdZ%J#ilOE8v5CSC2x<89`R9>z`5NfGGI&xF$oY36&xWd6YkTiL~;Q8!K zGk8i`+V}%*IY4C|H>Gk~;gA)(2CB^i70b%H3>=s|dd0Y$zCBj3ajR%${-?acO>dQI zS?cw2K5u&C_49@RBeQn;WM|9Ng!k{*3BY=POv~`nonE&qGp$o6dp90Xf9Lx7r&lc> zcl@EZttmZe&bW!k>^LU+xGam^wX^!gBaeJy`}XMBv+_>5;FtxQkD8RU;_$}uB6+Lv z%%a)DryW^z(CYc)zcq4p#q0|%&6}`m+}HzaZ(K3|^b@CdOGz(XcB=5)@x(yaA#26X z`sVz(!_{apPNq|L7Cxzg6MB~ZXX$TB_mp~#ek+?i z-b{Xkxa=5t&RvuAGoB;z>kiBq&t4fr%$%!@{GPb?I`2mP=AtM9dAimK1Dj~&)-R=SU_N1V#$IF$o5mDvZhotK6P?bL<7GJW7}390PAE-5J=hjrN! zr?S7gbXgfvIW45J@4DzdN$nL788Dw6Lh35%sCwDj8IELz8cGGlat^p zsh5+JOUvmt40=k>Fqp`y<}@A6hZ~%6>d;r?{5EPvfA3KEO)A=b{vuk_9UBzHW+9TI zTeWXk-_vz{b#IT8&U3Oyw(B{=fy|;A4)jh>I-N}PFXl+k4WD;#r#%;^amJUXamE*< zu`H~|nQ7G6+~ps~VVn6`@Z#?~)LBhDFH+tXNlV*9qz zoN=6~2b{5p^&RU&&X7Kx3};A{oC$ft8R24*c%N#nNPf@M46azzjw=?z6;j3Sha4_k zF+5me63^jTG?<<%z-lubwTsHjOjpm0@r29!sKi;ZjXeF9)_1bTL-gHa=4p2Vlyb8s zCnwH}G1uWeruCi4yE5qtqwiE7Cf&M^>}>sr=sS~lWzuyv@5$)9Nz)Tnkig9*@2Nbk z^Hxh*UnOs5cr)~T-Y3oMIn<`)XrZ@~-?q7@s3pHLT3u!ghvyyKzT8R2r;3)-d7~F^ z*1FVH>A`$nhAn%@F=G1~U8+l;s7tei$Gluy{_q#$b?d~bY!0bV1vy*mv*w{0rVin6 zM3=s$HMXIWpi8L;R7!G9O~PN$P8=;Sy42KVOGst^buqfsP)X3G`>2cV4XsNJmD55h z`>qQu=DnqLsiBgfOZQb5;Z?0mp(47p^#iL*g=f*F?ihGh>gA0bFD)l+81$57c^!Qh zF4npf%A!ku73X}ByBYAZRCMU{*|cW7>*7*FNX=cXIh!yva!~2X`T~&};q1QcIC~|} z#Pmr1SNrsdhO<=~v&nr2v8Xj+++V`(LGoU}IC(EXWXuy8gR?~-WrS@flQ-|ZPHjql zhvygC=hy4!-F{R<);jbVXy(tY6>{d@>ykGz=Wo{)xNDM`AJ$gL1hH_kCYxDa`!o_S zCkpbkgb_vJ?=iWL*15MfXO3(0yjd|IHcq~&Yw{w~GOkQh_nV&8=4p|dNxEfB?v+V9 zZCS=4mwl&Zwt3p*EfS;i_D)S+M&5cn$`Z|=oNIFrxnJ^MtK~)Kk5me$h*iW{bYidk zqdCjc2!GR_%H}wgTur4U*OV&!g}gU4DS^u7kct);q0*sbnu?Z7Q9>72~~FmPp3Gi@b+-OW_KFQ_h9Rvn9Y+3$!VAOY`sE) z=ckhOgRMt2A24;lxzGNE&RvGH2U}y!g_GKIHzh}MOv&9!Eji?Vpw9h~<^`SQ&UmTI zjt(=+&Y* zZA-uRx|FfZXa=P>T7~CJ==uj+zt`Np<?jqivv&=l5^dL{8Lx&F#9lE!9$jJ1>o_!ELFrJyo zy)t>2;TpwKTh)8gz_z*bbQi6)OzxFQvc5vfG7^2>BX>yqyi*owjx0AE={&95U9pOb zvRvLgcEZ3e2|T%zXy6vjlQM3=ldz`Q)%2F;tjX!YPNmpDl)6pMvz_TC=dn8HF3l6h z?lz!$7j>E8MQIOHiesCn1=(uP+LTxLP|7QOD6L_hUD`aolYE5- zb-v`e!jyQDF7dqP$p>~UvF1VD7HSCtsL6RzbKb#iN(}!k()?#iZ1{s7&(fpj{0^;* z&f22+&y;#iz#$m2^h#O0snIRsJ;713f6h4PK+93v3`eEgQMqf+R5zg)_4+Q&fsC%2 zUoQ$;Mdde-&bAB4Oy1aN#oC%Mc~>TFq*b&HPP1eT@7ghE&3z_kd2h;aAM5;7M#<`aqlBZH%p5J#MJL&bk52cJ`XRRU5q#1)Udh|%0vDi`Oh?;(>S8iwP z#gmwCa)=iW{)=ArDks3bM4WRpYx<`a4EF{khgW+aT0Q!R!w&BCOs||Nx&8KDyL$8z z?w-|mNv{t*a@i3>`i)+E#KK`i60RNh({)L&w?3A#jb+zEd7CJ&dwNnYCbniw;WV_v zhk8Skl7>!kPI4sXoa8*wrT>s2N!!vdW3!a)>^FT98@lV#adadFQ&R@N$QEg`h=l`! zSUJQ?2x{~=*{mydG^aWi%R%aLNJ;_WvDDFfUte8NU0AfPprT+??i0BU1&cC94jb01 zdD6P#ilo;^9hIAV)Tki`oKseI&H+yjnl!m^WWNK~OmN&!E}-4sv?X3JBPYpAAHm7N zGlr(851m4hF6(kjm!vLFIQ{$dN#EvOhV8$-S3*(cAfYxz4NGbZ*e@t?v0Ug@{lK!MdWUCl{y?x5)gGV1e+8dpeG`dam4jMFK+`xhRY~mO5W#i2@&75D#n=qZU zb6?qAB6Tzen9Dpnv+HyKlN}uzeP_m~$%9gsrWMaDozQ=Lw{GJ`tXkc!_0=iECJgVF za>UtPM~odihE2DNiw)an|y{O$pIqQOcNO!Wb;$7f8F?g^uzW=4KjQI74_t_ml z_7@&8V$7w3diUN($KVkF;pER4l(M~Bw-HlVJN87sjASk|wh!*v`y@6<(z5UpFIl}v`H=-U zZLo-I$ns;&8>2|Be(&nD6EiZ0TaH(?$rBE%nS13GDb-0sa_3AOGqYf1a`MN6CQfEr z;J`H#Qx05JHtyoB6Y>Y8b{&$J)vi<}GlnN`?>3`v|M>|;V;7f>MMFw$(I)7!g-p&d zMl5*>54`#8r*R(tw6mhUIZ-%$>g0)o`n4-sP`1<*c2Uc5X3ZEmXy{OiGIng=DMaYI zcHwqZ))Pa9^zE{}N6+Mw*eAiZ9PMRUyuh@czM}=(mTi1T-WJw=sgq((uo( zT&$ctHdWimNR;6WoYA%CcBe}hm-GG{*0+eXQP8~H0fo~4a)ey)UUSjzi_RKcI%Rmp z>R~em_n0(jRN;G7jeQGe9GbIyZI><^laeRUqs$?wQ&~&f+v#(ESJkU~%0D=-PBu&{ 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 aWGe4uD(_?}?_?_PWGe4uD(~cOqW=eI(CQrk diff --git a/deps/nuklear/extra_font/Raleway-Bold.ttf b/deps/nuklear/extra_font/Raleway-Bold.ttf deleted file mode 100644 index 7aa37f014fec4c7b5a9abaecbbc5992e6507cdc2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 176280 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 diff --git a/deps/nuklear/extra_font/Roboto-Bold.ttf b/deps/nuklear/extra_font/Roboto-Bold.ttf deleted file mode 100644 index aaf374d2cc000c058f434f43c3b53bcaf315e2a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 135820 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 TYqd&VnqJLHIX9iq_T+y7#;O#c diff --git a/deps/nuklear/extra_font/Roboto-Light.ttf b/deps/nuklear/extra_font/Roboto-Light.ttf deleted file mode 100644 index 664e1b2f9dbafbf6280305123d2df7fa0c66cee9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 140276 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 diff --git a/deps/nuklear/extra_font/Roboto-Regular.ttf b/deps/nuklear/extra_font/Roboto-Regular.ttf deleted file mode 100644 index 3e6e2e76134cd6040a49ccf9961d302f7d139fcd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145348 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 PiOjzua{P-TkKXowY>-!K diff --git a/deps/nuklear/extra_font/kenvector_future_thin.ttf b/deps/nuklear/extra_font/kenvector_future_thin.ttf deleted file mode 100644 index 9f4b4fa59ac2211aabf9cb60c6f7caf441d087ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34100 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 KTY$`k7yb_mr&(bD diff --git a/deps/nuklear/nuklear.h b/deps/nuklear/nuklear.h deleted file mode 100644 index 271ca942..00000000 --- a/deps/nuklear/nuklear.h +++ /dev/null @@ -1,22007 +0,0 @@ -/* - Nuklear - v1.20 - public domain - no warrenty implied; use at your own risk. - authored from 2015-2016 by Micha Mettke - -ABOUT: - This is a minimal state graphical user interface single header toolkit - written in ANSI C and licensed under public domain. - It was designed as a simple embeddable user interface for application and does - not have any dependencies, a default renderbackend or OS window and input handling - but instead provides a very modular library approach by using simple input state - for input and draw commands describing primitive shapes as output. - So instead of providing a layered library that tries to abstract over a number - of platform and render backends it only focuses on the actual UI. - -VALUES: - - Graphical user interface toolkit - - Single header library - - Written in C89 (a.k.a. ANSI C or ISO C90) - - Small codebase (~17kLOC) - - Focus on portability, efficiency and simplicity - - No dependencies (not even the standard library if not wanted) - - Fully skinnable and customizable - - Low memory footprint with total memory control if needed or wanted - - UTF-8 support - - No global or hidden state - - Customizable library modules (you can compile and use only what you need) - - Optional font baker and vertex buffer output - -USAGE: - This library is self contained in one single header file and can be used either - in header only mode or in implementation mode. The header only mode is used - by default when included and allows including this header in other headers - and does not contain the actual implementation. - - The implementation mode requires to define the preprocessor macro - NK_IMPLEMENTATION in *one* .c/.cpp file before #includeing this file, e.g.: - - #define NK_IMPLEMENTATION - #include "nuklear.h" - - Also optionally define the symbols listed in the section "OPTIONAL DEFINES" - below in header and implementation mode if you want to use additional functionality - or need more control over the library. - IMPORTANT: Every time you include "nuklear.h" you have to define the same flags. - This is very important not doing it either leads to compiler errors - or even worse stack corruptions. - -FEATURES: - - Absolutely no platform dependend code - - Memory management control ranging from/to - - Ease of use by allocating everything from standard library - - Control every byte of memory inside the library - - Font handling control ranging from/to - - Use your own font implementation for everything - - Use this libraries internal font baking and handling API - - Drawing output control ranging from/to - - Simple shapes for more high level APIs which already have drawing capabilities - - Hardware accessible anti-aliased vertex buffer output - - Customizable colors and properties ranging from/to - - Simple changes to color by filling a simple color table - - Complete control with ability to use skinning to decorate widgets - - Bendable UI library with widget ranging from/to - - Basic widgets like buttons, checkboxes, slider, ... - - Advanced widget like abstract comboboxes, contextual menus,... - - Compile time configuration to only compile what you need - - Subset which can be used if you do not want to link or use the standard library - - Can be easily modified to only update on user input instead of frame updates - -OPTIONAL DEFINES: - NK_PRIVATE - If defined declares all functions as static, so they can only be accessed - inside the file that contains the implementation - - NK_INCLUDE_FIXED_TYPES - If defined it will include header 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. - If used needs to be defined for implementation and header - - NK_INCLUDE_DEFAULT_ALLOCATOR - if defined it will include header and provide additional functions - to use this library without caring for memory allocation control and therefore - ease memory management. - Adds the standard library with malloc and free so don't define if you - don't want to link to the standard library - If used needs to be defined for implementation and header - - NK_INCLUDE_STANDARD_IO - if defined it will include header and provide - additional functions depending on file loading. - Adds the standard library with fopen, fclose,... so don't define this - if you don't want to link to the standard library - If used needs to be defined for implementation and header - - NK_INCLUDE_STANDARD_VARARGS - if defined it will include header and provide - additional functions depending on variable arguments - Adds the standard library with va_list and so don't define this if - you don't want to link to the standard library - If used needs to be defined for implementation and header - - 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,... - If used needs to be defined for implementation and header - - NK_INCLUDE_FONT_BAKING - Defining this adds the `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. - If used needs to be defined for implementation and header - - 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 - Enabling this adds ~12kb to global stack memory - If used needs to be defined for implementation and header - - 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. - If used needs to be defined for implementation and header - - NK_BUTTON_TRIGGER_ON_RELEASE - Different platforms require button clicks occuring 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. - If used it is only required to be defined for the implementation part - - 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. - - NK_ASSERT - If you don't define this, nuklear will use with assert(). - Adds the standard library so define to nothing of not wanted - If used needs to be defined for implementation and header - - 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. - If used needs to be defined for implementation and header - - NK_MAX_NUMBER_BUFFER - Maximum buffer size for the conversion buffer between float and string - Under normal circumstances this should be more than sufficient. - If used needs to be defined for implementation and header - - 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. - If used it is only required to be defined for the implementation part - - NK_MEMSET - You can define this to 'memset' or your own memset implementation - replacement. If not nuklear will use its own version. - If used it is only required to be defined for the implementation part - - NK_MEMCPY - You can define this to 'memcpy' or your own memcpy implementation - replacement. If not nuklear will use its own version. - If used it is only required to be defined for the implementation part - - 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. - If used it is only required to be defined for the implementation part - - NK_SIN - You can define this to 'sinf' or your own sine implementation - replacement. If not nuklear will use its own approximation implementation. - If used it is only required to be defined for the implementation part - - NK_COS - You can define this to 'cosf' or your own cosine implementation - replacement. If not nuklear will use its own approximation implementation. - If used it is only required to be defined for the implementation part - - 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!). - If used it is only required to be defined for the implementation part - - 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!). - If used it is only required to be defined for the implementation part - - 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. - If used it is only required to be defined for the implementation part - - NK_BYTE - NK_INT16 - NK_UINT16 - NK_INT32 - NK_UINT32 - NK_SIZE_TYPE - NK_POINTER_TYPE - If you compile without NK_USE_FIXED_TYPE then a number of standard types - will be selected and compile time validated. If they are incorrect you can - define the correct types by overloading these type defines. - -CREDITS: - Developed by Micha Mettke and every direct or indirect contributor. - - Embeds stb_texedit, stb_truetype and stb_rectpack by Sean Barret (public domain) - Embeds ProggyClean.ttf font by Tristan Grimmer (MIT license). - - Big thank you to Omar Cornut (ocornut@github) for his imgui library and - giving me the inspiration for this library, Casey Muratori for handmade hero - and his original immediate mode graphical user interface idea and Sean - Barret for his amazing single header libraries which restored my faith - in libraries and brought me to create some of my own. - -LICENSE: - This software is dual-licensed to the public domain and under the following - license: you are granted a perpetual, irrevocable license to copy, modify, - publish and distribute this file as you see fit. -*/ -#ifndef NK_NUKLEAR_H_ -#define NK_NUKLEAR_H_ - -#ifdef __cplusplus -extern "C" { -#endif -/* - * ============================================================== - * - * CONSTANTS - * - * =============================================================== - */ -#define NK_UNDEFINED (-1.0f) -#define NK_UTF_INVALID 0xFFFD /* internal invalid utf8 rune */ -#define NK_UTF_SIZE 4 /* describes the number of bytes a glyph consists of*/ -#ifndef NK_INPUT_MAX -#define NK_INPUT_MAX 16 -#endif -#ifndef NK_MAX_NUMBER_BUFFER -#define NK_MAX_NUMBER_BUFFER 64 -#endif -#ifndef NK_SCROLLBAR_HIDING_TIMEOUT -#define NK_SCROLLBAR_HIDING_TIMEOUT 4.0f -#endif - -/* - * ============================================================== - * - * HELPER - * - * =============================================================== - */ -#ifndef NK_API -#ifdef NK_PRIVATE -#define NK_API static -#else -#define NK_API extern -#endif -#endif - -#define NK_INTERN static -#define NK_STORAGE static -#define NK_GLOBAL static - -#define NK_FLAG(x) (1 << (x)) -#define NK_STRINGIFY(x) #x -#define NK_MACRO_STRINGIFY(x) NK_STRINGIFY(x) -#define NK_STRING_JOIN_IMMEDIATE(arg1, arg2) arg1 ## arg2 -#define NK_STRING_JOIN_DELAY(arg1, arg2) NK_STRING_JOIN_IMMEDIATE(arg1, arg2) -#define NK_STRING_JOIN(arg1, arg2) NK_STRING_JOIN_DELAY(arg1, arg2) - -#ifdef _MSC_VER -#define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__COUNTER__) -#else -#define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__LINE__) -#endif - -#ifndef NK_STATIC_ASSERT -#define NK_STATIC_ASSERT(exp) typedef char NK_UNIQUE_NAME(_dummy_array)[(exp)?1:-1] -#endif - -#ifndef NK_FILE_LINE -#ifdef _MSC_VER -#define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__COUNTER__) -#else -#define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__LINE__) -#endif -#endif - -#define NK_MIN(a,b) ((a) < (b) ? (a) : (b)) -#define NK_MAX(a,b) ((a) < (b) ? (b) : (a)) -#define NK_CLAMP(i,v,x) (NK_MAX(NK_MIN(v,x), i)) - -/* - * =============================================================== - * - * BASIC - * - * =============================================================== - */ -#ifdef NK_INCLUDE_FIXED_TYPES - #include - #define NK_INT8 int8_t - #define NK_UINT8 uint8_t - #define NK_INT16 int16_t - #define NK_UINT16 uint16_t - #define NK_INT32 int32_t - #define NK_UINT32 uint32_t - #define NK_SIZE_TYPE uintptr_t - #define NK_POINTER_TYPE uintptr_t -#else - #ifndef NK_INT8 - #define NK_INT8 char - #endif - #ifndef NK_UINT8 - #define NK_UINT8 unsigned char - #endif - #ifndef NK_INT16 - #define NK_INT16 signed short - #endif - #ifndef NK_UINT16 - #define NK_UINT16 unsigned short - #endif - #ifndef NK_INT32 - #if defined(_MSC_VER) - #define NK_INT32 __int32 - #else - #define NK_INT32 signed int - #endif - #endif - #ifndef NK_UINT32 - #if defined(_MSC_VER) - #define NK_UINT32 unsigned __int32 - #else - #define NK_UINT32 unsigned int - #endif - #endif - #ifndef NK_SIZE_TYPE - #if (defined(__WIN32) || defined(WIN32)) && defined(_MSC_VER) - #define NK_SIZE_TYPE __int32 - #elif defined(__WIN64) && defined(_MSC_VER) - #define NK_SIZE_TYPE __int64 - #elif defined(__GNUC__) || defined(__clang__) - #if defined(__x86_64__) || defined(__ppc64__) - #define NK_SIZE_TYPE unsigned long - #else - #define NK_SIZE_TYPE unsigned int - #endif - #else - #define NK_SIZE_TYPE unsigned long - #endif - #endif - #ifndef NK_POINTER_TYPE - #if (defined(__WIN32) || defined(WIN32)) && defined(_MSC_VER) - #define NK_POINTER_TYPE unsigned __int32 - #elif defined(__WIN64) && defined(_MSC_VER) - #define NK_POINTER_TYPE unsigned __int64 - #elif defined(__GNUC__) || defined(__clang__) - #if defined(__x86_64__) || defined(__ppc64__) - #define NK_POINTER_TYPE unsigned long - #else - #define NK_POINTER_TYPE unsigned int - #endif - #else - #define NK_POINTER_TYPE unsigned long - #endif - #endif -#endif - -typedef NK_INT8 nk_char; -typedef NK_UINT8 nk_uchar; -typedef NK_UINT8 nk_byte; -typedef NK_INT16 nk_short; -typedef NK_UINT16 nk_ushort; -typedef NK_INT32 nk_int; -typedef NK_UINT32 nk_uint; -typedef NK_SIZE_TYPE nk_size; -typedef NK_POINTER_TYPE nk_ptr; - -typedef nk_uint nk_hash; -typedef nk_uint nk_flags; -typedef nk_uint nk_rune; - -/* Make sure correct type size: - * This will fire with a negative subscript error if the type sizes - * are set incorrectly by the compiler, and compile out if not */ -NK_STATIC_ASSERT(sizeof(nk_short) == 2); -NK_STATIC_ASSERT(sizeof(nk_ushort) == 2); -NK_STATIC_ASSERT(sizeof(nk_uint) == 4); -NK_STATIC_ASSERT(sizeof(nk_int) == 4); -NK_STATIC_ASSERT(sizeof(nk_byte) == 1); -NK_STATIC_ASSERT(sizeof(nk_flags) >= 4); -NK_STATIC_ASSERT(sizeof(nk_rune) >= 4); -NK_STATIC_ASSERT(sizeof(nk_size) >= sizeof(void*)); -NK_STATIC_ASSERT(sizeof(nk_ptr) >= sizeof(void*)); - -/* ============================================================================ - * - * API - * - * =========================================================================== */ -struct nk_buffer; -struct nk_allocator; -struct nk_command_buffer; -struct nk_draw_command; -struct nk_convert_config; -struct nk_style_item; -struct nk_text_edit; -struct nk_draw_list; -struct nk_user_font; -struct nk_panel; -struct nk_context; -struct nk_draw_vertex_layout_element; -struct nk_style_button; -struct nk_style_toggle; -struct nk_style_selectable; -struct nk_style_slide; -struct nk_style_progress; -struct nk_style_scrollbar; -struct nk_style_edit; -struct nk_style_property; -struct nk_style_chart; -struct nk_style_combo; -struct nk_style_tab; -struct nk_style_window_header; -struct nk_style_window; - -enum {nk_false, nk_true}; -struct nk_color {nk_byte r,g,b,a;}; -struct nk_colorf {float r,g,b,a;}; -struct nk_vec2 {float x,y;}; -struct nk_vec2i {short x, y;}; -struct nk_rect {float x,y,w,h;}; -struct nk_recti {short x,y,w,h;}; -typedef char nk_glyph[NK_UTF_SIZE]; -typedef union {void *ptr; int id;} nk_handle; -struct nk_image {nk_handle handle;unsigned short w,h;unsigned short region[4];}; -struct nk_cursor {struct nk_image img; struct nk_vec2 size, offset;}; -struct nk_scroll {nk_uint x, y;}; - -enum nk_heading {NK_UP, NK_RIGHT, NK_DOWN, NK_LEFT}; -enum nk_button_behavior {NK_BUTTON_DEFAULT, NK_BUTTON_REPEATER}; -enum nk_modify {NK_FIXED = nk_false, NK_MODIFIABLE = nk_true}; -enum nk_orientation {NK_VERTICAL, NK_HORIZONTAL}; -enum nk_collapse_states {NK_MINIMIZED = nk_false, NK_MAXIMIZED = nk_true}; -enum nk_show_states {NK_HIDDEN = nk_false, NK_SHOWN = nk_true}; -enum nk_chart_type {NK_CHART_LINES, NK_CHART_COLUMN, NK_CHART_MAX}; -enum nk_chart_event {NK_CHART_HOVERING = 0x01, NK_CHART_CLICKED = 0x02}; -enum nk_color_format {NK_RGB, NK_RGBA}; -enum nk_popup_type {NK_POPUP_STATIC, NK_POPUP_DYNAMIC}; -enum nk_layout_format {NK_DYNAMIC, NK_STATIC}; -enum nk_tree_type {NK_TREE_NODE, NK_TREE_TAB}; -enum nk_anti_aliasing {NK_ANTI_ALIASING_OFF, NK_ANTI_ALIASING_ON}; - -typedef void*(*nk_plugin_alloc)(nk_handle, void *old, nk_size); -typedef void (*nk_plugin_free)(nk_handle, void *old); -typedef int(*nk_plugin_filter)(const struct nk_text_edit*, nk_rune unicode); -typedef void(*nk_plugin_paste)(nk_handle, struct nk_text_edit*); -typedef void(*nk_plugin_copy)(nk_handle, const char*, int len); - -struct nk_allocator { - nk_handle userdata; - nk_plugin_alloc alloc; - nk_plugin_free free; -}; - -struct nk_draw_null_texture { - nk_handle texture;/* texture handle to a texture with a white pixel */ - struct nk_vec2 uv; /* coordinates to a white pixel in the texture */ -}; -struct nk_convert_config { - float global_alpha; /* global alpha value */ - enum nk_anti_aliasing line_AA; /* line anti-aliasing flag can be turned off if you are tight on memory */ - enum nk_anti_aliasing shape_AA; /* shape anti-aliasing flag can be turned off if you are tight on memory */ - unsigned int circle_segment_count; /* number of segments used for circles: default to 22 */ - unsigned int arc_segment_count; /* number of segments used for arcs: default to 22 */ - unsigned int curve_segment_count; /* number of segments used for curves: default to 22 */ - struct nk_draw_null_texture null; /* handle to texture with a white pixel for shape drawing */ - const struct nk_draw_vertex_layout_element *vertex_layout; /* describes the vertex output format and packing */ - nk_size vertex_size; /* sizeof one vertex for vertex packing */ - nk_size vertex_alignment; /* vertex alignment: Can be optained by NK_ALIGNOF */ -}; - -struct nk_list_view { -/* public: */ - int begin, end, count; -/* private: */ - int total_height; - struct nk_context *ctx; - nk_uint *scroll_pointer; - nk_uint scroll_value; -}; - -enum nk_symbol_type { - NK_SYMBOL_NONE, - NK_SYMBOL_X, - NK_SYMBOL_UNDERSCORE, - NK_SYMBOL_CIRCLE_SOLID, - NK_SYMBOL_CIRCLE_OUTLINE, - NK_SYMBOL_RECT_SOLID, - NK_SYMBOL_RECT_OUTLINE, - NK_SYMBOL_TRIANGLE_UP, - NK_SYMBOL_TRIANGLE_DOWN, - NK_SYMBOL_TRIANGLE_LEFT, - NK_SYMBOL_TRIANGLE_RIGHT, - NK_SYMBOL_PLUS, - NK_SYMBOL_MINUS, - NK_SYMBOL_MAX -}; - -enum nk_keys { - NK_KEY_NONE, - NK_KEY_SHIFT, - NK_KEY_CTRL, - NK_KEY_DEL, - NK_KEY_ENTER, - NK_KEY_TAB, - NK_KEY_BACKSPACE, - NK_KEY_COPY, - NK_KEY_CUT, - NK_KEY_PASTE, - NK_KEY_UP, - NK_KEY_DOWN, - NK_KEY_LEFT, - NK_KEY_RIGHT, - - /* Shortcuts: text field */ - NK_KEY_TEXT_INSERT_MODE, - NK_KEY_TEXT_REPLACE_MODE, - NK_KEY_TEXT_RESET_MODE, - NK_KEY_TEXT_LINE_START, - NK_KEY_TEXT_LINE_END, - NK_KEY_TEXT_START, - NK_KEY_TEXT_END, - NK_KEY_TEXT_UNDO, - NK_KEY_TEXT_REDO, - NK_KEY_TEXT_WORD_LEFT, - NK_KEY_TEXT_WORD_RIGHT, - - /* Shortcuts: scrollbar */ - NK_KEY_SCROLL_START, - NK_KEY_SCROLL_END, - NK_KEY_SCROLL_DOWN, - NK_KEY_SCROLL_UP, - - NK_KEY_MAX -}; - -enum nk_buttons { - NK_BUTTON_LEFT, - NK_BUTTON_MIDDLE, - NK_BUTTON_RIGHT, - NK_BUTTON_MAX -}; - -enum nk_style_colors { - NK_COLOR_TEXT, - NK_COLOR_WINDOW, - NK_COLOR_HEADER, - NK_COLOR_BORDER, - NK_COLOR_BUTTON, - NK_COLOR_BUTTON_HOVER, - NK_COLOR_BUTTON_ACTIVE, - NK_COLOR_TOGGLE, - NK_COLOR_TOGGLE_HOVER, - NK_COLOR_TOGGLE_CURSOR, - NK_COLOR_SELECT, - NK_COLOR_SELECT_ACTIVE, - NK_COLOR_SLIDER, - NK_COLOR_SLIDER_CURSOR, - NK_COLOR_SLIDER_CURSOR_HOVER, - NK_COLOR_SLIDER_CURSOR_ACTIVE, - NK_COLOR_PROPERTY, - NK_COLOR_EDIT, - NK_COLOR_EDIT_CURSOR, - NK_COLOR_COMBO, - NK_COLOR_CHART, - NK_COLOR_CHART_COLOR, - NK_COLOR_CHART_COLOR_HIGHLIGHT, - NK_COLOR_SCROLLBAR, - NK_COLOR_SCROLLBAR_CURSOR, - NK_COLOR_SCROLLBAR_CURSOR_HOVER, - NK_COLOR_SCROLLBAR_CURSOR_ACTIVE, - NK_COLOR_TAB_HEADER, - NK_COLOR_COUNT -}; - -enum nk_style_cursor { - NK_CURSOR_ARROW, - NK_CURSOR_TEXT, - NK_CURSOR_MOVE, - NK_CURSOR_RESIZE_VERTICAL, - NK_CURSOR_RESIZE_HORIZONTAL, - NK_CURSOR_RESIZE_TOP_LEFT_DOWN_RIGHT, - NK_CURSOR_RESIZE_TOP_RIGHT_DOWN_LEFT, - NK_CURSOR_COUNT -}; - -enum nk_widget_layout_states { - NK_WIDGET_INVALID, /* The widget cannot be seen and is completely out of view */ - NK_WIDGET_VALID, /* The widget is completely inside the window and can be updated and drawn */ - NK_WIDGET_ROM /* The widget is partially visible and cannot be updated */ -}; - -/* widget states */ -enum nk_widget_states { - NK_WIDGET_STATE_MODIFIED = NK_FLAG(1), - NK_WIDGET_STATE_INACTIVE = NK_FLAG(2), /* widget is neither active nor hovered */ - NK_WIDGET_STATE_ENTERED = NK_FLAG(3), /* widget has been hovered on the current frame */ - NK_WIDGET_STATE_HOVER = NK_FLAG(4), /* widget is being hovered */ - NK_WIDGET_STATE_ACTIVED = NK_FLAG(5),/* widget is currently activated */ - NK_WIDGET_STATE_LEFT = NK_FLAG(6), /* widget is from this frame on not hovered anymore */ - NK_WIDGET_STATE_HOVERED = NK_WIDGET_STATE_HOVER|NK_WIDGET_STATE_MODIFIED, /* widget is being hovered */ - NK_WIDGET_STATE_ACTIVE = NK_WIDGET_STATE_ACTIVED|NK_WIDGET_STATE_MODIFIED /* widget is currently activated */ -}; - -/* text alignment */ -enum nk_text_align { - NK_TEXT_ALIGN_LEFT = 0x01, - NK_TEXT_ALIGN_CENTERED = 0x02, - NK_TEXT_ALIGN_RIGHT = 0x04, - NK_TEXT_ALIGN_TOP = 0x08, - NK_TEXT_ALIGN_MIDDLE = 0x10, - NK_TEXT_ALIGN_BOTTOM = 0x20 -}; -enum nk_text_alignment { - NK_TEXT_LEFT = NK_TEXT_ALIGN_MIDDLE|NK_TEXT_ALIGN_LEFT, - NK_TEXT_CENTERED = NK_TEXT_ALIGN_MIDDLE|NK_TEXT_ALIGN_CENTERED, - NK_TEXT_RIGHT = NK_TEXT_ALIGN_MIDDLE|NK_TEXT_ALIGN_RIGHT -}; - -/* edit flags */ -enum nk_edit_flags { - NK_EDIT_DEFAULT = 0, - NK_EDIT_READ_ONLY = NK_FLAG(0), - NK_EDIT_AUTO_SELECT = NK_FLAG(1), - NK_EDIT_SIG_ENTER = NK_FLAG(2), - NK_EDIT_ALLOW_TAB = NK_FLAG(3), - NK_EDIT_NO_CURSOR = NK_FLAG(4), - NK_EDIT_SELECTABLE = NK_FLAG(5), - NK_EDIT_CLIPBOARD = NK_FLAG(6), - NK_EDIT_CTRL_ENTER_NEWLINE = NK_FLAG(7), - NK_EDIT_NO_HORIZONTAL_SCROLL = NK_FLAG(8), - NK_EDIT_ALWAYS_INSERT_MODE = NK_FLAG(9), - NK_EDIT_MULTILINE = NK_FLAG(11), - NK_EDIT_GOTO_END_ON_ACTIVATE = NK_FLAG(12) -}; -enum nk_edit_types { - NK_EDIT_SIMPLE = NK_EDIT_ALWAYS_INSERT_MODE, - NK_EDIT_FIELD = NK_EDIT_SIMPLE|NK_EDIT_SELECTABLE|NK_EDIT_CLIPBOARD, - NK_EDIT_BOX = NK_EDIT_ALWAYS_INSERT_MODE| NK_EDIT_SELECTABLE| NK_EDIT_MULTILINE|NK_EDIT_ALLOW_TAB|NK_EDIT_CLIPBOARD, - NK_EDIT_EDITOR = NK_EDIT_SELECTABLE|NK_EDIT_MULTILINE|NK_EDIT_ALLOW_TAB| NK_EDIT_CLIPBOARD -}; -enum nk_edit_events { - NK_EDIT_ACTIVE = NK_FLAG(0), /* edit widget is currently being modified */ - NK_EDIT_INACTIVE = NK_FLAG(1), /* edit widget is not active and is not being modified */ - NK_EDIT_ACTIVATED = NK_FLAG(2), /* edit widget went from state inactive to state active */ - NK_EDIT_DEACTIVATED = NK_FLAG(3), /* edit widget went from state active to state inactive */ - NK_EDIT_COMMITED = NK_FLAG(4) /* edit widget has received an enter and lost focus */ -}; -enum nk_panel_flags { - NK_WINDOW_BORDER = NK_FLAG(0), /* Draws a border around the window to visually separate the window from the background */ - NK_WINDOW_MOVABLE = NK_FLAG(1), /* The movable flag indicates that a window can be moved by user input or by dragging the window header */ - NK_WINDOW_SCALABLE = NK_FLAG(2), /* The scalable flag indicates that a window can be scaled by user input by dragging a scaler icon at the button of the window */ - NK_WINDOW_CLOSABLE = NK_FLAG(3), /* adds a closable icon into the header */ - NK_WINDOW_MINIMIZABLE = NK_FLAG(4), /* adds a minimize icon into the header */ - NK_WINDOW_NO_SCROLLBAR = NK_FLAG(5), /* Removes the scrollbar from the window */ - NK_WINDOW_TITLE = NK_FLAG(6), /* Forces a header at the top at the window showing the title */ - NK_WINDOW_SCROLL_AUTO_HIDE = NK_FLAG(7), /* Automatically hides the window scrollbar if no user interaction: also requires delta time in `nk_context` to be set each frame */ - NK_WINDOW_BACKGROUND = NK_FLAG(8) /* Always keep window in the background */ -}; - -/* context */ -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_API int nk_init_default(struct nk_context*, const struct nk_user_font*); -#endif -NK_API int nk_init_fixed(struct nk_context*, void *memory, nk_size size, const struct nk_user_font*); -NK_API int nk_init(struct nk_context*, struct nk_allocator*, const struct nk_user_font*); -NK_API int nk_init_custom(struct nk_context*, struct nk_buffer *cmds, struct nk_buffer *pool, const struct nk_user_font*); -NK_API void nk_clear(struct nk_context*); -NK_API void nk_free(struct nk_context*); -#ifdef NK_INCLUDE_COMMAND_USERDATA -NK_API void nk_set_user_data(struct nk_context*, nk_handle handle); -#endif - -/* window */ -NK_API int nk_begin(struct nk_context*, const char *title, struct nk_rect bounds, nk_flags flags); -NK_API int nk_begin_titled(struct nk_context*, const char *name, const char *title, struct nk_rect bounds, nk_flags flags); -NK_API void nk_end(struct nk_context*); - -NK_API struct nk_window* nk_window_find(struct nk_context *ctx, const char *name); -NK_API struct nk_rect nk_window_get_bounds(const struct nk_context*); -NK_API struct nk_vec2 nk_window_get_position(const struct nk_context*); -NK_API struct nk_vec2 nk_window_get_size(const struct nk_context*); -NK_API float nk_window_get_width(const struct nk_context*); -NK_API float nk_window_get_height(const struct nk_context*); -NK_API struct nk_panel* nk_window_get_panel(struct nk_context*); -NK_API struct nk_rect nk_window_get_content_region(struct nk_context*); -NK_API struct nk_vec2 nk_window_get_content_region_min(struct nk_context*); -NK_API struct nk_vec2 nk_window_get_content_region_max(struct nk_context*); -NK_API struct nk_vec2 nk_window_get_content_region_size(struct nk_context*); -NK_API struct nk_command_buffer* nk_window_get_canvas(struct nk_context*); - -NK_API int nk_window_has_focus(const struct nk_context*); -NK_API int nk_window_is_collapsed(struct nk_context*, const char*); -NK_API int nk_window_is_closed(struct nk_context*, const char*); -NK_API int nk_window_is_hidden(struct nk_context*, const char*); -NK_API int nk_window_is_active(struct nk_context*, const char*); -NK_API int nk_window_is_hovered(struct nk_context*); -NK_API int nk_window_is_any_hovered(struct nk_context*); -NK_API int nk_item_is_any_active(struct nk_context*); - -NK_API void nk_window_set_bounds(struct nk_context*, struct nk_rect); -NK_API void nk_window_set_position(struct nk_context*, struct nk_vec2); -NK_API void nk_window_set_size(struct nk_context*, struct nk_vec2); -NK_API void nk_window_set_focus(struct nk_context*, const char *name); - -NK_API void nk_window_close(struct nk_context *ctx, const char *name); -NK_API void nk_window_collapse(struct nk_context*, const char *name, enum nk_collapse_states); -NK_API void nk_window_collapse_if(struct nk_context*, const char *name, enum nk_collapse_states, int cond); -NK_API void nk_window_show(struct nk_context*, const char *name, enum nk_show_states); -NK_API void nk_window_show_if(struct nk_context*, const char *name, enum nk_show_states, int cond); - -/* Layout */ -NK_API void nk_layout_row_dynamic(struct nk_context*, float height, int cols); -NK_API void nk_layout_row_static(struct nk_context*, float height, int item_width, int cols); - -NK_API void nk_layout_row_begin(struct nk_context*, enum nk_layout_format, float row_height, int cols); -NK_API void nk_layout_row_push(struct nk_context*, float value); -NK_API void nk_layout_row_end(struct nk_context*); -NK_API void nk_layout_row(struct nk_context*, enum nk_layout_format, float height, int cols, const float *ratio); - -NK_API void nk_layout_space_begin(struct nk_context*, enum nk_layout_format, float height, int widget_count); -NK_API void nk_layout_space_push(struct nk_context*, struct nk_rect); -NK_API void nk_layout_space_end(struct nk_context*); - -NK_API struct nk_rect nk_layout_space_bounds(struct nk_context*); -NK_API struct nk_vec2 nk_layout_space_to_screen(struct nk_context*, struct nk_vec2); -NK_API struct nk_vec2 nk_layout_space_to_local(struct nk_context*, struct nk_vec2); -NK_API struct nk_rect nk_layout_space_rect_to_screen(struct nk_context*, struct nk_rect); -NK_API struct nk_rect nk_layout_space_rect_to_local(struct nk_context*, struct nk_rect); -NK_API float nk_layout_ratio_from_pixel(struct nk_context*, float pixel_width); - -/* Layout: Group */ -NK_API int nk_group_begin(struct nk_context*, const char *title, nk_flags); -NK_API int nk_group_scrolled_offset_begin(struct nk_context*, nk_uint *x_offset, nk_uint *y_offset, const char*, nk_flags); -NK_API int nk_group_scrolled_begin(struct nk_context*, struct nk_scroll*, const char *title, nk_flags); -NK_API void nk_group_scrolled_end(struct nk_context*); -NK_API void nk_group_end(struct nk_context*); - -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); -NK_API void nk_list_view_end(struct nk_list_view*); - -/* Layout: Tree */ -#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__) -#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) -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); -#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__) -#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) -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); -NK_API void nk_tree_pop(struct nk_context*); - -NK_API int nk_tree_state_push(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states *state); -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); -NK_API void nk_tree_state_pop(struct nk_context*); - -/* Widgets */ -NK_API void nk_text(struct nk_context*, const char*, int, nk_flags); -NK_API void nk_text_colored(struct nk_context*, const char*, int, nk_flags, struct nk_color); -NK_API void nk_text_wrap(struct nk_context*, const char*, int); -NK_API void nk_text_wrap_colored(struct nk_context*, const char*, int, struct nk_color); - -NK_API void nk_label(struct nk_context*, const char*, nk_flags align); -NK_API void nk_label_colored(struct nk_context*, const char*, nk_flags align, struct nk_color); -NK_API void nk_label_wrap(struct nk_context*, const char*); -NK_API void nk_label_colored_wrap(struct nk_context*, const char*, struct nk_color); -NK_API void nk_image(struct nk_context*, struct nk_image); -#ifdef NK_INCLUDE_STANDARD_VARARGS -NK_API void nk_labelf(struct nk_context*, nk_flags, const char*, ...); -NK_API void nk_labelf_colored(struct nk_context*, nk_flags align, struct nk_color, const char*,...); -NK_API void nk_labelf_wrap(struct nk_context*, const char*,...); -NK_API void nk_labelf_colored_wrap(struct nk_context*, struct nk_color, const char*,...); - -NK_API void nk_value_bool(struct nk_context*, const char *prefix, int); -NK_API void nk_value_int(struct nk_context*, const char *prefix, int); -NK_API void nk_value_uint(struct nk_context*, const char *prefix, unsigned int); -NK_API void nk_value_float(struct nk_context*, const char *prefix, float); -NK_API void nk_value_color_byte(struct nk_context*, const char *prefix, struct nk_color); -NK_API void nk_value_color_float(struct nk_context*, const char *prefix, struct nk_color); -NK_API void nk_value_color_hex(struct nk_context*, const char *prefix, struct nk_color); -#endif - -/* Widgets: Buttons */ -NK_API void nk_button_set_behavior(struct nk_context*, enum nk_button_behavior); -NK_API int nk_button_push_behavior(struct nk_context*, enum nk_button_behavior); -NK_API int nk_button_pop_behavior(struct nk_context*); - -NK_API int nk_button_text(struct nk_context*, const char *title, int len); -NK_API int nk_button_label(struct nk_context*, const char *title); -NK_API int nk_button_color(struct nk_context*, struct nk_color); -NK_API int nk_button_symbol(struct nk_context*, enum nk_symbol_type); -NK_API int nk_button_image(struct nk_context*, struct nk_image img); -NK_API int nk_button_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags text_alignment); -NK_API int nk_button_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment); -NK_API int nk_button_image_label(struct nk_context*, struct nk_image img, const char*, nk_flags text_alignment); -NK_API int nk_button_image_text(struct nk_context*, struct nk_image img, const char*, int, nk_flags alignment); - -NK_API int nk_button_text_styled(struct nk_context*, const struct nk_style_button*, const char *title, int len); -NK_API int nk_button_label_styled(struct nk_context*, const struct nk_style_button*, const char *title); -NK_API int nk_button_symbol_styled(struct nk_context*, const struct nk_style_button*, enum nk_symbol_type); -NK_API int nk_button_image_styled(struct nk_context*, const struct nk_style_button*, struct nk_image img); -NK_API int nk_button_symbol_label_styled(struct nk_context*,const struct nk_style_button*, enum nk_symbol_type, const char*, nk_flags text_alignment); -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); -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); -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); - -/* Widgets: Checkbox */ -NK_API int nk_check_label(struct nk_context*, const char*, int active); -NK_API int nk_check_text(struct nk_context*, const char*, int,int active); -NK_API unsigned nk_check_flags_label(struct nk_context*, const char*, unsigned int flags, unsigned int value); -NK_API unsigned nk_check_flags_text(struct nk_context*, const char*, int, unsigned int flags, unsigned int value); -NK_API int nk_checkbox_label(struct nk_context*, const char*, int *active); -NK_API int nk_checkbox_text(struct nk_context*, const char*, int, int *active); -NK_API int nk_checkbox_flags_label(struct nk_context*, const char*, unsigned int *flags, unsigned int value); -NK_API int nk_checkbox_flags_text(struct nk_context*, const char*, int, unsigned int *flags, unsigned int value); - -/* Widgets: Radio */ -NK_API int nk_radio_label(struct nk_context*, const char*, int *active); -NK_API int nk_radio_text(struct nk_context*, const char*, int, int *active); -NK_API int nk_option_label(struct nk_context*, const char*, int active); -NK_API int nk_option_text(struct nk_context*, const char*, int, int active); - -/* Widgets: Selectable */ -NK_API int nk_selectable_label(struct nk_context*, const char*, nk_flags align, int *value); -NK_API int nk_selectable_text(struct nk_context*, const char*, int, nk_flags align, int *value); -NK_API int nk_selectable_image_label(struct nk_context*,struct nk_image, const char*, nk_flags align, int *value); -NK_API int nk_selectable_image_text(struct nk_context*,struct nk_image, const char*, int, nk_flags align, int *value); - -NK_API int nk_select_label(struct nk_context*, const char*, nk_flags align, int value); -NK_API int nk_select_text(struct nk_context*, const char*, int, nk_flags align, int value); -NK_API int nk_select_image_label(struct nk_context*, struct nk_image,const char*, nk_flags align, int value); -NK_API int nk_select_image_text(struct nk_context*, struct nk_image,const char*, int, nk_flags align, int value); - -/* Widgets: Slider */ -NK_API float nk_slide_float(struct nk_context*, float min, float val, float max, float step); -NK_API int nk_slide_int(struct nk_context*, int min, int val, int max, int step); -NK_API int nk_slider_float(struct nk_context*, float min, float *val, float max, float step); -NK_API int nk_slider_int(struct nk_context*, int min, int *val, int max, int step); - -/* Widgets: Progressbar */ -NK_API int nk_progress(struct nk_context*, nk_size *cur, nk_size max, int modifyable); -NK_API nk_size nk_prog(struct nk_context*, nk_size cur, nk_size max, int modifyable); - -/* Widgets: Color picker */ -NK_API struct nk_color nk_color_picker(struct nk_context*, struct nk_color, enum nk_color_format); -NK_API int nk_color_pick(struct nk_context*, struct nk_color*, enum nk_color_format); - -/* Widgets: Property */ -NK_API void nk_property_int(struct nk_context*, const char *name, int min, int *val, int max, int step, float inc_per_pixel); -NK_API void nk_property_float(struct nk_context*, const char *name, float min, float *val, float max, float step, float inc_per_pixel); -NK_API void nk_property_double(struct nk_context*, const char *name, double min, double *val, double max, double step, float inc_per_pixel); -NK_API int nk_propertyi(struct nk_context*, const char *name, int min, int val, int max, int step, float inc_per_pixel); -NK_API float nk_propertyf(struct nk_context*, const char *name, float min, float val, float max, float step, float inc_per_pixel); -NK_API double nk_propertyd(struct nk_context*, const char *name, double min, double val, double max, double step, float inc_per_pixel); - -/* Widgets: TextEdit */ -NK_API void nk_edit_focus(struct nk_context *ctx, nk_flags flags); -NK_API nk_flags nk_edit_string(struct nk_context*, nk_flags, char *buffer, int *len, int max, nk_plugin_filter); -NK_API nk_flags nk_edit_buffer(struct nk_context*, nk_flags, struct nk_text_edit*, nk_plugin_filter); -NK_API nk_flags nk_edit_string_zero_terminated(struct nk_context*, nk_flags, char *buffer, int max, nk_plugin_filter); - -/* Chart */ -NK_API int nk_chart_begin(struct nk_context*, enum nk_chart_type, int num, float min, float max); -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); -NK_API void nk_chart_add_slot(struct nk_context *ctx, const enum nk_chart_type, int count, float min_value, float max_value); -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); -NK_API nk_flags nk_chart_push(struct nk_context*, float); -NK_API nk_flags nk_chart_push_slot(struct nk_context*, float, int); -NK_API void nk_chart_end(struct nk_context*); -NK_API void nk_plot(struct nk_context*, enum nk_chart_type, const float *values, int count, int offset); -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); - -/* Popups */ -NK_API int nk_popup_begin(struct nk_context*, enum nk_popup_type, const char*, nk_flags, struct nk_rect bounds); -NK_API void nk_popup_close(struct nk_context*); -NK_API void nk_popup_end(struct nk_context*); - -/* Combobox */ -NK_API int nk_combo(struct nk_context*, const char **items, int count, int selected, int item_height, struct nk_vec2 size); -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); -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); -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); -NK_API void nk_combobox(struct nk_context*, const char **items, int count, int *selected, int item_height, struct nk_vec2 size); -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); -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); -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); - -/* Combobox: abstract */ -NK_API int nk_combo_begin_text(struct nk_context*, const char *selected, int, struct nk_vec2 size); -NK_API int nk_combo_begin_label(struct nk_context*, const char *selected, struct nk_vec2 size); -NK_API int nk_combo_begin_color(struct nk_context*, struct nk_color color, struct nk_vec2 size); -NK_API int nk_combo_begin_symbol(struct nk_context*, enum nk_symbol_type, struct nk_vec2 size); -NK_API int nk_combo_begin_symbol_label(struct nk_context*, const char *selected, enum nk_symbol_type, struct nk_vec2 size); -NK_API int nk_combo_begin_symbol_text(struct nk_context*, const char *selected, int, enum nk_symbol_type, struct nk_vec2 size); -NK_API int nk_combo_begin_image(struct nk_context*, struct nk_image img, struct nk_vec2 size); -NK_API int nk_combo_begin_image_label(struct nk_context*, const char *selected, struct nk_image, struct nk_vec2 size); -NK_API int nk_combo_begin_image_text(struct nk_context*, const char *selected, int, struct nk_image, struct nk_vec2 size); -NK_API int nk_combo_item_label(struct nk_context*, const char*, nk_flags alignment); -NK_API int nk_combo_item_text(struct nk_context*, const char*,int, nk_flags alignment); -NK_API int nk_combo_item_image_label(struct nk_context*, struct nk_image, const char*, nk_flags alignment); -NK_API int nk_combo_item_image_text(struct nk_context*, struct nk_image, const char*, int,nk_flags alignment); -NK_API int nk_combo_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags alignment); -NK_API int nk_combo_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment); -NK_API void nk_combo_close(struct nk_context*); -NK_API void nk_combo_end(struct nk_context*); - -/* Contextual */ -NK_API int nk_contextual_begin(struct nk_context*, nk_flags, struct nk_vec2, struct nk_rect trigger_bounds); -NK_API int nk_contextual_item_text(struct nk_context*, const char*, int,nk_flags align); -NK_API int nk_contextual_item_label(struct nk_context*, const char*, nk_flags align); -NK_API int nk_contextual_item_image_label(struct nk_context*, struct nk_image, const char*, nk_flags alignment); -NK_API int nk_contextual_item_image_text(struct nk_context*, struct nk_image, const char*, int len, nk_flags alignment); -NK_API int nk_contextual_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags alignment); -NK_API int nk_contextual_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment); -NK_API void nk_contextual_close(struct nk_context*); -NK_API void nk_contextual_end(struct nk_context*); - -/* Tooltip */ -NK_API void nk_tooltip(struct nk_context*, const char*); -NK_API int nk_tooltip_begin(struct nk_context*, float width); -NK_API void nk_tooltip_end(struct nk_context*); - -/* Menu */ -NK_API void nk_menubar_begin(struct nk_context*); -NK_API void nk_menubar_end(struct nk_context*); - -NK_API int nk_menu_begin_text(struct nk_context*, const char* title, int title_len, nk_flags align, struct nk_vec2 size); -NK_API int nk_menu_begin_label(struct nk_context*, const char*, nk_flags align, struct nk_vec2 size); -NK_API int nk_menu_begin_image(struct nk_context*, const char*, struct nk_image, struct nk_vec2 size); -NK_API int nk_menu_begin_image_text(struct nk_context*, const char*, int,nk_flags align,struct nk_image, struct nk_vec2 size); -NK_API int nk_menu_begin_image_label(struct nk_context*, const char*, nk_flags align,struct nk_image, struct nk_vec2 size); -NK_API int nk_menu_begin_symbol(struct nk_context*, const char*, enum nk_symbol_type, struct nk_vec2 size); -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); -NK_API int nk_menu_begin_symbol_label(struct nk_context*, const char*, nk_flags align,enum nk_symbol_type, struct nk_vec2 size); -NK_API int nk_menu_item_text(struct nk_context*, const char*, int,nk_flags align); -NK_API int nk_menu_item_label(struct nk_context*, const char*, nk_flags alignment); -NK_API int nk_menu_item_image_label(struct nk_context*, struct nk_image, const char*, nk_flags alignment); -NK_API int nk_menu_item_image_text(struct nk_context*, struct nk_image, const char*, int len, nk_flags alignment); -NK_API int nk_menu_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment); -NK_API int nk_menu_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags alignment); -NK_API void nk_menu_close(struct nk_context*); -NK_API void nk_menu_end(struct nk_context*); - -/* Drawing*/ -#define nk_foreach(c, ctx) for((c)=nk__begin(ctx); (c)!=0; (c)=nk__next(ctx, c)) -#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT -NK_API void nk_convert(struct nk_context*, struct nk_buffer *cmds, struct nk_buffer *vertices, struct nk_buffer *elements, const struct nk_convert_config*); -#define nk_draw_foreach(cmd,ctx, b) for((cmd)=nk__draw_begin(ctx, b); (cmd)!=0; (cmd)=nk__draw_next(cmd, b, ctx)) -#define nk_draw_foreach_bounded(cmd,from,to) for((cmd)=(from); (cmd) && (to) && (cmd)>=to; --(cmd)) -NK_API const struct nk_draw_command* nk__draw_begin(const struct nk_context*, const struct nk_buffer*); -NK_API const struct nk_draw_command* nk__draw_end(const struct nk_context*, const struct nk_buffer*); -NK_API const struct nk_draw_command* nk__draw_next(const struct nk_draw_command*, const struct nk_buffer*, const struct nk_context*); -#endif - -/* User Input */ -NK_API void nk_input_begin(struct nk_context*); -NK_API void nk_input_motion(struct nk_context*, int x, int y); -NK_API void nk_input_key(struct nk_context*, enum nk_keys, int down); -NK_API void nk_input_button(struct nk_context*, enum nk_buttons, int x, int y, int down); -NK_API void nk_input_scroll(struct nk_context*, float y); -NK_API void nk_input_char(struct nk_context*, char); -NK_API void nk_input_glyph(struct nk_context*, const nk_glyph); -NK_API void nk_input_unicode(struct nk_context*, nk_rune); -NK_API void nk_input_end(struct nk_context*); - -/* Style */ -NK_API void nk_style_default(struct nk_context*); -NK_API void nk_style_from_table(struct nk_context*, const struct nk_color*); -NK_API void nk_style_load_cursor(struct nk_context*, enum nk_style_cursor, const struct nk_cursor*); -NK_API void nk_style_load_all_cursors(struct nk_context*, struct nk_cursor*); -NK_API const char* nk_style_get_color_by_name(enum nk_style_colors); -NK_API void nk_style_set_font(struct nk_context*, const struct nk_user_font*); -NK_API int nk_style_set_cursor(struct nk_context*, enum nk_style_cursor); -NK_API void nk_style_show_cursor(struct nk_context*); -NK_API void nk_style_hide_cursor(struct nk_context*); - -/* Style: stack */ -NK_API int nk_style_push_font(struct nk_context*, struct nk_user_font*); -NK_API int nk_style_push_float(struct nk_context*, float*, float); -NK_API int nk_style_push_vec2(struct nk_context*, struct nk_vec2*, struct nk_vec2); -NK_API int nk_style_push_style_item(struct nk_context*, struct nk_style_item*, struct nk_style_item); -NK_API int nk_style_push_flags(struct nk_context*, nk_flags*, nk_flags); -NK_API int nk_style_push_color(struct nk_context*, struct nk_color*, struct nk_color); - -NK_API int nk_style_pop_font(struct nk_context*); -NK_API int nk_style_pop_float(struct nk_context*); -NK_API int nk_style_pop_vec2(struct nk_context*); -NK_API int nk_style_pop_style_item(struct nk_context*); -NK_API int nk_style_pop_flags(struct nk_context*); -NK_API int nk_style_pop_color(struct nk_context*); - -/* Utilities */ -NK_API struct nk_rect nk_widget_bounds(struct nk_context*); -NK_API struct nk_vec2 nk_widget_position(struct nk_context*); -NK_API struct nk_vec2 nk_widget_size(struct nk_context*); -NK_API float nk_widget_width(struct nk_context*); -NK_API float nk_widget_height(struct nk_context*); -NK_API int nk_widget_is_hovered(struct nk_context*); -NK_API int nk_widget_is_mouse_clicked(struct nk_context*, enum nk_buttons); -NK_API int nk_widget_has_mouse_click_down(struct nk_context*, enum nk_buttons, int down); -NK_API void nk_spacing(struct nk_context*, int cols); - -/* base widget function */ -NK_API enum nk_widget_layout_states nk_widget(struct nk_rect*, const struct nk_context*); -NK_API enum nk_widget_layout_states nk_widget_fitting(struct nk_rect*, struct nk_context*, struct nk_vec2); - -/* color (conversion user --> nuklear) */ -NK_API struct nk_color nk_rgb(int r, int g, int b); -NK_API struct nk_color nk_rgb_iv(const int *rgb); -NK_API struct nk_color nk_rgb_bv(const nk_byte* rgb); -NK_API struct nk_color nk_rgb_f(float r, float g, float b); -NK_API struct nk_color nk_rgb_fv(const float *rgb); -NK_API struct nk_color nk_rgb_hex(const char *rgb); - -NK_API struct nk_color nk_rgba(int r, int g, int b, int a); -NK_API struct nk_color nk_rgba_u32(nk_uint); -NK_API struct nk_color nk_rgba_iv(const int *rgba); -NK_API struct nk_color nk_rgba_bv(const nk_byte *rgba); -NK_API struct nk_color nk_rgba_f(float r, float g, float b, float a); -NK_API struct nk_color nk_rgba_fv(const float *rgba); -NK_API struct nk_color nk_rgba_hex(const char *rgb); - -NK_API struct nk_color nk_hsv(int h, int s, int v); -NK_API struct nk_color nk_hsv_iv(const int *hsv); -NK_API struct nk_color nk_hsv_bv(const nk_byte *hsv); -NK_API struct nk_color nk_hsv_f(float h, float s, float v); -NK_API struct nk_color nk_hsv_fv(const float *hsv); - -NK_API struct nk_color nk_hsva(int h, int s, int v, int a); -NK_API struct nk_color nk_hsva_iv(const int *hsva); -NK_API struct nk_color nk_hsva_bv(const nk_byte *hsva); -NK_API struct nk_color nk_hsva_f(float h, float s, float v, float a); -NK_API struct nk_color nk_hsva_fv(const float *hsva); - -/* color (conversion nuklear --> user) */ -NK_API void nk_color_f(float *r, float *g, float *b, float *a, struct nk_color); -NK_API void nk_color_fv(float *rgba_out, struct nk_color); -NK_API void nk_color_d(double *r, double *g, double *b, double *a, struct nk_color); -NK_API void nk_color_dv(double *rgba_out, struct nk_color); - -NK_API nk_uint nk_color_u32(struct nk_color); -NK_API void nk_color_hex_rgba(char *output, struct nk_color); -NK_API void nk_color_hex_rgb(char *output, struct nk_color); - -NK_API void nk_color_hsv_i(int *out_h, int *out_s, int *out_v, struct nk_color); -NK_API void nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v, struct nk_color); -NK_API void nk_color_hsv_iv(int *hsv_out, struct nk_color); -NK_API void nk_color_hsv_bv(nk_byte *hsv_out, struct nk_color); -NK_API void nk_color_hsv_f(float *out_h, float *out_s, float *out_v, struct nk_color); -NK_API void nk_color_hsv_fv(float *hsv_out, struct nk_color); - -NK_API void nk_color_hsva_i(int *h, int *s, int *v, int *a, struct nk_color); -NK_API void nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a, struct nk_color); -NK_API void nk_color_hsva_iv(int *hsva_out, struct nk_color); -NK_API void nk_color_hsva_bv(nk_byte *hsva_out, struct nk_color); -NK_API void nk_color_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_color); -NK_API void nk_color_hsva_fv(float *hsva_out, struct nk_color); - -/* image */ -NK_API nk_handle nk_handle_ptr(void*); -NK_API nk_handle nk_handle_id(int); -NK_API struct nk_image nk_image_handle(nk_handle); -NK_API struct nk_image nk_image_ptr(void*); -NK_API struct nk_image nk_image_id(int); -NK_API int nk_image_is_subimage(const struct nk_image* img); -NK_API struct nk_image nk_subimage_ptr(void*, unsigned short w, unsigned short h, struct nk_rect sub_region); -NK_API struct nk_image nk_subimage_id(int, unsigned short w, unsigned short h, struct nk_rect sub_region); -NK_API struct nk_image nk_subimage_handle(nk_handle, unsigned short w, unsigned short h, struct nk_rect sub_region); - -/* math */ -NK_API nk_hash nk_murmur_hash(const void *key, int len, nk_hash seed); -NK_API void nk_triangle_from_direction(struct nk_vec2 *result, struct nk_rect r, float pad_x, float pad_y, enum nk_heading); - -NK_API struct nk_vec2 nk_vec2(float x, float y); -NK_API struct nk_vec2 nk_vec2i(int x, int y); -NK_API struct nk_vec2 nk_vec2v(const float *xy); -NK_API struct nk_vec2 nk_vec2iv(const int *xy); - -NK_API struct nk_rect nk_get_null_rect(void); -NK_API struct nk_rect nk_rect(float x, float y, float w, float h); -NK_API struct nk_rect nk_recti(int x, int y, int w, int h); -NK_API struct nk_rect nk_recta(struct nk_vec2 pos, struct nk_vec2 size); -NK_API struct nk_rect nk_rectv(const float *xywh); -NK_API struct nk_rect nk_rectiv(const int *xywh); -NK_API struct nk_vec2 nk_rect_pos(struct nk_rect); -NK_API struct nk_vec2 nk_rect_size(struct nk_rect); - -/* string*/ -NK_API int nk_strlen(const char *str); -NK_API int nk_stricmp(const char *s1, const char *s2); -NK_API int nk_stricmpn(const char *s1, const char *s2, int n); -NK_API int nk_strtoi(const char *str, char **endptr); -NK_API float nk_strtof(const char *str, char **endptr); -NK_API double nk_strtod(const char *str, char **endptr); -NK_API int nk_strfilter(const char *text, const char *regexp); -NK_API int nk_strmatch_fuzzy_string(char const *str, char const *pattern, int *out_score); -NK_API int nk_strmatch_fuzzy_text(const char *txt, int txt_len, const char *pattern, int *out_score); - -/* UTF-8 */ -NK_API int nk_utf_decode(const char*, nk_rune*, int); -NK_API int nk_utf_encode(nk_rune, char*, int); -NK_API int nk_utf_len(const char*, int byte_len); -NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune *unicode, int *len); - -/* =============================================================== - * - * FONT - * - * ===============================================================*/ -/* Font handling in this library was designed to be quite customizable and lets - you decide what you want to use and what you want to provide. There are three - different ways to use the font atlas. The first two will use your font - handling scheme and only requires essential data to run nuklear. The next - slightly more advanced features is font handling with vertex buffer output. - Finally the most complex API wise is using nuklears font baking API. - - 1.) Using your own implementation without vertex buffer output - -------------------------------------------------------------- - So first up the easiest way to do font handling is by just providing a - `nk_user_font` struct which only requires the height in pixel of the used - font and a callback to calculate the width of a string. This way of handling - fonts is best fitted for using the normal draw shape command API where you - do all the text drawing yourself and the library does not require any kind - of deeper knowledge about which font handling mechanism you use. - IMPORTANT: the `nk_user_font` pointer provided to nuklear has to persist - over the complete life time! I know this sucks but it is currently the only - way to switch between fonts. - - float your_text_width_calculation(nk_handle handle, float height, const char *text, int len) - { - your_font_type *type = handle.ptr; - float text_width = ...; - return text_width; - } - - struct nk_user_font font; - font.userdata.ptr = &your_font_class_or_struct; - font.height = your_font_height; - font.width = your_text_width_calculation; - - struct nk_context ctx; - nk_init_default(&ctx, &font); - - 2.) Using your own implementation with vertex buffer output - -------------------------------------------------------------- - While the first approach works fine if you don't want to use the optional - vertex buffer output it is not enough if you do. To get font handling working - for these cases you have to provide two additional parameters inside the - `nk_user_font`. First a texture atlas handle used to draw text as subimages - of a bigger font atlas texture and a callback to query a character's glyph - information (offset, size, ...). So it is still possible to provide your own - font and use the vertex buffer output. - - float your_text_width_calculation(nk_handle handle, float height, const char *text, int len) - { - your_font_type *type = handle.ptr; - float text_width = ...; - return text_width; - } - void query_your_font_glyph(nk_handle handle, float font_height, struct nk_user_font_glyph *glyph, nk_rune codepoint, nk_rune next_codepoint) - { - your_font_type *type = handle.ptr; - glyph.width = ...; - glyph.height = ...; - glyph.xadvance = ...; - glyph.uv[0].x = ...; - glyph.uv[0].y = ...; - glyph.uv[1].x = ...; - glyph.uv[1].y = ...; - glyph.offset.x = ...; - glyph.offset.y = ...; - } - - struct nk_user_font font; - font.userdata.ptr = &your_font_class_or_struct; - font.height = your_font_height; - font.width = your_text_width_calculation; - font.query = query_your_font_glyph; - font.texture.id = your_font_texture; - - struct nk_context ctx; - nk_init_default(&ctx, &font); - - 3.) Nuklear font baker - ------------------------------------ - The final approach if you do not have a font handling functionality or don't - want to use it in this library is by using the optional font baker. - The font baker API's can be used to create a font plus font atlas texture - and can be used with or without the vertex buffer output. - - It still uses the `nk_user_font` struct and the two different approaches - previously stated still work. The font baker is not located inside - `nk_context` like all other systems since it can be understood as more of - an extension to nuklear and does not really depend on any `nk_context` state. - - Font baker need to be initialized first by one of the nk_font_atlas_init_xxx - functions. If you don't care about memory just call the default version - `nk_font_atlas_init_default` which will allocate all memory from the standard library. - If you want to control memory allocation but you don't care if the allocated - memory is temporary and therefore can be freed directly after the baking process - is over or permanent you can call `nk_font_atlas_init`. - - After successfull intializing the font baker you can add Truetype(.ttf) fonts from - different sources like memory or from file by calling one of the `nk_font_atlas_add_xxx`. - functions. Adding font will permanently store each font, font config and ttf memory block(!) - inside the font atlas and allows to reuse the font atlas. If you don't want to reuse - the font baker by for example adding additional fonts you can call - `nk_font_atlas_cleanup` after the baking process is over (after calling nk_font_atlas_end). - - As soon as you added all fonts you wanted you can now start the baking process - for every selected glyphes to image by calling `nk_font_atlas_bake`. - The baking process returns image memory, width and height which can be used to - either create your own image object or upload it to any graphics library. - No matter which case you finally have to call `nk_font_atlas_end` which - will free all temporary memory including the font atlas image so make sure - you created our texture beforehand. `nk_font_atlas_end` requires a handle - to your font texture or object and optionally fills a `struct nk_draw_null_texture` - which can be used for the optional vertex output. If you don't want it just - set the argument to `NULL`. - - At this point you are done and if you don't want to reuse the font atlas you - can call `nk_font_atlas_cleanup` to free all truetype blobs and configuration - memory. Finally if you don't use the font atlas and any of it's fonts anymore - you need to call `nk_font_atlas_clear` to free all memory still being used. - - struct nk_font_atlas atlas; - nk_font_atlas_init_default(&atlas); - nk_font_atlas_begin(&atlas); - nk_font *font = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font.ttf", 13, 0); - nk_font *font2 = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font2.ttf", 16, 0); - void* img = nk_font_atlas_bake(&atlas, &img_width, &img_height, NK_FONT_ATLAS_RGBA32, 0); - nk_font_atlas_end(&atlas, nk_handle_id(texture), 0); - - struct nk_context ctx; - nk_init_default(&ctx, &font->handle); - while (1) { - - } - nk_font_atlas_clear(&atlas); - - The font baker API is probably the most complex API inside this library and - I would suggest reading some of my examples `example/` to get a grip on how - to use the font atlas. There are a number of details I left out. For example - how to merge fonts, configure a font with `nk_font_config` to use other languages, - use another texture coodinate format and a lot more: - - struct nk_font_config cfg = nk_font_config(font_pixel_height); - cfg.merge_mode = nk_false or nk_true; - cfg.range = nk_font_korean_glyph_ranges(); - cfg.coord_type = NK_COORD_PIXEL; - nk_font *font = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font.ttf", 13, &cfg); - -*/ -struct nk_user_font_glyph; -typedef float(*nk_text_width_f)(nk_handle, float h, const char*, int len); -typedef void(*nk_query_font_glyph_f)(nk_handle handle, float font_height, - struct nk_user_font_glyph *glyph, - nk_rune codepoint, nk_rune next_codepoint); - -#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT -struct nk_user_font_glyph { - struct nk_vec2 uv[2]; - /* texture coordinates */ - struct nk_vec2 offset; - /* offset between top left and glyph */ - float width, height; - /* size of the glyph */ - float xadvance; - /* offset to the next glyph */ -}; -#endif - -struct nk_user_font { - nk_handle userdata; - /* user provided font handle */ - float height; - /* max height of the font */ - nk_text_width_f width; - /* font string width in pixel callback */ -#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT - nk_query_font_glyph_f query; - /* font glyph callback to query drawing info */ - nk_handle texture; - /* texture handle to the used font atlas or texture */ -#endif -}; - -#ifdef NK_INCLUDE_FONT_BAKING -enum nk_font_coord_type { - NK_COORD_UV, /* texture coordinates inside font glyphs are clamped between 0-1 */ - NK_COORD_PIXEL /* texture coordinates inside font glyphs are in absolute pixel */ -}; - -struct nk_baked_font { - float height; - /* height of the font */ - float ascent, descent; - /* font glyphs ascent and descent */ - nk_rune glyph_offset; - /* glyph array offset inside the font glyph baking output array */ - nk_rune glyph_count; - /* number of glyphs of this font inside the glyph baking array output */ - const nk_rune *ranges; - /* font codepoint ranges as pairs of (from/to) and 0 as last element */ -}; - -struct nk_font_config { - struct nk_font_config *next; - /* NOTE: only used internally */ - void *ttf_blob; - /* pointer to loaded TTF file memory block. - * NOTE: not needed for nk_font_atlas_add_from_memory and nk_font_atlas_add_from_file. */ - nk_size ttf_size; - /* size of the loaded TTF file memory block - * NOTE: not needed for nk_font_atlas_add_from_memory and nk_font_atlas_add_from_file. */ - - unsigned char ttf_data_owned_by_atlas; - /* used inside font atlas: default to: 0*/ - unsigned char merge_mode; - /* merges this font into the last font */ - unsigned char pixel_snap; - /* align every character to pixel boundary (if true set oversample (1,1)) */ - unsigned char oversample_v, oversample_h; - /* rasterize at hight quality for sub-pixel position */ - unsigned char padding[3]; - - float size; - /* baked pixel height of the font */ - enum nk_font_coord_type coord_type; - /* texture coordinate format with either pixel or UV coordinates */ - struct nk_vec2 spacing; - /* extra pixel spacing between glyphs */ - const nk_rune *range; - /* list of unicode ranges (2 values per range, zero terminated) */ - struct nk_baked_font *font; - /* font to setup in the baking process: NOTE: not needed for font atlas */ - nk_rune fallback_glyph; - /* fallback glyph to use if a given rune is not found */ -}; - -struct nk_font_glyph { - nk_rune codepoint; - float xadvance; - float x0, y0, x1, y1, w, h; - float u0, v0, u1, v1; -}; - -struct nk_font { - struct nk_font *next; - struct nk_user_font handle; - struct nk_baked_font info; - float scale; - struct nk_font_glyph *glyphs; - const struct nk_font_glyph *fallback; - nk_rune fallback_codepoint; - nk_handle texture; - struct nk_font_config *config; -}; - -enum nk_font_atlas_format { - NK_FONT_ATLAS_ALPHA8, - NK_FONT_ATLAS_RGBA32 -}; - -struct nk_font_atlas { - void *pixel; - int tex_width; - int tex_height; - - struct nk_allocator permanent; - struct nk_allocator temporary; - - struct nk_recti custom; - struct nk_cursor cursors[NK_CURSOR_COUNT]; - - int glyph_count; - struct nk_font_glyph *glyphs; - struct nk_font *default_font; - struct nk_font *fonts; - struct nk_font_config *config; - int font_num; -}; - -/* some language glyph codepoint ranges */ -NK_API const nk_rune *nk_font_default_glyph_ranges(void); -NK_API const nk_rune *nk_font_chinese_glyph_ranges(void); -NK_API const nk_rune *nk_font_cyrillic_glyph_ranges(void); -NK_API const nk_rune *nk_font_korean_glyph_ranges(void); - -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_API void nk_font_atlas_init_default(struct nk_font_atlas*); -#endif -NK_API void nk_font_atlas_init(struct nk_font_atlas*, struct nk_allocator*); -NK_API void nk_font_atlas_init_custom(struct nk_font_atlas*, struct nk_allocator *persistent, struct nk_allocator *transient); -NK_API void nk_font_atlas_begin(struct nk_font_atlas*); -NK_API struct nk_font_config nk_font_config(float pixel_height); -NK_API struct nk_font *nk_font_atlas_add(struct nk_font_atlas*, const struct nk_font_config*); -#ifdef NK_INCLUDE_DEFAULT_FONT -NK_API struct nk_font* nk_font_atlas_add_default(struct nk_font_atlas*, float height, const struct nk_font_config*); -#endif -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); -#ifdef NK_INCLUDE_STANDARD_IO -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*); -#endif -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*); -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); -NK_API const void* nk_font_atlas_bake(struct nk_font_atlas*, int *width, int *height, enum nk_font_atlas_format); -NK_API void nk_font_atlas_end(struct nk_font_atlas*, nk_handle tex, struct nk_draw_null_texture*); -NK_API const struct nk_font_glyph* nk_font_find_glyph(struct nk_font*, nk_rune unicode); -NK_API void nk_font_atlas_cleanup(struct nk_font_atlas *atlas); -NK_API void nk_font_atlas_clear(struct nk_font_atlas*); - -#endif - -/* ============================================================== - * - * MEMORY BUFFER - * - * ===============================================================*/ -/* A basic (double)-buffer with linear allocation and resetting as only - freeing policy. The buffer's main purpose is to control all memory management - inside the GUI toolkit and still leave memory control as much as possible in - the hand of the user while also making sure the library is easy to use if - not as much control is needed. - In general all memory inside this library can be provided from the user in - three different ways. - - The first way and the one providing most control is by just passing a fixed - size memory block. In this case all control lies in the hand of the user - since he can exactly control where the memory comes from and how much memory - the library should consume. Of course using the fixed size API removes the - ability to automatically resize a buffer if not enough memory is provided so - you have to take over the resizing. While being a fixed sized buffer sounds - quite limiting, it is very effective in this library since the actual memory - consumption is quite stable and has a fixed upper bound for a lot of cases. - - If you don't want to think about how much memory the library should allocate - at all time or have a very dynamic UI with unpredictable memory consumption - habits but still want control over memory allocation you can use the dynamic - allocator based API. The allocator consists of two callbacks for allocating - and freeing memory and optional userdata so you can plugin your own allocator. - - The final and easiest way can be used by defining - NK_INCLUDE_DEFAULT_ALLOCATOR which uses the standard library memory - allocation functions malloc and free and takes over complete control over - memory in this library. -*/ -struct nk_memory_status { - void *memory; - unsigned int type; - nk_size size; - nk_size allocated; - nk_size needed; - nk_size calls; -}; - -enum nk_allocation_type { - NK_BUFFER_FIXED, - NK_BUFFER_DYNAMIC -}; - -enum nk_buffer_allocation_type { - NK_BUFFER_FRONT, - NK_BUFFER_BACK, - NK_BUFFER_MAX -}; - -struct nk_buffer_marker { - int active; - nk_size offset; -}; - -struct nk_memory {void *ptr;nk_size size;}; -struct nk_buffer { - struct nk_buffer_marker marker[NK_BUFFER_MAX]; - /* buffer marker to free a buffer to a certain offset */ - struct nk_allocator pool; - /* allocator callback for dynamic buffers */ - enum nk_allocation_type type; - /* memory management type */ - struct nk_memory memory; - /* memory and size of the current memory block */ - float grow_factor; - /* growing factor for dynamic memory management */ - nk_size allocated; - /* total amount of memory allocated */ - nk_size needed; - /* totally consumed memory given that enough memory is present */ - nk_size calls; - /* number of allocation calls */ - nk_size size; - /* current size of the buffer */ -}; - -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_API void nk_buffer_init_default(struct nk_buffer*); -#endif -NK_API void nk_buffer_init(struct nk_buffer*, const struct nk_allocator*, nk_size size); -NK_API void nk_buffer_init_fixed(struct nk_buffer*, void *memory, nk_size size); -NK_API void nk_buffer_info(struct nk_memory_status*, struct nk_buffer*); -NK_API void nk_buffer_push(struct nk_buffer*, enum nk_buffer_allocation_type type, const void *memory, nk_size size, nk_size align); -NK_API void nk_buffer_mark(struct nk_buffer*, enum nk_buffer_allocation_type type); -NK_API void nk_buffer_reset(struct nk_buffer*, enum nk_buffer_allocation_type type); -NK_API void nk_buffer_clear(struct nk_buffer*); -NK_API void nk_buffer_free(struct nk_buffer*); -NK_API void *nk_buffer_memory(struct nk_buffer*); -NK_API const void *nk_buffer_memory_const(const struct nk_buffer*); -NK_API nk_size nk_buffer_total(struct nk_buffer*); - -/* ============================================================== - * - * STRING - * - * ===============================================================*/ -/* Basic string buffer which is only used in context with the text editor - * to manage and manipulate dynamic or fixed size string content. This is _NOT_ - * the default string handling method. The only instance you should have any contact - * with this API is if you interact with an `nk_text_edit` object inside one of the - * copy and paste functions and even there only for more advanced cases. */ -struct nk_str { - struct nk_buffer buffer; - int len; /* in codepoints/runes/glyphs */ -}; - -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_API void nk_str_init_default(struct nk_str*); -#endif -NK_API void nk_str_init(struct nk_str*, const struct nk_allocator*, nk_size size); -NK_API void nk_str_init_fixed(struct nk_str*, void *memory, nk_size size); -NK_API void nk_str_clear(struct nk_str*); -NK_API void nk_str_free(struct nk_str*); - -NK_API int nk_str_append_text_char(struct nk_str*, const char*, int); -NK_API int nk_str_append_str_char(struct nk_str*, const char*); -NK_API int nk_str_append_text_utf8(struct nk_str*, const char*, int); -NK_API int nk_str_append_str_utf8(struct nk_str*, const char*); -NK_API int nk_str_append_text_runes(struct nk_str*, const nk_rune*, int); -NK_API int nk_str_append_str_runes(struct nk_str*, const nk_rune*); - -NK_API int nk_str_insert_at_char(struct nk_str*, int pos, const char*, int); -NK_API int nk_str_insert_at_rune(struct nk_str*, int pos, const char*, int); - -NK_API int nk_str_insert_text_char(struct nk_str*, int pos, const char*, int); -NK_API int nk_str_insert_str_char(struct nk_str*, int pos, const char*); -NK_API int nk_str_insert_text_utf8(struct nk_str*, int pos, const char*, int); -NK_API int nk_str_insert_str_utf8(struct nk_str*, int pos, const char*); -NK_API int nk_str_insert_text_runes(struct nk_str*, int pos, const nk_rune*, int); -NK_API int nk_str_insert_str_runes(struct nk_str*, int pos, const nk_rune*); - -NK_API void nk_str_remove_chars(struct nk_str*, int len); -NK_API void nk_str_remove_runes(struct nk_str *str, int len); -NK_API void nk_str_delete_chars(struct nk_str*, int pos, int len); -NK_API void nk_str_delete_runes(struct nk_str*, int pos, int len); - -NK_API char *nk_str_at_char(struct nk_str*, int pos); -NK_API char *nk_str_at_rune(struct nk_str*, int pos, nk_rune *unicode, int *len); -NK_API nk_rune nk_str_rune_at(const struct nk_str*, int pos); -NK_API const char *nk_str_at_char_const(const struct nk_str*, int pos); -NK_API const char *nk_str_at_const(const struct nk_str*, int pos, nk_rune *unicode, int *len); - -NK_API char *nk_str_get(struct nk_str*); -NK_API const char *nk_str_get_const(const struct nk_str*); -NK_API int nk_str_len(struct nk_str*); -NK_API int nk_str_len_char(struct nk_str*); - -/*=============================================================== - * - * TEXT EDITOR - * - * ===============================================================*/ -/* Editing text in this library is handled by either `nk_edit_string` or - * `nk_edit_buffer`. But like almost everything in this library there are multiple - * ways of doing it and a balance between control and ease of use with memory - * as well as functionality controlled by flags. - * - * This library generally allows three different levels of memory control: - * First of is the most basic way of just providing a simple char array with - * string length. This method is probably the easiest way of handling simple - * user text input. Main upside is complete control over memory while the biggest - * downside in comparsion with the other two approaches is missing undo/redo. - * - * For UIs that require undo/redo the second way was created. It is based on - * a fixed size nk_text_edit struct, which has an internal undo/redo stack. - * This is mainly useful if you want something more like a text editor but don't want - * to have a dynamically growing buffer. - * - * The final way is using a dynamically growing nk_text_edit struct, which - * has both a default version if you don't care where memory comes from and an - * allocator version if you do. While the text editor is quite powerful for its - * complexity I would not recommend editing gigabytes of data with it. - * It is rather designed for uses cases which make sense for a GUI library not for - * an full blown text editor. - */ -#ifndef NK_TEXTEDIT_UNDOSTATECOUNT -#define NK_TEXTEDIT_UNDOSTATECOUNT 99 -#endif - -#ifndef NK_TEXTEDIT_UNDOCHARCOUNT -#define NK_TEXTEDIT_UNDOCHARCOUNT 999 -#endif - -struct nk_text_edit; -struct nk_clipboard { - nk_handle userdata; - nk_plugin_paste paste; - nk_plugin_copy copy; -}; - -struct nk_text_undo_record { - int where; - short insert_length; - short delete_length; - short char_storage; -}; - -struct nk_text_undo_state { - struct nk_text_undo_record undo_rec[NK_TEXTEDIT_UNDOSTATECOUNT]; - nk_rune undo_char[NK_TEXTEDIT_UNDOCHARCOUNT]; - short undo_point; - short redo_point; - short undo_char_point; - short redo_char_point; -}; - -enum nk_text_edit_type { - NK_TEXT_EDIT_SINGLE_LINE, - NK_TEXT_EDIT_MULTI_LINE -}; - -enum nk_text_edit_mode { - NK_TEXT_EDIT_MODE_VIEW, - NK_TEXT_EDIT_MODE_INSERT, - NK_TEXT_EDIT_MODE_REPLACE -}; - -struct nk_text_edit { - struct nk_clipboard clip; - struct nk_str string; - nk_plugin_filter filter; - struct nk_vec2 scrollbar; - - int cursor; - int select_start; - int select_end; - unsigned char mode; - unsigned char cursor_at_end_of_line; - unsigned char initialized; - unsigned char has_preferred_x; - unsigned char single_line; - unsigned char active; - unsigned char padding1; - float preferred_x; - struct nk_text_undo_state undo; -}; - -/* filter function */ -NK_API int nk_filter_default(const struct nk_text_edit*, nk_rune unicode); -NK_API int nk_filter_ascii(const struct nk_text_edit*, nk_rune unicode); -NK_API int nk_filter_float(const struct nk_text_edit*, nk_rune unicode); -NK_API int nk_filter_decimal(const struct nk_text_edit*, nk_rune unicode); -NK_API int nk_filter_hex(const struct nk_text_edit*, nk_rune unicode); -NK_API int nk_filter_oct(const struct nk_text_edit*, nk_rune unicode); -NK_API int nk_filter_binary(const struct nk_text_edit*, nk_rune unicode); - -/* text editor */ -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_API void nk_textedit_init_default(struct nk_text_edit*); -#endif -NK_API void nk_textedit_init(struct nk_text_edit*, struct nk_allocator*, nk_size size); -NK_API void nk_textedit_init_fixed(struct nk_text_edit*, void *memory, nk_size size); -NK_API void nk_textedit_free(struct nk_text_edit*); -NK_API void nk_textedit_text(struct nk_text_edit*, const char*, int total_len); -NK_API void nk_textedit_delete(struct nk_text_edit*, int where, int len); -NK_API void nk_textedit_delete_selection(struct nk_text_edit*); -NK_API void nk_textedit_select_all(struct nk_text_edit*); -NK_API int nk_textedit_cut(struct nk_text_edit*); -NK_API int nk_textedit_paste(struct nk_text_edit*, char const*, int len); -NK_API void nk_textedit_undo(struct nk_text_edit*); -NK_API void nk_textedit_redo(struct nk_text_edit*); - -/* =============================================================== - * - * DRAWING - * - * ===============================================================*/ -/* This library was designed to be render backend agnostic so it does - not draw anything to screen. Instead all drawn shapes, widgets - are made of, are buffered into memory and make up a command queue. - Each frame therefore fills the command buffer with draw commands - that then need to be executed by the user and his own render backend. - After that the command buffer needs to be cleared and a new frame can be - started. It is probably important to note that the command buffer is the main - drawing API and the optional vertex buffer API only takes this format and - converts it into a hardware accessible format. - - To use the command queue to draw your own widgets you can access the - command buffer of each window by calling `nk_window_get_canvas` after - previously having called `nk_begin`: - - void draw_red_rectangle_widget(struct nk_context *ctx) - { - struct nk_command_buffer *canvas; - struct nk_input *input = &ctx->input; - canvas = nk_window_get_canvas(ctx); - - struct nk_rect space; - enum nk_widget_layout_states state; - state = nk_widget(&space, ctx); - if (!state) return; - - if (state != NK_WIDGET_ROM) - update_your_widget_by_user_input(...); - nk_fill_rect(canvas, space, 0, nk_rgb(255,0,0)); - } - - if (nk_begin(...)) { - nk_layout_row_dynamic(ctx, 25, 1); - draw_red_rectangle_widget(ctx); - } - nk_end(..) - - Important to know if you want to create your own widgets is the `nk_widget` - call. It allocates space on the panel reserved for this widget to be used, - but also returns the state of the widget space. If your widget is not seen and does - not have to be updated it is '0' and you can just return. If it only has - to be drawn the state will be `NK_WIDGET_ROM` otherwise you can do both - update and draw your widget. The reason for seperating is to only draw and - update what is actually neccessary which is crucial for performance. -*/ -enum nk_command_type { - NK_COMMAND_NOP, - NK_COMMAND_SCISSOR, - NK_COMMAND_LINE, - NK_COMMAND_CURVE, - NK_COMMAND_RECT, - NK_COMMAND_RECT_FILLED, - NK_COMMAND_RECT_MULTI_COLOR, - NK_COMMAND_CIRCLE, - NK_COMMAND_CIRCLE_FILLED, - NK_COMMAND_ARC, - NK_COMMAND_ARC_FILLED, - NK_COMMAND_TRIANGLE, - NK_COMMAND_TRIANGLE_FILLED, - NK_COMMAND_POLYGON, - NK_COMMAND_POLYGON_FILLED, - NK_COMMAND_POLYLINE, - NK_COMMAND_TEXT, - NK_COMMAND_IMAGE -}; - -/* command base and header of every command inside the buffer */ -struct nk_command { - enum nk_command_type type; - nk_size next; -#ifdef NK_INCLUDE_COMMAND_USERDATA - nk_handle userdata; -#endif -}; - -struct nk_command_scissor { - struct nk_command header; - short x, y; - unsigned short w, h; -}; - -struct nk_command_line { - struct nk_command header; - unsigned short line_thickness; - struct nk_vec2i begin; - struct nk_vec2i end; - struct nk_color color; -}; - -struct nk_command_curve { - struct nk_command header; - unsigned short line_thickness; - struct nk_vec2i begin; - struct nk_vec2i end; - struct nk_vec2i ctrl[2]; - struct nk_color color; -}; - -struct nk_command_rect { - struct nk_command header; - unsigned short rounding; - unsigned short line_thickness; - short x, y; - unsigned short w, h; - struct nk_color color; -}; - -struct nk_command_rect_filled { - struct nk_command header; - unsigned short rounding; - short x, y; - unsigned short w, h; - struct nk_color color; -}; - -struct nk_command_rect_multi_color { - struct nk_command header; - short x, y; - unsigned short w, h; - struct nk_color left; - struct nk_color top; - struct nk_color bottom; - struct nk_color right; -}; - -struct nk_command_triangle { - struct nk_command header; - unsigned short line_thickness; - struct nk_vec2i a; - struct nk_vec2i b; - struct nk_vec2i c; - struct nk_color color; -}; - -struct nk_command_triangle_filled { - struct nk_command header; - struct nk_vec2i a; - struct nk_vec2i b; - struct nk_vec2i c; - struct nk_color color; -}; - -struct nk_command_circle { - struct nk_command header; - short x, y; - unsigned short line_thickness; - unsigned short w, h; - struct nk_color color; -}; - -struct nk_command_circle_filled { - struct nk_command header; - short x, y; - unsigned short w, h; - struct nk_color color; -}; - -struct nk_command_arc { - struct nk_command header; - short cx, cy; - unsigned short r; - unsigned short line_thickness; - float a[2]; - struct nk_color color; -}; - -struct nk_command_arc_filled { - struct nk_command header; - short cx, cy; - unsigned short r; - float a[2]; - struct nk_color color; -}; - -struct nk_command_polygon { - struct nk_command header; - struct nk_color color; - unsigned short line_thickness; - unsigned short point_count; - struct nk_vec2i points[1]; -}; - -struct nk_command_polygon_filled { - struct nk_command header; - struct nk_color color; - unsigned short point_count; - struct nk_vec2i points[1]; -}; - -struct nk_command_polyline { - struct nk_command header; - struct nk_color color; - unsigned short line_thickness; - unsigned short point_count; - struct nk_vec2i points[1]; -}; - -struct nk_command_image { - struct nk_command header; - short x, y; - unsigned short w, h; - struct nk_image img; - struct nk_color col; -}; - -struct nk_command_text { - struct nk_command header; - const struct nk_user_font *font; - struct nk_color background; - struct nk_color foreground; - short x, y; - unsigned short w, h; - float height; - int length; - char string[1]; -}; - -enum nk_command_clipping { - NK_CLIPPING_OFF = nk_false, - NK_CLIPPING_ON = nk_true -}; - -struct nk_command_buffer { - struct nk_buffer *base; - struct nk_rect clip; - int use_clipping; - nk_handle userdata; - nk_size begin, end, last; -}; - -/* shape outlines */ -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); -NK_API void nk_stroke_curve(struct nk_command_buffer*, float, float, float, float, float, float, float, float, float line_thickness, struct nk_color); -NK_API void nk_stroke_rect(struct nk_command_buffer*, struct nk_rect, float rounding, float line_thickness, struct nk_color); -NK_API void nk_stroke_circle(struct nk_command_buffer*, struct nk_rect, float line_thickness, struct nk_color); -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); -NK_API void nk_stroke_triangle(struct nk_command_buffer*, float, float, float, float, float, float, float line_thichness, struct nk_color); -NK_API void nk_stroke_polyline(struct nk_command_buffer*, float *points, int point_count, float line_thickness, struct nk_color col); -NK_API void nk_stroke_polygon(struct nk_command_buffer*, float*, int point_count, float line_thickness, struct nk_color); - -/* filled shades */ -NK_API void nk_fill_rect(struct nk_command_buffer*, struct nk_rect, float rounding, struct nk_color); -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); -NK_API void nk_fill_circle(struct nk_command_buffer*, struct nk_rect, struct nk_color); -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); -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); -NK_API void nk_fill_polygon(struct nk_command_buffer*, float*, int point_count, struct nk_color); - -/* misc */ -NK_API void nk_push_scissor(struct nk_command_buffer*, struct nk_rect); -NK_API void nk_draw_image(struct nk_command_buffer*, struct nk_rect, const struct nk_image*, struct nk_color); -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); -NK_API const struct nk_command* nk__next(struct nk_context*, const struct nk_command*); -NK_API const struct nk_command* nk__begin(struct nk_context*); - -/* =============================================================== - * - * INPUT - * - * ===============================================================*/ -struct nk_mouse_button { - int down; - unsigned int clicked; - struct nk_vec2 clicked_pos; -}; -struct nk_mouse { - struct nk_mouse_button buttons[NK_BUTTON_MAX]; - struct nk_vec2 pos; - struct nk_vec2 prev; - struct nk_vec2 delta; - float scroll_delta; - unsigned char grab; - unsigned char grabbed; - unsigned char ungrab; -}; - -struct nk_key { - int down; - unsigned int clicked; -}; -struct nk_keyboard { - struct nk_key keys[NK_KEY_MAX]; - char text[NK_INPUT_MAX]; - int text_len; -}; - -struct nk_input { - struct nk_keyboard keyboard; - struct nk_mouse mouse; -}; - -NK_API int nk_input_has_mouse_click(const struct nk_input*, enum nk_buttons); -NK_API int nk_input_has_mouse_click_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect); -NK_API int nk_input_has_mouse_click_down_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect, int down); -NK_API int nk_input_is_mouse_click_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect); -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); -NK_API int nk_input_any_mouse_click_in_rect(const struct nk_input*, struct nk_rect); -NK_API int nk_input_is_mouse_prev_hovering_rect(const struct nk_input*, struct nk_rect); -NK_API int nk_input_is_mouse_hovering_rect(const struct nk_input*, struct nk_rect); -NK_API int nk_input_mouse_clicked(const struct nk_input*, enum nk_buttons, struct nk_rect); -NK_API int nk_input_is_mouse_down(const struct nk_input*, enum nk_buttons); -NK_API int nk_input_is_mouse_pressed(const struct nk_input*, enum nk_buttons); -NK_API int nk_input_is_mouse_released(const struct nk_input*, enum nk_buttons); -NK_API int nk_input_is_key_pressed(const struct nk_input*, enum nk_keys); -NK_API int nk_input_is_key_released(const struct nk_input*, enum nk_keys); -NK_API int nk_input_is_key_down(const struct nk_input*, enum nk_keys); - -/* =============================================================== - * - * DRAW LIST - * - * ===============================================================*/ -#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT -/* The optional vertex buffer draw list provides a 2D drawing context - with antialiasing functionality which takes basic filled or outlined shapes - or a path and outputs vertexes, elements and draw commands. - The actual draw list API is not required to be used directly while using this - library since converting the default library draw command output is done by - just calling `nk_convert` but I decided to still make this library accessible - since it can be useful. - - The draw list is based on a path buffering and polygon and polyline - rendering API which allows a lot of ways to draw 2D content to screen. - In fact it is probably more powerful than needed but allows even more crazy - things than this library provides by default. -*/ -typedef nk_ushort nk_draw_index; -enum nk_draw_list_stroke { - NK_STROKE_OPEN = nk_false, - /* build up path has no connection back to the beginning */ - NK_STROKE_CLOSED = nk_true - /* build up path has a connection back to the beginning */ -}; - -enum nk_draw_vertex_layout_attribute { - NK_VERTEX_POSITION, - NK_VERTEX_COLOR, - NK_VERTEX_TEXCOORD, - NK_VERTEX_ATTRIBUTE_COUNT -}; - -enum nk_draw_vertex_layout_format { - NK_FORMAT_SCHAR, - NK_FORMAT_SSHORT, - NK_FORMAT_SINT, - NK_FORMAT_UCHAR, - NK_FORMAT_USHORT, - NK_FORMAT_UINT, - NK_FORMAT_FLOAT, - NK_FORMAT_DOUBLE, - -NK_FORMAT_COLOR_BEGIN, - NK_FORMAT_R8G8B8 = NK_FORMAT_COLOR_BEGIN, - NK_FORMAT_R16G15B16, - NK_FORMAT_R32G32B32, - - NK_FORMAT_R8G8B8A8, - NK_FORMAT_R16G15B16A16, - NK_FORMAT_R32G32B32A32, - NK_FORMAT_R32G32B32A32_FLOAT, - NK_FORMAT_R32G32B32A32_DOUBLE, - - NK_FORMAT_RGB32, - NK_FORMAT_RGBA32, -NK_FORMAT_COLOR_END = NK_FORMAT_RGBA32, - NK_FORMAT_COUNT -}; - -#define NK_VERTEX_LAYOUT_END NK_VERTEX_ATTRIBUTE_COUNT,NK_FORMAT_COUNT,0 -struct nk_draw_vertex_layout_element { - enum nk_draw_vertex_layout_attribute attribute; - enum nk_draw_vertex_layout_format format; - nk_size offset; -}; - -struct nk_draw_command { - unsigned int elem_count; - /* number of elements in the current draw batch */ - struct nk_rect clip_rect; - /* current screen clipping rectangle */ - nk_handle texture; - /* current texture to set */ -#ifdef NK_INCLUDE_COMMAND_USERDATA - nk_handle userdata; -#endif -}; - -struct nk_draw_list { - struct nk_rect clip_rect; - struct nk_vec2 circle_vtx[12]; - struct nk_convert_config config; - - struct nk_buffer *buffer; - struct nk_buffer *vertices; - struct nk_buffer *elements; - - unsigned int element_count; - unsigned int vertex_count; - unsigned int cmd_count; - nk_size cmd_offset; - - unsigned int path_count; - unsigned int path_offset; - -#ifdef NK_INCLUDE_COMMAND_USERDATA - nk_handle userdata; -#endif -}; - -/* draw list */ -NK_API void nk_draw_list_init(struct nk_draw_list*); -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); -NK_API void nk_draw_list_clear(struct nk_draw_list*); - -/* drawing */ -#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)) -NK_API const struct nk_draw_command* nk__draw_list_begin(const struct nk_draw_list*, const struct nk_buffer*); -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*); -NK_API const struct nk_draw_command* nk__draw_list_end(const struct nk_draw_list*, const struct nk_buffer*); -NK_API void nk_draw_list_clear(struct nk_draw_list *list); - -/* path */ -NK_API void nk_draw_list_path_clear(struct nk_draw_list*); -NK_API void nk_draw_list_path_line_to(struct nk_draw_list*, struct nk_vec2 pos); -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); -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); -NK_API void nk_draw_list_path_rect_to(struct nk_draw_list*, struct nk_vec2 a, struct nk_vec2 b, float rounding); -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); -NK_API void nk_draw_list_path_fill(struct nk_draw_list*, struct nk_color); -NK_API void nk_draw_list_path_stroke(struct nk_draw_list*, struct nk_color, enum nk_draw_list_stroke closed, float thickness); - -/* stroke */ -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); -NK_API void nk_draw_list_stroke_rect(struct nk_draw_list*, struct nk_rect rect, struct nk_color, float rounding, float thickness); -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); -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); -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); -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); - -/* fill */ -NK_API void nk_draw_list_fill_rect(struct nk_draw_list*, struct nk_rect rect, struct nk_color, float rounding); -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); -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); -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); -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); - -/* misc */ -NK_API void nk_draw_list_add_image(struct nk_draw_list*, struct nk_image texture, struct nk_rect rect, struct nk_color); -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); -#ifdef NK_INCLUDE_COMMAND_USERDATA -NK_API void nk_draw_list_push_userdata(struct nk_draw_list*, nk_handle userdata); -#endif - -#endif - -/* =============================================================== - * - * GUI - * - * ===============================================================*/ -enum nk_style_item_type { - NK_STYLE_ITEM_COLOR, - NK_STYLE_ITEM_IMAGE -}; - -union nk_style_item_data { - struct nk_image image; - struct nk_color color; -}; - -struct nk_style_item { - enum nk_style_item_type type; - union nk_style_item_data data; -}; - -struct nk_style_text { - struct nk_color color; - struct nk_vec2 padding; -}; - -struct nk_style_button { - /* background */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item active; - struct nk_color border_color; - - /* text */ - struct nk_color text_background; - struct nk_color text_normal; - struct nk_color text_hover; - struct nk_color text_active; - nk_flags text_alignment; - - /* properties */ - float border; - float rounding; - struct nk_vec2 padding; - struct nk_vec2 image_padding; - struct nk_vec2 touch_padding; - - /* optional user callbacks */ - nk_handle userdata; - void(*draw_begin)(struct nk_command_buffer*, nk_handle userdata); - void(*draw_end)(struct nk_command_buffer*, nk_handle userdata); -}; - -struct nk_style_toggle { - /* background */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item active; - struct nk_color border_color; - - /* cursor */ - struct nk_style_item cursor_normal; - struct nk_style_item cursor_hover; - - /* text */ - struct nk_color text_normal; - struct nk_color text_hover; - struct nk_color text_active; - struct nk_color text_background; - nk_flags text_alignment; - - /* properties */ - struct nk_vec2 padding; - struct nk_vec2 touch_padding; - float spacing; - float border; - - /* optional user callbacks */ - nk_handle userdata; - void(*draw_begin)(struct nk_command_buffer*, nk_handle); - void(*draw_end)(struct nk_command_buffer*, nk_handle); -}; - -struct nk_style_selectable { - /* background (inactive) */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item pressed; - - /* background (active) */ - struct nk_style_item normal_active; - struct nk_style_item hover_active; - struct nk_style_item pressed_active; - - /* text color (inactive) */ - struct nk_color text_normal; - struct nk_color text_hover; - struct nk_color text_pressed; - - /* text color (active) */ - struct nk_color text_normal_active; - struct nk_color text_hover_active; - struct nk_color text_pressed_active; - struct nk_color text_background; - nk_flags text_alignment; - - /* properties */ - float rounding; - struct nk_vec2 padding; - struct nk_vec2 touch_padding; - struct nk_vec2 image_padding; - - /* optional user callbacks */ - nk_handle userdata; - void(*draw_begin)(struct nk_command_buffer*, nk_handle); - void(*draw_end)(struct nk_command_buffer*, nk_handle); -}; - -struct nk_style_slider { - /* background */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item active; - struct nk_color border_color; - - /* background bar */ - struct nk_color bar_normal; - struct nk_color bar_hover; - struct nk_color bar_active; - struct nk_color bar_filled; - - /* cursor */ - struct nk_style_item cursor_normal; - struct nk_style_item cursor_hover; - struct nk_style_item cursor_active; - - /* properties */ - float border; - float rounding; - float bar_height; - struct nk_vec2 padding; - struct nk_vec2 spacing; - struct nk_vec2 cursor_size; - - /* optional buttons */ - int show_buttons; - struct nk_style_button inc_button; - struct nk_style_button dec_button; - enum nk_symbol_type inc_symbol; - enum nk_symbol_type dec_symbol; - - /* optional user callbacks */ - nk_handle userdata; - void(*draw_begin)(struct nk_command_buffer*, nk_handle); - void(*draw_end)(struct nk_command_buffer*, nk_handle); -}; - -struct nk_style_progress { - /* background */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item active; - struct nk_color border_color; - - /* cursor */ - struct nk_style_item cursor_normal; - struct nk_style_item cursor_hover; - struct nk_style_item cursor_active; - struct nk_color cursor_border_color; - - /* properties */ - float rounding; - float border; - float cursor_border; - float cursor_rounding; - struct nk_vec2 padding; - - /* optional user callbacks */ - nk_handle userdata; - void(*draw_begin)(struct nk_command_buffer*, nk_handle); - void(*draw_end)(struct nk_command_buffer*, nk_handle); -}; - -struct nk_style_scrollbar { - /* background */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item active; - struct nk_color border_color; - - /* cursor */ - struct nk_style_item cursor_normal; - struct nk_style_item cursor_hover; - struct nk_style_item cursor_active; - struct nk_color cursor_border_color; - - /* properties */ - float border; - float rounding; - float border_cursor; - float rounding_cursor; - struct nk_vec2 padding; - - /* optional buttons */ - int show_buttons; - struct nk_style_button inc_button; - struct nk_style_button dec_button; - enum nk_symbol_type inc_symbol; - enum nk_symbol_type dec_symbol; - - /* optional user callbacks */ - nk_handle userdata; - void(*draw_begin)(struct nk_command_buffer*, nk_handle); - void(*draw_end)(struct nk_command_buffer*, nk_handle); -}; - -struct nk_style_edit { - /* background */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item active; - struct nk_color border_color; - struct nk_style_scrollbar scrollbar; - - /* cursor */ - struct nk_color cursor_normal; - struct nk_color cursor_hover; - struct nk_color cursor_text_normal; - struct nk_color cursor_text_hover; - - /* text (unselected) */ - struct nk_color text_normal; - struct nk_color text_hover; - struct nk_color text_active; - - /* text (selected) */ - struct nk_color selected_normal; - struct nk_color selected_hover; - struct nk_color selected_text_normal; - struct nk_color selected_text_hover; - - /* properties */ - float border; - float rounding; - float cursor_size; - struct nk_vec2 scrollbar_size; - struct nk_vec2 padding; - float row_padding; -}; - -struct nk_style_property { - /* background */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item active; - struct nk_color border_color; - - /* text */ - struct nk_color label_normal; - struct nk_color label_hover; - struct nk_color label_active; - - /* symbols */ - enum nk_symbol_type sym_left; - enum nk_symbol_type sym_right; - - /* properties */ - float border; - float rounding; - struct nk_vec2 padding; - - struct nk_style_edit edit; - struct nk_style_button inc_button; - struct nk_style_button dec_button; - - /* optional user callbacks */ - nk_handle userdata; - void(*draw_begin)(struct nk_command_buffer*, nk_handle); - void(*draw_end)(struct nk_command_buffer*, nk_handle); -}; - -struct nk_style_chart { - /* colors */ - struct nk_style_item background; - struct nk_color border_color; - struct nk_color selected_color; - struct nk_color color; - - /* properties */ - float border; - float rounding; - struct nk_vec2 padding; -}; - -struct nk_style_combo { - /* background */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item active; - struct nk_color border_color; - - /* label */ - struct nk_color label_normal; - struct nk_color label_hover; - struct nk_color label_active; - - /* symbol */ - struct nk_color symbol_normal; - struct nk_color symbol_hover; - struct nk_color symbol_active; - - /* button */ - struct nk_style_button button; - enum nk_symbol_type sym_normal; - enum nk_symbol_type sym_hover; - enum nk_symbol_type sym_active; - - /* properties */ - float border; - float rounding; - struct nk_vec2 content_padding; - struct nk_vec2 button_padding; - struct nk_vec2 spacing; -}; - -struct nk_style_tab { - /* background */ - struct nk_style_item background; - struct nk_color border_color; - struct nk_color text; - - /* button */ - struct nk_style_button tab_maximize_button; - struct nk_style_button tab_minimize_button; - struct nk_style_button node_maximize_button; - struct nk_style_button node_minimize_button; - enum nk_symbol_type sym_minimize; - enum nk_symbol_type sym_maximize; - - /* properties */ - float border; - float rounding; - float indent; - struct nk_vec2 padding; - struct nk_vec2 spacing; -}; - -enum nk_style_header_align { - NK_HEADER_LEFT, - NK_HEADER_RIGHT -}; -struct nk_style_window_header { - /* background */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item active; - - /* button */ - struct nk_style_button close_button; - struct nk_style_button minimize_button; - enum nk_symbol_type close_symbol; - enum nk_symbol_type minimize_symbol; - enum nk_symbol_type maximize_symbol; - - /* title */ - struct nk_color label_normal; - struct nk_color label_hover; - struct nk_color label_active; - - /* properties */ - enum nk_style_header_align align; - struct nk_vec2 padding; - struct nk_vec2 label_padding; - struct nk_vec2 spacing; -}; - -struct nk_style_window { - struct nk_style_window_header header; - struct nk_style_item fixed_background; - struct nk_color background; - - struct nk_color border_color; - struct nk_color popup_border_color; - struct nk_color combo_border_color; - struct nk_color contextual_border_color; - struct nk_color menu_border_color; - struct nk_color group_border_color; - struct nk_color tooltip_border_color; - struct nk_style_item scaler; - - float border; - float combo_border; - float contextual_border; - float menu_border; - float group_border; - float tooltip_border; - float popup_border; - - float rounding; - struct nk_vec2 spacing; - struct nk_vec2 scrollbar_size; - struct nk_vec2 min_size; - - struct nk_vec2 padding; - struct nk_vec2 group_padding; - struct nk_vec2 popup_padding; - struct nk_vec2 combo_padding; - struct nk_vec2 contextual_padding; - struct nk_vec2 menu_padding; - struct nk_vec2 tooltip_padding; -}; - -struct nk_style { - const struct nk_user_font *font; - const struct nk_cursor *cursors[NK_CURSOR_COUNT]; - const struct nk_cursor *cursor_active; - struct nk_cursor *cursor_last; - int cursor_visible; - - struct nk_style_text text; - struct nk_style_button button; - struct nk_style_button contextual_button; - struct nk_style_button menu_button; - struct nk_style_toggle option; - struct nk_style_toggle checkbox; - struct nk_style_selectable selectable; - struct nk_style_slider slider; - struct nk_style_progress progress; - struct nk_style_property property; - struct nk_style_edit edit; - struct nk_style_chart chart; - struct nk_style_scrollbar scrollh; - struct nk_style_scrollbar scrollv; - struct nk_style_tab tab; - struct nk_style_combo combo; - struct nk_style_window window; -}; - -NK_API struct nk_style_item nk_style_item_image(struct nk_image img); -NK_API struct nk_style_item nk_style_item_color(struct nk_color); -NK_API struct nk_style_item nk_style_item_hide(void); - -/*============================================================== - * PANEL - * =============================================================*/ -#ifndef NK_CHART_MAX_SLOT -#define NK_CHART_MAX_SLOT 4 -#endif - -enum nk_panel_type { - NK_PANEL_WINDOW = NK_FLAG(0), - NK_PANEL_GROUP = NK_FLAG(1), - NK_PANEL_POPUP = NK_FLAG(2), - NK_PANEL_CONTEXTUAL = NK_FLAG(4), - NK_PANEL_COMBO = NK_FLAG(5), - NK_PANEL_MENU = NK_FLAG(6), - NK_PANEL_TOOLTIP = NK_FLAG(7) -}; -enum nk_panel_set { - NK_PANEL_SET_NONBLOCK = NK_PANEL_CONTEXTUAL|NK_PANEL_COMBO|NK_PANEL_MENU|NK_PANEL_TOOLTIP, - NK_PANEL_SET_POPUP = NK_PANEL_SET_NONBLOCK|NK_PANEL_POPUP, - NK_PANEL_SET_SUB = NK_PANEL_SET_POPUP|NK_PANEL_GROUP -}; - -struct nk_chart_slot { - enum nk_chart_type type; - struct nk_color color; - struct nk_color highlight; - float min, max, range; - int count; - struct nk_vec2 last; - int index; -}; - -struct nk_chart { - int slot; - float x, y, w, h; - struct nk_chart_slot slots[NK_CHART_MAX_SLOT]; -}; - -struct nk_row_layout { - int type; - int index; - float height; - int columns; - const float *ratio; - float item_width; - float item_height; - float item_offset; - float filled; - struct nk_rect item; - int tree_depth; -}; - -struct nk_popup_buffer { - nk_size begin; - nk_size parent; - nk_size last; - nk_size end; - int active; -}; - -struct nk_menu_state { - float x, y, w, h; - struct nk_scroll offset; -}; - -struct nk_panel { - enum nk_panel_type type; - nk_flags flags; - struct nk_rect bounds; - nk_uint *offset_x; - nk_uint *offset_y; - float at_x, at_y, max_x; - float footer_height; - float header_height; - float border; - unsigned int has_scrolling; - struct nk_rect clip; - struct nk_menu_state menu; - struct nk_row_layout row; - struct nk_chart chart; - struct nk_popup_buffer popup_buffer; - struct nk_command_buffer *buffer; - struct nk_panel *parent; -}; - -/*============================================================== - * WINDOW - * =============================================================*/ -#ifndef NK_WINDOW_MAX_NAME -#define NK_WINDOW_MAX_NAME 64 -#endif - -struct nk_table; -enum nk_window_flags { - NK_WINDOW_PRIVATE = NK_FLAG(10), - NK_WINDOW_DYNAMIC = NK_WINDOW_PRIVATE, - /* special window type growing up in height while being filled to a certain maximum height */ - NK_WINDOW_ROM = NK_FLAG(11), - /* sets the window into a read only mode and does not allow input changes */ - NK_WINDOW_HIDDEN = NK_FLAG(12), - /* Hides the window and stops any window interaction and drawing */ - NK_WINDOW_CLOSED = NK_FLAG(13), - /* Directly closes and frees the window at the end of the frame */ - NK_WINDOW_MINIMIZED = NK_FLAG(14), - /* marks the window as minimized */ - NK_WINDOW_REMOVE_ROM = NK_FLAG(15) - /* Removes the read only mode at the end of the window */ -}; - -struct nk_popup_state { - struct nk_window *win; - enum nk_panel_type type; - nk_hash name; - int active; - unsigned combo_count; - unsigned con_count, con_old; - unsigned active_con; - struct nk_rect header; -}; - -struct nk_edit_state { - nk_hash name; - unsigned int seq; - unsigned int old; - int active, prev; - int cursor; - int sel_start; - int sel_end; - struct nk_scroll scrollbar; - unsigned char mode; - unsigned char single_line; -}; - -struct nk_property_state { - int active, prev; - char buffer[NK_MAX_NUMBER_BUFFER]; - int length; - int cursor; - nk_hash name; - unsigned int seq; - unsigned int old; - int state; -}; - -struct nk_window { - unsigned int seq; - nk_hash name; - char name_string[NK_WINDOW_MAX_NAME]; - nk_flags flags; - - struct nk_rect bounds; - struct nk_scroll scrollbar; - struct nk_command_buffer buffer; - struct nk_panel *layout; - float scrollbar_hiding_timer; - - /* persistent widget state */ - struct nk_property_state property; - struct nk_popup_state popup; - struct nk_edit_state edit; - unsigned int scrolled; - - struct nk_table *tables; - unsigned short table_count; - unsigned short table_size; - - /* window list hooks */ - struct nk_window *next; - struct nk_window *prev; - struct nk_window *parent; -}; - -/*============================================================== - * STACK - * =============================================================*/ -/* The style modifier stack can be used to temporarily change a - * property inside `nk_style`. For example if you want a special - * red button you can temporarily push the old button color onto a stack - * draw the button with a red color and then you just pop the old color - * back from the stack: - * - * nk_style_push_style_item(ctx, &ctx->style.button.normal, nk_style_item_color(nk_rgb(255,0,0))); - * nk_style_push_style_item(ctx, &ctx->style.button.hover, nk_style_item_color(nk_rgb(255,0,0))); - * nk_style_push_style_item(ctx, &ctx->style.button.active, nk_style_item_color(nk_rgb(255,0,0))); - * nk_style_push_vec2(ctx, &cx->style.button.padding, nk_vec2(2,2)); - * - * nk_button(...); - * - * nk_style_pop_style_item(ctx); - * nk_style_pop_style_item(ctx); - * nk_style_pop_style_item(ctx); - * nk_style_pop_vec2(ctx); - * - * Nuklear has a stack for style_items, float properties, vector properties, - * flags, colors, fonts and for button_behavior. Each has it's own fixed size stack - * which can be changed at compile time. - */ -#ifndef NK_BUTTON_BEHAVIOR_STACK_SIZE -#define NK_BUTTON_BEHAVIOR_STACK_SIZE 8 -#endif - -#ifndef NK_FONT_STACK_SIZE -#define NK_FONT_STACK_SIZE 8 -#endif - -#ifndef NK_STYLE_ITEM_STACK_SIZE -#define NK_STYLE_ITEM_STACK_SIZE 16 -#endif - -#ifndef NK_FLOAT_STACK_SIZE -#define NK_FLOAT_STACK_SIZE 32 -#endif - -#ifndef NK_VECTOR_STACK_SIZE -#define NK_VECTOR_STACK_SIZE 16 -#endif - -#ifndef NK_FLAGS_STACK_SIZE -#define NK_FLAGS_STACK_SIZE 32 -#endif - -#ifndef NK_COLOR_STACK_SIZE -#define NK_COLOR_STACK_SIZE 32 -#endif - -#define NK_CONFIGURATION_STACK_TYPE(prefix, name, type)\ - struct nk_config_stack_##name##_element {\ - prefix##_##type *address;\ - prefix##_##type old_value;\ - } -#define NK_CONFIG_STACK(type,size)\ - struct nk_config_stack_##type {\ - int head;\ - struct nk_config_stack_##type##_element elements[size];\ - } - -#define nk_float float -NK_CONFIGURATION_STACK_TYPE(struct nk, style_item, style_item); -NK_CONFIGURATION_STACK_TYPE(nk ,float, float); -NK_CONFIGURATION_STACK_TYPE(struct nk, vec2, vec2); -NK_CONFIGURATION_STACK_TYPE(nk ,flags, flags); -NK_CONFIGURATION_STACK_TYPE(struct nk, color, color); -NK_CONFIGURATION_STACK_TYPE(const struct nk, user_font, user_font*); -NK_CONFIGURATION_STACK_TYPE(enum nk, button_behavior, button_behavior); - -NK_CONFIG_STACK(style_item, NK_STYLE_ITEM_STACK_SIZE); -NK_CONFIG_STACK(float, NK_FLOAT_STACK_SIZE); -NK_CONFIG_STACK(vec2, NK_VECTOR_STACK_SIZE); -NK_CONFIG_STACK(flags, NK_FLAGS_STACK_SIZE); -NK_CONFIG_STACK(color, NK_COLOR_STACK_SIZE); -NK_CONFIG_STACK(user_font, NK_FONT_STACK_SIZE); -NK_CONFIG_STACK(button_behavior, NK_BUTTON_BEHAVIOR_STACK_SIZE); - -struct nk_configuration_stacks { - struct nk_config_stack_style_item style_items; - struct nk_config_stack_float floats; - struct nk_config_stack_vec2 vectors; - struct nk_config_stack_flags flags; - struct nk_config_stack_color colors; - struct nk_config_stack_user_font fonts; - struct nk_config_stack_button_behavior button_behaviors; -}; - -/*============================================================== - * CONTEXT - * =============================================================*/ -#define NK_VALUE_PAGE_CAPACITY \ - ((NK_MAX(sizeof(struct nk_window),sizeof(struct nk_panel)) / sizeof(nk_uint)) / 2) - -struct nk_table { - unsigned int seq; - nk_hash keys[NK_VALUE_PAGE_CAPACITY]; - nk_uint values[NK_VALUE_PAGE_CAPACITY]; - struct nk_table *next, *prev; -}; - -union nk_page_data { - struct nk_table tbl; - struct nk_panel pan; - struct nk_window win; -}; - -struct nk_page_element { - union nk_page_data data; - struct nk_page_element *next; - struct nk_page_element *prev; -}; - -struct nk_page { - unsigned int size; - struct nk_page *next; - struct nk_page_element win[1]; -}; - -struct nk_pool { - struct nk_allocator alloc; - enum nk_allocation_type type; - unsigned int page_count; - struct nk_page *pages; - struct nk_page_element *freelist; - unsigned capacity; - nk_size size; - nk_size cap; -}; - -struct nk_context { -/* public: can be accessed freely */ - struct nk_input input; - struct nk_style style; - struct nk_buffer memory; - struct nk_clipboard clip; - nk_flags last_widget_state; - enum nk_button_behavior button_behavior; - struct nk_configuration_stacks stacks; - float delta_time_seconds; - -/* private: - should only be accessed if you - know what you are doing */ -#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT - struct nk_draw_list draw_list; -#endif -#ifdef NK_INCLUDE_COMMAND_USERDATA - nk_handle userdata; -#endif - /* text editor objects are quite big because of an internal - * undo/redo stack. Therefore it does not make sense to have one for - * each window for temporary use cases, so I only provide *one* instance - * for all windows. This works because the content is cleared anyway */ - struct nk_text_edit text_edit; - /* draw buffer used for overlay drawing operation like cursor */ - struct nk_command_buffer overlay; - - /* windows */ - int build; - int use_pool; - struct nk_pool pool; - struct nk_window *begin; - struct nk_window *end; - struct nk_window *active; - struct nk_window *current; - struct nk_page_element *freelist; - unsigned int count; - unsigned int seq; -}; - -/* ============================================================== - * MATH - * =============================================================== */ -#define NK_PI 3.141592654f -#define NK_UTF_INVALID 0xFFFD -#define NK_MAX_FLOAT_PRECISION 2 - -#define NK_UNUSED(x) ((void)(x)) -#define NK_SATURATE(x) (NK_MAX(0, NK_MIN(1.0f, x))) -#define NK_LEN(a) (sizeof(a)/sizeof(a)[0]) -#define NK_ABS(a) (((a) < 0) ? -(a) : (a)) -#define NK_BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b)) -#define NK_INBOX(px, py, x, y, w, h)\ - (NK_BETWEEN(px,x,x+w) && NK_BETWEEN(py,y,y+h)) -#define NK_INTERSECT(x0, y0, w0, h0, x1, y1, w1, h1) \ - (!(((x1 > (x0 + w0)) || ((x1 + w1) < x0) || (y1 > (y0 + h0)) || (y1 + h1) < y0))) -#define NK_CONTAINS(x, y, w, h, bx, by, bw, bh)\ - (NK_INBOX(x,y, bx, by, bw, bh) && NK_INBOX(x+w,y+h, bx, by, bw, bh)) - -#define nk_vec2_sub(a, b) nk_vec2((a).x - (b).x, (a).y - (b).y) -#define nk_vec2_add(a, b) nk_vec2((a).x + (b).x, (a).y + (b).y) -#define nk_vec2_len_sqr(a) ((a).x*(a).x+(a).y*(a).y) -#define nk_vec2_muls(a, t) nk_vec2((a).x * (t), (a).y * (t)) - -#define nk_ptr_add(t, p, i) ((t*)((void*)((nk_byte*)(p) + (i)))) -#define nk_ptr_add_const(t, p, i) ((const t*)((const void*)((const nk_byte*)(p) + (i)))) -#define nk_zero_struct(s) nk_zero(&s, sizeof(s)) - -/* ============================================================== - * ALIGNMENT - * =============================================================== */ -/* Pointer to Integer type conversion for pointer alignment */ -#if defined(__PTRDIFF_TYPE__) /* This case should work for GCC*/ -# define NK_UINT_TO_PTR(x) ((void*)(__PTRDIFF_TYPE__)(x)) -# define NK_PTR_TO_UINT(x) ((nk_size)(__PTRDIFF_TYPE__)(x)) -#elif !defined(__GNUC__) /* works for compilers other than LLVM */ -# define NK_UINT_TO_PTR(x) ((void*)&((char*)0)[x]) -# define NK_PTR_TO_UINT(x) ((nk_size)(((char*)x)-(char*)0)) -#elif defined(NK_USE_FIXED_TYPES) /* used if we have */ -# define NK_UINT_TO_PTR(x) ((void*)(uintptr_t)(x)) -# define NK_PTR_TO_UINT(x) ((uintptr_t)(x)) -#else /* generates warning but works */ -# define NK_UINT_TO_PTR(x) ((void*)(x)) -# define NK_PTR_TO_UINT(x) ((nk_size)(x)) -#endif - -#define NK_ALIGN_PTR(x, mask)\ - (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte*)(x) + (mask-1)) & ~(mask-1)))) -#define NK_ALIGN_PTR_BACK(x, mask)\ - (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte*)(x)) & ~(mask-1)))) - -#define NK_OFFSETOF(st,m) ((nk_ptr)&(((st*)0)->m)) -#define NK_CONTAINER_OF(ptr,type,member)\ - (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member))) - -#ifdef __cplusplus -} -#endif - -#ifdef __cplusplus -template struct nk_alignof; -template struct nk_helper{enum {value = size_diff};}; -template struct nk_helper{enum {value = nk_alignof::value};}; -template struct nk_alignof{struct Big {T x; char c;}; enum { - diff = sizeof(Big) - sizeof(T), value = nk_helper::value};}; -#define NK_ALIGNOF(t) (nk_alignof::value); -#elif defined(_MSC_VER) -#define NK_ALIGNOF(t) (__alignof(t)) -#else -#define NK_ALIGNOF(t) ((char*)(&((struct {char c; t _h;}*)0)->_h) - (char*)0) -#endif - -#endif /* NK_H_ */ -/* - * ============================================================== - * - * IMPLEMENTATION - * - * =============================================================== - */ -#ifdef NK_IMPLEMENTATION - -#ifndef NK_POOL_DEFAULT_CAPACITY -#define NK_POOL_DEFAULT_CAPACITY 16 -#endif - -#ifndef NK_DEFAULT_COMMAND_BUFFER_SIZE -#define NK_DEFAULT_COMMAND_BUFFER_SIZE (4*1024) -#endif - -#ifndef NK_BUFFER_DEFAULT_INITIAL_SIZE -#define NK_BUFFER_DEFAULT_INITIAL_SIZE (4*1024) -#endif - -/* standard library headers */ -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -#include /* malloc, free */ -#endif -#ifdef NK_INCLUDE_STANDARD_IO -#include /* fopen, fclose,... */ -#endif -#ifdef NK_INCLUDE_STANDARD_VARARGS -#include /* valist, va_start, va_end, ... */ -#endif -#ifndef NK_ASSERT -#include -#define NK_ASSERT(expr) assert(expr) -#endif - -#ifndef NK_MEMSET -#define NK_MEMSET nk_memset -#endif -#ifndef NK_MEMCPY -#define NK_MEMCPY nk_memcopy -#endif -#ifndef NK_SQRT -#define NK_SQRT nk_sqrt -#endif -#ifndef NK_SIN -#define NK_SIN nk_sin -#endif -#ifndef NK_COS -#define NK_COS nk_cos -#endif -#ifndef NK_STRTOD -#define NK_STRTOD nk_strtod -#endif -#ifndef NK_DTOA -#define NK_DTOA nk_dtoa -#endif - -#define NK_DEFAULT (-1) - -#ifndef NK_VSNPRINTF -/* If your compiler does support `vsnprintf` I would highly recommend - * defining this to vsnprintf instead since `vsprintf` is basically - * unbelievable unsafe and should *NEVER* be used. But I have to support - * it since C89 only provides this unsafe version. */ - #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) ||\ - (defined(__cplusplus) && (__cplusplus >= 201103L)) || \ - (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) ||\ - (defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)) ||\ - defined(_ISOC99_SOURCE) || defined(_BSD_SOURCE) - #define NK_VSNPRINTF(s,n,f,a) vsnprintf(s,n,f,a) - #else - #define NK_VSNPRINTF(s,n,f,a) vsprintf(s,f,a) - #endif -#endif - -#define NK_SCHAR_MIN (-127) -#define NK_SCHAR_MAX 127 -#define NK_UCHAR_MIN 0 -#define NK_UCHAR_MAX 256 -#define NK_SSHORT_MIN (-32767) -#define NK_SSHORT_MAX 32767 -#define NK_USHORT_MIN 0 -#define NK_USHORT_MAX 65535 -#define NK_SINT_MIN (-2147483647) -#define NK_SINT_MAX 2147483647 -#define NK_UINT_MIN 0 -#define NK_UINT_MAX 4294967295 - -/* Make sure correct type size: - * This will fire with a negative subscript error if the type sizes - * are set incorrectly by the compiler, and compile out if not */ -NK_STATIC_ASSERT(sizeof(nk_size) >= sizeof(void*)); -NK_STATIC_ASSERT(sizeof(nk_ptr) == sizeof(void*)); -NK_STATIC_ASSERT(sizeof(nk_flags) >= 4); -NK_STATIC_ASSERT(sizeof(nk_rune) >= 4); -NK_STATIC_ASSERT(sizeof(nk_ushort) == 2); -NK_STATIC_ASSERT(sizeof(nk_short) == 2); -NK_STATIC_ASSERT(sizeof(nk_uint) == 4); -NK_STATIC_ASSERT(sizeof(nk_int) == 4); -NK_STATIC_ASSERT(sizeof(nk_byte) == 1); - -NK_GLOBAL const struct nk_rect nk_null_rect = {-8192.0f, -8192.0f, 16384, 16384}; -#define NK_FLOAT_PRECISION 0.00000000000001 - -NK_GLOBAL const struct nk_color nk_red = {255,0,0,255}; -NK_GLOBAL const struct nk_color nk_green = {0,255,0,255}; -NK_GLOBAL const struct nk_color nk_blue = {0,0,255,255}; -NK_GLOBAL const struct nk_color nk_white = {255,255,255,255}; -NK_GLOBAL const struct nk_color nk_black = {0,0,0,255}; -NK_GLOBAL const struct nk_color nk_yellow = {255,255,0,255}; - -/* - * ============================================================== - * - * MATH - * - * =============================================================== - */ -/* Since nuklear is supposed to work on all systems providing floating point - math without any dependencies I also had to implement my own math functions - for sqrt, sin and cos. Since the actual highly accurate implementations for - the standard library functions are quite complex and I do not need high - precision for my use cases I use approximations. - - Sqrt - ---- - For square root nuklear uses the famous fast inverse square root: - https://en.wikipedia.org/wiki/Fast_inverse_square_root with - slightly tweaked magic constant. While on todays hardware it is - probably not faster it is still fast and accurate enough for - nuklear's use cases. IMPORTANT: this requires float format IEEE 754 - - Sine/Cosine - ----------- - All constants inside both function are generated Remez's minimax - approximations for value range 0...2*PI. The reason why I decided to - approximate exactly that range is that nuklear only needs sine and - cosine to generate circles which only requires that exact range. - In addition I used Remez instead of Taylor for additional precision: - www.lolengine.net/blog/2011/12/21/better-function-approximatations. - - The tool I used to generate constants for both sine and cosine - (it can actually approximate a lot more functions) can be - found here: www.lolengine.net/wiki/oss/lolremez -*/ -NK_INTERN float -nk_inv_sqrt(float number) -{ - float x2; - const float threehalfs = 1.5f; - union {nk_uint i; float f;} conv = {0}; - conv.f = number; - x2 = number * 0.5f; - conv.i = 0x5f375A84 - (conv.i >> 1); - conv.f = conv.f * (threehalfs - (x2 * conv.f * conv.f)); - return conv.f; -} - -NK_INTERN float -nk_sqrt(float x) -{ - return x * nk_inv_sqrt(x); -} - -NK_INTERN float -nk_sin(float x) -{ - NK_STORAGE const float a0 = +1.91059300966915117e-31f; - NK_STORAGE const float a1 = +1.00086760103908896f; - NK_STORAGE const float a2 = -1.21276126894734565e-2f; - NK_STORAGE const float a3 = -1.38078780785773762e-1f; - NK_STORAGE const float a4 = -2.67353392911981221e-2f; - NK_STORAGE const float a5 = +2.08026600266304389e-2f; - NK_STORAGE const float a6 = -3.03996055049204407e-3f; - NK_STORAGE const float a7 = +1.38235642404333740e-4f; - return a0 + x*(a1 + x*(a2 + x*(a3 + x*(a4 + x*(a5 + x*(a6 + x*a7)))))); -} - -NK_INTERN float -nk_cos(float x) -{ - NK_STORAGE const float a0 = +1.00238601909309722f; - NK_STORAGE const float a1 = -3.81919947353040024e-2f; - NK_STORAGE const float a2 = -3.94382342128062756e-1f; - NK_STORAGE const float a3 = -1.18134036025221444e-1f; - NK_STORAGE const float a4 = +1.07123798512170878e-1f; - NK_STORAGE const float a5 = -1.86637164165180873e-2f; - NK_STORAGE const float a6 = +9.90140908664079833e-4f; - NK_STORAGE const float a7 = -5.23022132118824778e-14f; - return a0 + x*(a1 + x*(a2 + x*(a3 + x*(a4 + x*(a5 + x*(a6 + x*a7)))))); -} - -NK_INTERN nk_uint -nk_round_up_pow2(nk_uint v) -{ - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v++; - return v; -} - -NK_API struct nk_rect -nk_get_null_rect(void) -{ - return nk_null_rect; -} - -NK_API struct nk_rect -nk_rect(float x, float y, float w, float h) -{ - struct nk_rect r; - r.x = x; r.y = y; - r.w = w; r.h = h; - return r; -} - -NK_API struct nk_rect -nk_recti(int x, int y, int w, int h) -{ - struct nk_rect r; - r.x = (float)x; - r.y = (float)y; - r.w = (float)w; - r.h = (float)h; - return r; -} - -NK_API struct nk_rect -nk_recta(struct nk_vec2 pos, struct nk_vec2 size) -{ - return nk_rect(pos.x, pos.y, size.x, size.y); -} - -NK_API struct nk_rect -nk_rectv(const float *r) -{ - return nk_rect(r[0], r[1], r[2], r[3]); -} - -NK_API struct nk_rect -nk_rectiv(const int *r) -{ - return nk_recti(r[0], r[1], r[2], r[3]); -} - -NK_API struct nk_vec2 -nk_rect_pos(struct nk_rect r) -{ - struct nk_vec2 ret; - ret.x = r.x; ret.y = r.y; - return ret; -} - -NK_API struct nk_vec2 -nk_rect_size(struct nk_rect r) -{ - struct nk_vec2 ret; - ret.x = r.w; ret.y = r.h; - return ret; -} - -NK_INTERN struct nk_rect -nk_shrink_rect(struct nk_rect r, float amount) -{ - struct nk_rect res; - r.w = NK_MAX(r.w, 2 * amount); - r.h = NK_MAX(r.h, 2 * amount); - res.x = r.x + amount; - res.y = r.y + amount; - res.w = r.w - 2 * amount; - res.h = r.h - 2 * amount; - return res; -} - -NK_INTERN struct nk_rect -nk_pad_rect(struct nk_rect r, struct nk_vec2 pad) -{ - r.w = NK_MAX(r.w, 2 * pad.x); - r.h = NK_MAX(r.h, 2 * pad.y); - r.x += pad.x; r.y += pad.y; - r.w -= 2 * pad.x; - r.h -= 2 * pad.y; - return r; -} - -NK_API struct nk_vec2 -nk_vec2(float x, float y) -{ - struct nk_vec2 ret; - ret.x = x; ret.y = y; - return ret; -} - -NK_API struct nk_vec2 -nk_vec2i(int x, int y) -{ - struct nk_vec2 ret; - ret.x = (float)x; - ret.y = (float)y; - return ret; -} - -NK_API struct nk_vec2 -nk_vec2v(const float *v) -{ - return nk_vec2(v[0], v[1]); -} - -NK_API struct nk_vec2 -nk_vec2iv(const int *v) -{ - return nk_vec2i(v[0], v[1]); -} - -/* - * ============================================================== - * - * UTIL - * - * =============================================================== - */ -NK_INTERN int nk_str_match_here(const char *regexp, const char *text); -NK_INTERN int nk_str_match_star(int c, const char *regexp, const char *text); -NK_INTERN int nk_is_lower(int c) {return (c >= 'a' && c <= 'z') || (c >= 0xE0 && c <= 0xFF);} -NK_INTERN int nk_is_upper(int c){return (c >= 'A' && c <= 'Z') || (c >= 0xC0 && c <= 0xDF);} -NK_INTERN int nk_to_upper(int c) {return (c >= 'a' && c <= 'z') ? (c - ('a' - 'A')) : c;} -NK_INTERN int nk_to_lower(int c) {return (c >= 'A' && c <= 'Z') ? (c - ('a' + 'A')) : c;} - -NK_INTERN void* -nk_memcopy(void *dst0, const void *src0, nk_size length) -{ - nk_ptr t; - char *dst = (char*)dst0; - const char *src = (const char*)src0; - if (length == 0 || dst == src) - goto done; - - #define nk_word int - #define nk_wsize sizeof(nk_word) - #define nk_wmask (nk_wsize-1) - #define NK_TLOOP(s) if (t) NK_TLOOP1(s) - #define NK_TLOOP1(s) do { s; } while (--t) - - if (dst < src) { - t = (nk_ptr)src; /* only need low bits */ - if ((t | (nk_ptr)dst) & nk_wmask) { - if ((t ^ (nk_ptr)dst) & nk_wmask || length < nk_wsize) - t = length; - else - t = nk_wsize - (t & nk_wmask); - length -= t; - NK_TLOOP1(*dst++ = *src++); - } - t = length / nk_wsize; - NK_TLOOP(*(nk_word*)(void*)dst = *(const nk_word*)(const void*)src; - src += nk_wsize; dst += nk_wsize); - t = length & nk_wmask; - NK_TLOOP(*dst++ = *src++); - } else { - src += length; - dst += length; - t = (nk_ptr)src; - if ((t | (nk_ptr)dst) & nk_wmask) { - if ((t ^ (nk_ptr)dst) & nk_wmask || length <= nk_wsize) - t = length; - else - t &= nk_wmask; - length -= t; - NK_TLOOP1(*--dst = *--src); - } - t = length / nk_wsize; - NK_TLOOP(src -= nk_wsize; dst -= nk_wsize; - *(nk_word*)(void*)dst = *(const nk_word*)(const void*)src); - t = length & nk_wmask; - NK_TLOOP(*--dst = *--src); - } - #undef nk_word - #undef nk_wsize - #undef nk_wmask - #undef NK_TLOOP - #undef NK_TLOOP1 -done: - return (dst0); -} - -NK_INTERN void -nk_memset(void *ptr, int c0, nk_size size) -{ - #define nk_word unsigned - #define nk_wsize sizeof(nk_word) - #define nk_wmask (nk_wsize - 1) - nk_byte *dst = (nk_byte*)ptr; - unsigned c = 0; - nk_size t = 0; - - if ((c = (nk_byte)c0) != 0) { - c = (c << 8) | c; /* at least 16-bits */ - if (sizeof(unsigned int) > 2) - c = (c << 16) | c; /* at least 32-bits*/ - } - - /* too small of a word count */ - dst = (nk_byte*)ptr; - if (size < 3 * nk_wsize) { - while (size--) *dst++ = (nk_byte)c0; - return; - } - - /* align destination */ - if ((t = NK_PTR_TO_UINT(dst) & nk_wmask) != 0) { - t = nk_wsize -t; - size -= t; - do { - *dst++ = (nk_byte)c0; - } while (--t != 0); - } - - /* fill word */ - t = size / nk_wsize; - do { - *(nk_word*)((void*)dst) = c; - dst += nk_wsize; - } while (--t != 0); - - /* fill trailing bytes */ - t = (size & nk_wmask); - if (t != 0) { - do { - *dst++ = (nk_byte)c0; - } while (--t != 0); - } - - #undef nk_word - #undef nk_wsize - #undef nk_wmask -} - -NK_INTERN void -nk_zero(void *ptr, nk_size size) -{ - NK_ASSERT(ptr); - NK_MEMSET(ptr, 0, size); -} - -NK_API int -nk_strlen(const char *str) -{ - int siz = 0; - NK_ASSERT(str); - while (str && *str++ != '\0') siz++; - return siz; -} - -NK_API int -nk_strtoi(const char *str, char **endptr) -{ - int neg = 1; - const char *p = str; - int value = 0; - - NK_ASSERT(str); - if (!str) return 0; - - /* skip whitespace */ - while (*p == ' ') p++; - if (*p == '-') { - neg = -1; - p++; - } - while (*p && *p >= '0' && *p <= '9') { - value = value * 10 + (int) (*p - '0'); - p++; - } - if (endptr) - *endptr = (char*)p; - return neg*value; -} - -NK_API double -nk_strtod(const char *str, char **endptr) -{ - double m; - double neg = 1.0; - const char *p = str; - double value = 0; - double number = 0; - - NK_ASSERT(str); - if (!str) return 0; - - /* skip whitespace */ - while (*p == ' ') p++; - if (*p == '-') { - neg = -1.0; - p++; - } - - while (*p && *p != '.' && *p != 'e') { - value = value * 10.0 + (double) (*p - '0'); - p++; - } - - if (*p == '.') { - p++; - for(m = 0.1; *p && *p != 'e'; p++ ) { - value = value + (double) (*p - '0') * m; - m *= 0.1; - } - } - if (*p == 'e') { - int i, pow, div; - p++; - if (*p == '-') { - div = nk_true; - p++; - } else if (*p == '+') { - div = nk_false; - p++; - } else div = nk_false; - - for (pow = 0; *p; p++) - pow = pow * 10 + (int) (*p - '0'); - - for (m = 1.0, i = 0; i < pow; i++) - m *= 10.0; - - if (div) - value /= m; - else value *= m; - } - number = value * neg; - if (endptr) - *endptr = (char*)p; - return number; -} - -NK_API float -nk_strtof(const char *str, char **endptr) -{ - float float_value; - double double_value; - double_value = NK_STRTOD(str, endptr); - float_value = (float)double_value; - return float_value; -} - -NK_API int -nk_stricmp(const char *s1, const char *s2) -{ - nk_int c1,c2,d; - do { - c1 = *s1++; - c2 = *s2++; - d = c1 - c2; - while (d) { - if (c1 <= 'Z' && c1 >= 'A') { - d += ('a' - 'A'); - if (!d) break; - } - if (c2 <= 'Z' && c2 >= 'A') { - d -= ('a' - 'A'); - if (!d) break; - } - return ((d >= 0) << 1) - 1; - } - } while (c1); - return 0; -} - -NK_API int -nk_stricmpn(const char *s1, const char *s2, int n) -{ - int c1,c2,d; - NK_ASSERT(n >= 0); - do { - c1 = *s1++; - c2 = *s2++; - if (!n--) return 0; - - d = c1 - c2; - while (d) { - if (c1 <= 'Z' && c1 >= 'A') { - d += ('a' - 'A'); - if (!d) break; - } - if (c2 <= 'Z' && c2 >= 'A') { - d -= ('a' - 'A'); - if (!d) break; - } - return ((d >= 0) << 1) - 1; - } - } while (c1); - return 0; -} - -NK_INTERN int -nk_str_match_here(const char *regexp, const char *text) -{ - if (regexp[0] == '\0') - return 1; - if (regexp[1] == '*') - return nk_str_match_star(regexp[0], regexp+2, text); - if (regexp[0] == '$' && regexp[1] == '\0') - return *text == '\0'; - if (*text!='\0' && (regexp[0]=='.' || regexp[0]==*text)) - return nk_str_match_here(regexp+1, text+1); - return 0; -} - -NK_INTERN int -nk_str_match_star(int c, const char *regexp, const char *text) -{ - do {/* a '* matches zero or more instances */ - if (nk_str_match_here(regexp, text)) - return 1; - } while (*text != '\0' && (*text++ == c || c == '.')); - return 0; -} - -NK_API int -nk_strfilter(const char *text, const char *regexp) -{ - /* - c matches any literal character c - . matches any single character - ^ matches the beginning of the input string - $ matches the end of the input string - * matches zero or more occurrences of the previous character*/ - if (regexp[0] == '^') - return nk_str_match_here(regexp+1, text); - do { /* must look even if string is empty */ - if (nk_str_match_here(regexp, text)) - return 1; - } while (*text++ != '\0'); - return 0; -} - -NK_API int -nk_strmatch_fuzzy_text(const char *str, int str_len, - const char *pattern, int *out_score) -{ - /* Returns true if each character in pattern is found sequentially within str - * if found then outScore is also set. Score value has no intrinsic meaning. - * Range varies with pattern. Can only compare scores with same search pattern. */ - - /* ------- scores --------- */ - /* bonus for adjacent matches */ - #define NK_ADJACENCY_BONUS 5 - /* bonus if match occurs after a separator */ - #define NK_SEPARATOR_BONUS 10 - /* bonus if match is uppercase and prev is lower */ - #define NK_CAMEL_BONUS 10 - /* penalty applied for every letter in str before the first match */ - #define NK_LEADING_LETTER_PENALTY (-3) - /* maximum penalty for leading letters */ - #define NK_MAX_LEADING_LETTER_PENALTY (-9) - /* penalty for every letter that doesn't matter */ - #define NK_UNMATCHED_LETTER_PENALTY (-1) - - /* loop variables */ - int score = 0; - char const * pattern_iter = pattern; - int str_iter = 0; - int prev_matched = nk_false; - int prev_lower = nk_false; - /* true so if first letter match gets separator bonus*/ - int prev_separator = nk_true; - - /* use "best" matched letter if multiple string letters match the pattern */ - char const * best_letter = 0; - int best_letter_score = 0; - - /* loop over strings */ - NK_ASSERT(str); - NK_ASSERT(pattern); - if (!str || !str_len || !pattern) return 0; - while (str_iter < str_len) - { - const char pattern_letter = *pattern_iter; - const char str_letter = str[str_iter]; - - int next_match = *pattern_iter != '\0' && - nk_to_lower(pattern_letter) == nk_to_lower(str_letter); - int rematch = best_letter && nk_to_lower(*best_letter) == nk_to_lower(str_letter); - - int advanced = next_match && best_letter; - int pattern_repeat = best_letter && *pattern_iter != '\0'; - pattern_repeat = pattern_repeat && - nk_to_lower(*best_letter) == nk_to_lower(pattern_letter); - - if (advanced || pattern_repeat) { - score += best_letter_score; - best_letter = 0; - best_letter_score = 0; - } - - if (next_match || rematch) - { - int new_score = 0; - /* Apply penalty for each letter before the first pattern match */ - if (pattern_iter == pattern) { - int count = (int)(&str[str_iter] - str); - int penalty = NK_LEADING_LETTER_PENALTY * count; - if (penalty < NK_MAX_LEADING_LETTER_PENALTY) - penalty = NK_MAX_LEADING_LETTER_PENALTY; - - score += penalty; - } - - /* apply bonus for consecutive bonuses */ - if (prev_matched) - new_score += NK_ADJACENCY_BONUS; - - /* apply bonus for matches after a separator */ - if (prev_separator) - new_score += NK_SEPARATOR_BONUS; - - /* apply bonus across camel case boundaries */ - if (prev_lower && nk_is_upper(str_letter)) - new_score += NK_CAMEL_BONUS; - - /* update pattern iter IFF the next pattern letter was matched */ - if (next_match) - ++pattern_iter; - - /* update best letter in str which may be for a "next" letter or a rematch */ - if (new_score >= best_letter_score) { - /* apply penalty for now skipped letter */ - if (best_letter != 0) - score += NK_UNMATCHED_LETTER_PENALTY; - - best_letter = &str[str_iter]; - best_letter_score = new_score; - } - prev_matched = nk_true; - } else { - score += NK_UNMATCHED_LETTER_PENALTY; - prev_matched = nk_false; - } - - /* separators should be more easily defined */ - prev_lower = nk_is_lower(str_letter) != 0; - prev_separator = str_letter == '_' || str_letter == ' '; - - ++str_iter; - } - - /* apply score for last match */ - if (best_letter) - score += best_letter_score; - - /* did not match full pattern */ - if (*pattern_iter != '\0') - return nk_false; - - if (out_score) - *out_score = score; - return nk_true; -} - -NK_API int -nk_strmatch_fuzzy_string(char const *str, char const *pattern, int *out_score) -{return nk_strmatch_fuzzy_text(str, nk_strlen(str), pattern, out_score);} - -NK_INTERN int -nk_string_float_limit(char *string, int prec) -{ - int dot = 0; - char *c = string; - while (*c) { - if (*c == '.') { - dot = 1; - c++; - continue; - } - if (dot == (prec+1)) { - *c = 0; - break; - } - if (dot > 0) dot++; - c++; - } - return (int)(c - string); -} - -NK_INTERN double -nk_pow(double x, int n) -{ - /* check the sign of n */ - double r = 1; - int plus = n >= 0; - n = (plus) ? n : -n; - while (n > 0) { - if ((n & 1) == 1) - r *= x; - n /= 2; - x *= x; - } - return plus ? r : 1.0 / r; -} - -NK_INTERN int -nk_ifloord(double x) -{ - x = (double)((int)x - ((x < 0.0) ? 1 : 0)); - return (int)x; -} - -NK_INTERN int -nk_ifloorf(float x) -{ - x = (float)((int)x - ((x < 0.0f) ? 1 : 0)); - return (int)x; -} - -NK_INTERN int -nk_iceilf(float x) -{ - if (x >= 0) { - int i = (int)x; - return i; - } else { - int t = (int)x; - float r = x - (float)t; - return (r > 0.0f) ? t+1: t; - } -} - -NK_INTERN int -nk_log10(double n) -{ - int neg; - int ret; - int exp = 0; - - neg = (n < 0) ? 1 : 0; - ret = (neg) ? (int)-n : (int)n; - while ((ret / 10) > 0) { - ret /= 10; - exp++; - } - if (neg) exp = -exp; - return exp; -} - -NK_INTERN void -nk_strrev_ascii(char *s) -{ - int len = nk_strlen(s); - int end = len / 2; - int i = 0; - char t; - for (; i < end; ++i) { - t = s[i]; - s[i] = s[len - 1 - i]; - s[len -1 - i] = t; - } -} - -NK_INTERN char* -nk_itoa(char *s, long n) -{ - long i = 0; - if (n == 0) { - s[i++] = '0'; - s[i] = 0; - return s; - } - if (n < 0) { - s[i++] = '-'; - n = -n; - } - while (n > 0) { - s[i++] = (char)('0' + (n % 10)); - n /= 10; - } - s[i] = 0; - if (s[0] == '-') - ++s; - - nk_strrev_ascii(s); - return s; -} - -NK_INTERN char* -nk_dtoa(char *s, double n) -{ - int useExp = 0; - int digit = 0, m = 0, m1 = 0; - char *c = s; - int neg = 0; - - NK_ASSERT(s); - if (!s) return 0; - - if (n == 0.0) { - s[0] = '0'; s[1] = '\0'; - return s; - } - - neg = (n < 0); - if (neg) n = -n; - - /* calculate magnitude */ - m = nk_log10(n); - useExp = (m >= 14 || (neg && m >= 9) || m <= -9); - if (neg) *(c++) = '-'; - - /* set up for scientific notation */ - if (useExp) { - if (m < 0) - m -= 1; - n = n / (double)nk_pow(10.0, m); - m1 = m; - m = 0; - } - if (m < 1.0) { - m = 0; - } - - /* convert the number */ - while (n > NK_FLOAT_PRECISION || m >= 0) { - double weight = nk_pow(10.0, m); - if (weight > 0) { - double t = (double)n / weight; - digit = nk_ifloord(t); - n -= ((double)digit * weight); - *(c++) = (char)('0' + (char)digit); - } - if (m == 0 && n > 0) - *(c++) = '.'; - m--; - } - - if (useExp) { - /* convert the exponent */ - int i, j; - *(c++) = 'e'; - if (m1 > 0) { - *(c++) = '+'; - } else { - *(c++) = '-'; - m1 = -m1; - } - m = 0; - while (m1 > 0) { - *(c++) = (char)('0' + (char)(m1 % 10)); - m1 /= 10; - m++; - } - c -= m; - for (i = 0, j = m-1; i= buf_size) break; - iter++; - - /* flag arguments */ - while (*iter) { - if (*iter == '-') flag |= NK_ARG_FLAG_LEFT; - else if (*iter == '+') flag |= NK_ARG_FLAG_PLUS; - else if (*iter == ' ') flag |= NK_ARG_FLAG_SPACE; - else if (*iter == '#') flag |= NK_ARG_FLAG_NUM; - else if (*iter == '0') flag |= NK_ARG_FLAG_ZERO; - else break; - iter++; - } - - /* width argument */ - width = NK_DEFAULT; - if (*iter >= '1' && *iter <= '9') { - char *end; - width = nk_strtoi(iter, &end); - if (end == iter) - width = -1; - else iter = end; - } else if (*iter == '*') { - width = va_arg(args, int); - iter++; - } - - /* precision argument */ - precision = NK_DEFAULT; - if (*iter == '.') { - iter++; - if (*iter == '*') { - precision = va_arg(args, int); - iter++; - } else { - char *end; - precision = nk_strtoi(iter, &end); - if (end == iter) - precision = -1; - else iter = end; - } - } - - /* length modifier */ - if (*iter == 'h') { - if (*(iter+1) == 'h') { - arg_type = NK_ARG_TYPE_CHAR; - iter++; - } else arg_type = NK_ARG_TYPE_SHORT; - iter++; - } else if (*iter == 'l') { - arg_type = NK_ARG_TYPE_LONG; - iter++; - } else arg_type = NK_ARG_TYPE_DEFAULT; - - /* specifier */ - if (*iter == '%') { - NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT); - NK_ASSERT(precision == NK_DEFAULT); - NK_ASSERT(width == NK_DEFAULT); - if (len < buf_size) - buf[len++] = '%'; - } else if (*iter == 's') { - /* string */ - const char *str = va_arg(args, const char*); - NK_ASSERT(str != buf && "buffer and argument are not allowed to overlap!"); - NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT); - NK_ASSERT(precision == NK_DEFAULT); - NK_ASSERT(width == NK_DEFAULT); - if (str == buf) return -1; - while (str && *str && len < buf_size) - buf[len++] = *str++; - } else if (*iter == 'n') { - /* current length callback */ - signed int *n = va_arg(args, int*); - NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT); - NK_ASSERT(precision == NK_DEFAULT); - NK_ASSERT(width == NK_DEFAULT); - if (n) *n = len; - } else if (*iter == 'c' || *iter == 'i' || *iter == 'd') { - /* signed integer */ - long value = 0; - const char *num_iter; - int num_len, num_print, padding; - int cur_precision = NK_MAX(precision, 1); - int cur_width = NK_MAX(width, 0); - - /* retrieve correct value type */ - if (arg_type == NK_ARG_TYPE_CHAR) - value = (signed char)va_arg(args, int); - else if (arg_type == NK_ARG_TYPE_SHORT) - value = (signed short)va_arg(args, int); - else if (arg_type == NK_ARG_TYPE_LONG) - value = va_arg(args, signed long); - else if (*iter == 'c') - value = (unsigned char)va_arg(args, int); - else value = va_arg(args, signed int); - - /* convert number to string */ - nk_itoa(number_buffer, value); - num_len = nk_strlen(number_buffer); - padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0); - if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE)) - padding = NK_MAX(padding-1, 0); - - /* fill left padding up to a total of `width` characters */ - if (!(flag & NK_ARG_FLAG_LEFT)) { - while (padding-- > 0 && (len < buf_size)) { - if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT)) - buf[len++] = '0'; - else buf[len++] = ' '; - } - } - - /* copy string value representation into buffer */ - if ((flag & NK_ARG_FLAG_PLUS) && value >= 0 && len < buf_size) - buf[len++] = '+'; - else if ((flag & NK_ARG_FLAG_SPACE) && value >= 0 && len < buf_size) - buf[len++] = ' '; - - /* fill up to precision number of digits with '0' */ - num_print = NK_MAX(cur_precision, num_len); - while (precision && (num_print > num_len) && (len < buf_size)) { - buf[len++] = '0'; - num_print--; - } - - /* copy string value representation into buffer */ - num_iter = number_buffer; - while (precision && *num_iter && len < buf_size) - buf[len++] = *num_iter++; - - /* fill right padding up to width characters */ - if (flag & NK_ARG_FLAG_LEFT) { - while ((padding-- > 0) && (len < buf_size)) - buf[len++] = ' '; - } - } else if (*iter == 'o' || *iter == 'x' || *iter == 'X' || *iter == 'u') { - /* unsigned integer */ - unsigned long value = 0; - int num_len = 0, num_print, padding = 0; - int cur_precision = NK_MAX(precision, 1); - int cur_width = NK_MAX(width, 0); - unsigned int base = (*iter == 'o') ? 8: (*iter == 'u')? 10: 16; - - /* print oct/hex/dec value */ - const char *upper_output_format = "0123456789ABCDEF"; - const char *lower_output_format = "0123456789abcdef"; - const char *output_format = (*iter == 'x') ? - lower_output_format: upper_output_format; - - /* retrieve correct value type */ - if (arg_type == NK_ARG_TYPE_CHAR) - value = (unsigned char)va_arg(args, int); - else if (arg_type == NK_ARG_TYPE_SHORT) - value = (unsigned short)va_arg(args, int); - else if (arg_type == NK_ARG_TYPE_LONG) - value = va_arg(args, unsigned long); - else value = va_arg(args, unsigned int); - - do { - /* convert decimal number into hex/oct number */ - int digit = output_format[value % base]; - if (num_len < NK_MAX_NUMBER_BUFFER) - number_buffer[num_len++] = (char)digit; - value /= base; - } while (value > 0); - - num_print = NK_MAX(cur_precision, num_len); - padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0); - if (flag & NK_ARG_FLAG_NUM) - padding = NK_MAX(padding-1, 0); - - /* fill left padding up to a total of `width` characters */ - if (!(flag & NK_ARG_FLAG_LEFT)) { - while ((padding-- > 0) && (len < buf_size)) { - if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT)) - buf[len++] = '0'; - else buf[len++] = ' '; - } - } - - /* fill up to precision number of digits */ - if (num_print && (flag & NK_ARG_FLAG_NUM)) { - if ((*iter == 'o') && (len < buf_size)) { - buf[len++] = '0'; - } else if ((*iter == 'x') && ((len+1) < buf_size)) { - buf[len++] = '0'; - buf[len++] = 'x'; - } else if ((*iter == 'X') && ((len+1) < buf_size)) { - buf[len++] = '0'; - buf[len++] = 'X'; - } - } - while (precision && (num_print > num_len) && (len < buf_size)) { - buf[len++] = '0'; - num_print--; - } - - /* reverse number direction */ - while (num_len > 0) { - if (precision && (len < buf_size)) - buf[len++] = number_buffer[num_len-1]; - num_len--; - } - - /* fill right padding up to width characters */ - if (flag & NK_ARG_FLAG_LEFT) { - while ((padding-- > 0) && (len < buf_size)) - buf[len++] = ' '; - } - } else if (*iter == 'f') { - /* floating point */ - const char *num_iter; - int cur_precision = (precision < 0) ? 6: precision; - int prefix, cur_width = NK_MAX(width, 0); - double value = va_arg(args, double); - int num_len = 0, frac_len = 0, dot = 0; - int padding = 0; - - NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT); - NK_DTOA(number_buffer, value); - num_len = nk_strlen(number_buffer); - - /* calculate padding */ - num_iter = number_buffer; - while (*num_iter && *num_iter != '.') - num_iter++; - - prefix = (*num_iter == '.')?(int)(num_iter - number_buffer)+1:0; - padding = NK_MAX(cur_width - (prefix + NK_MIN(cur_precision, num_len - prefix)) , 0); - if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE)) - padding = NK_MAX(padding-1, 0); - - /* fill left padding up to a total of `width` characters */ - if (!(flag & NK_ARG_FLAG_LEFT)) { - while (padding-- > 0 && (len < buf_size)) { - if (flag & NK_ARG_FLAG_ZERO) - buf[len++] = '0'; - else buf[len++] = ' '; - } - } - - /* copy string value representation into buffer */ - num_iter = number_buffer; - if ((flag & NK_ARG_FLAG_PLUS) && (value >= 0) && (len < buf_size)) - buf[len++] = '+'; - else if ((flag & NK_ARG_FLAG_SPACE) && (value >= 0) && (len < buf_size)) - buf[len++] = ' '; - while (*num_iter) { - if (dot) frac_len++; - if (len < buf_size) - buf[len++] = *num_iter; - if (*num_iter == '.') dot = 1; - if (frac_len >= cur_precision) break; - num_iter++; - } - - /* fill number up to precision */ - while (frac_len < cur_precision) { - if (!dot && len < buf_size) { - buf[len++] = '.'; - dot = 1; - } - if (len < buf_size) - buf[len++] = '0'; - frac_len++; - } - - /* fill right padding up to width characters */ - if (flag & NK_ARG_FLAG_LEFT) { - while ((padding-- > 0) && (len < buf_size)) - buf[len++] = ' '; - } - } else { - /* Specifier not supported: g,G,e,E,p,z */ - NK_ASSERT(0 && "specifier is not supported!"); - return result; - } - } - buf[(len >= buf_size)?(buf_size-1):len] = 0; - result = (len >= buf_size)?-1:len; - return result; -} - -NK_INTERN int -nk_strfmt(char *buf, int buf_size, const char *fmt, va_list args) -{ - int result = -1; - NK_ASSERT(buf); - NK_ASSERT(buf_size); - if (!buf || !buf_size || !fmt) return 0; -#ifdef NK_INCLUDE_STANDARD_IO - result = NK_VSNPRINTF(buf, (nk_size)buf_size, fmt, args); - result = (result >= buf_size) ? -1: result; - buf[buf_size-1] = 0; -#else - result = nk_vsnprintf(buf, buf_size, fmt, args); -#endif - return result; -} -#endif - -NK_API nk_hash -nk_murmur_hash(const void * key, int len, nk_hash seed) -{ - /* 32-Bit MurmurHash3: https://code.google.com/p/smhasher/wiki/MurmurHash3*/ - #define NK_ROTL(x,r) ((x) << (r) | ((x) >> (32 - r))) - union {const nk_uint *i; const nk_byte *b;} conv = {0}; - const nk_byte *data = (const nk_byte*)key; - const int nblocks = len/4; - nk_uint h1 = seed; - const nk_uint c1 = 0xcc9e2d51; - const nk_uint c2 = 0x1b873593; - const nk_byte *tail; - const nk_uint *blocks; - nk_uint k1; - int i; - - /* body */ - if (!key) return 0; - conv.b = (data + nblocks*4); - blocks = (const nk_uint*)conv.i; - for (i = -nblocks; i; ++i) { - k1 = blocks[i]; - k1 *= c1; - k1 = NK_ROTL(k1,15); - k1 *= c2; - - h1 ^= k1; - h1 = NK_ROTL(h1,13); - h1 = h1*5+0xe6546b64; - } - - /* tail */ - tail = (const nk_byte*)(data + nblocks*4); - k1 = 0; - switch (len & 3) { - case 3: k1 ^= (nk_uint)(tail[2] << 16); - case 2: k1 ^= (nk_uint)(tail[1] << 8u); - case 1: k1 ^= tail[0]; - k1 *= c1; - k1 = NK_ROTL(k1,15); - k1 *= c2; - h1 ^= k1; - default: break; - } - - /* finalization */ - h1 ^= (nk_uint)len; - /* fmix32 */ - h1 ^= h1 >> 16; - h1 *= 0x85ebca6b; - h1 ^= h1 >> 13; - h1 *= 0xc2b2ae35; - h1 ^= h1 >> 16; - - #undef NK_ROTL - return h1; -} - -#ifdef NK_INCLUDE_STANDARD_IO -NK_INTERN char* -nk_file_load(const char* path, nk_size* siz, struct nk_allocator *alloc) -{ - char *buf; - FILE *fd; - long ret; - - NK_ASSERT(path); - NK_ASSERT(siz); - NK_ASSERT(alloc); - if (!path || !siz || !alloc) - return 0; - - fd = fopen(path, "rb"); - if (!fd) return 0; - fseek(fd, 0, SEEK_END); - ret = ftell(fd); - if (ret < 0) { - fclose(fd); - return 0; - } - *siz = (nk_size)ret; - fseek(fd, 0, SEEK_SET); - buf = (char*)alloc->alloc(alloc->userdata,0, *siz); - NK_ASSERT(buf); - if (!buf) { - fclose(fd); - return 0; - } - *siz = (nk_size)fread(buf, *siz, 1, fd); - fclose(fd); - return buf; -} -#endif - -/* - * ============================================================== - * - * COLOR - * - * =============================================================== - */ -NK_INTERN int -nk_parse_hex(const char *p, int length) -{ - int i = 0; - int len = 0; - while (len < length) { - i <<= 4; - if (p[len] >= 'a' && p[len] <= 'f') - i += ((p[len] - 'a') + 10); - else if (p[len] >= 'A' && p[len] <= 'F') - i += ((p[len] - 'A') + 10); - else i += (p[len] - '0'); - len++; - } - return i; -} - -NK_API struct nk_color -nk_rgba(int r, int g, int b, int a) -{ - struct nk_color ret; - ret.r = (nk_byte)NK_CLAMP(0, r, 255); - ret.g = (nk_byte)NK_CLAMP(0, g, 255); - ret.b = (nk_byte)NK_CLAMP(0, b, 255); - ret.a = (nk_byte)NK_CLAMP(0, a, 255); - return ret; -} - -NK_API struct nk_color -nk_rgb_hex(const char *rgb) -{ - struct nk_color col; - const char *c = rgb; - if (*c == '#') c++; - col.r = (nk_byte)nk_parse_hex(c, 2); - col.g = (nk_byte)nk_parse_hex(c+2, 2); - col.b = (nk_byte)nk_parse_hex(c+4, 2); - col.a = 255; - return col; -} - -NK_API struct nk_color -nk_rgba_hex(const char *rgb) -{ - struct nk_color col; - const char *c = rgb; - if (*c == '#') c++; - col.r = (nk_byte)nk_parse_hex(c, 2); - col.g = (nk_byte)nk_parse_hex(c+2, 2); - col.b = (nk_byte)nk_parse_hex(c+4, 2); - col.a = (nk_byte)nk_parse_hex(c+6, 2); - return col; -} - -NK_API void -nk_color_hex_rgba(char *output, struct nk_color col) -{ - #define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i): 'A' - 10 + (i)) - output[0] = (char)NK_TO_HEX((col.r & 0xF0) >> 4); - output[1] = (char)NK_TO_HEX((col.r & 0x0F)); - output[2] = (char)NK_TO_HEX((col.g & 0xF0) >> 4); - output[3] = (char)NK_TO_HEX((col.g & 0x0F)); - output[4] = (char)NK_TO_HEX((col.b & 0xF0) >> 4); - output[5] = (char)NK_TO_HEX((col.b & 0x0F)); - output[6] = (char)NK_TO_HEX((col.a & 0xF0) >> 4); - output[7] = (char)NK_TO_HEX((col.a & 0x0F)); - output[8] = '\0'; - #undef NK_TO_HEX -} - -NK_API void -nk_color_hex_rgb(char *output, struct nk_color col) -{ - #define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i): 'A' - 10 + (i)) - output[0] = (char)NK_TO_HEX((col.r & 0xF0) >> 4); - output[1] = (char)NK_TO_HEX((col.r & 0x0F)); - output[2] = (char)NK_TO_HEX((col.g & 0xF0) >> 4); - output[3] = (char)NK_TO_HEX((col.g & 0x0F)); - output[4] = (char)NK_TO_HEX((col.b & 0xF0) >> 4); - output[5] = (char)NK_TO_HEX((col.b & 0x0F)); - output[6] = '\0'; - #undef NK_TO_HEX -} - -NK_API struct nk_color -nk_rgba_iv(const int *c) -{ - return nk_rgba(c[0], c[1], c[2], c[3]); -} - -NK_API struct nk_color -nk_rgba_bv(const nk_byte *c) -{ - return nk_rgba(c[0], c[1], c[2], c[3]); -} - -NK_API struct nk_color -nk_rgb(int r, int g, int b) -{ - struct nk_color ret; - ret.r = (nk_byte)NK_CLAMP(0, r, 255); - ret.g = (nk_byte)NK_CLAMP(0, g, 255); - ret.b = (nk_byte)NK_CLAMP(0, b, 255); - ret.a = (nk_byte)255; - return ret; -} - -NK_API struct nk_color -nk_rgb_iv(const int *c) -{ - return nk_rgb(c[0], c[1], c[2]); -} - -NK_API struct nk_color -nk_rgb_bv(const nk_byte* c) -{ - return nk_rgb(c[0], c[1], c[2]); -} - -NK_API struct nk_color -nk_rgba_u32(nk_uint in) -{ - struct nk_color ret; - ret.r = (in & 0xFF); - ret.g = ((in >> 8) & 0xFF); - ret.b = ((in >> 16) & 0xFF); - ret.a = (nk_byte)((in >> 24) & 0xFF); - return ret; -} - -NK_API struct nk_color -nk_rgba_f(float r, float g, float b, float a) -{ - struct nk_color ret; - ret.r = (nk_byte)(NK_SATURATE(r) * 255.0f); - ret.g = (nk_byte)(NK_SATURATE(g) * 255.0f); - ret.b = (nk_byte)(NK_SATURATE(b) * 255.0f); - ret.a = (nk_byte)(NK_SATURATE(a) * 255.0f); - return ret; -} - -NK_API struct nk_color -nk_rgba_fv(const float *c) -{ - return nk_rgba_f(c[0], c[1], c[2], c[3]); -} - -NK_API struct nk_color -nk_rgb_f(float r, float g, float b) -{ - struct nk_color ret; - ret.r = (nk_byte)(NK_SATURATE(r) * 255.0f); - ret.g = (nk_byte)(NK_SATURATE(g) * 255.0f); - ret.b = (nk_byte)(NK_SATURATE(b) * 255.0f); - ret.a = 255; - return ret; -} - -NK_API struct nk_color -nk_rgb_fv(const float *c) -{ - return nk_rgb_f(c[0], c[1], c[2]); -} - -NK_API struct nk_color -nk_hsv(int h, int s, int v) -{ - return nk_hsva(h, s, v, 255); -} - -NK_API struct nk_color -nk_hsv_iv(const int *c) -{ - return nk_hsv(c[0], c[1], c[2]); -} - -NK_API struct nk_color -nk_hsv_bv(const nk_byte *c) -{ - return nk_hsv(c[0], c[1], c[2]); -} - -NK_API struct nk_color -nk_hsv_f(float h, float s, float v) -{ - return nk_hsva_f(h, s, v, 1.0f); -} - -NK_API struct nk_color -nk_hsv_fv(const float *c) -{ - return nk_hsv_f(c[0], c[1], c[2]); -} - -NK_API struct nk_color -nk_hsva(int h, int s, int v, int a) -{ - float hf = ((float)NK_CLAMP(0, h, 255)) / 255.0f; - float sf = ((float)NK_CLAMP(0, s, 255)) / 255.0f; - float vf = ((float)NK_CLAMP(0, v, 255)) / 255.0f; - float af = ((float)NK_CLAMP(0, a, 255)) / 255.0f; - return nk_hsva_f(hf, sf, vf, af); -} - -NK_API struct nk_color -nk_hsva_iv(const int *c) -{ - return nk_hsva(c[0], c[1], c[2], c[3]); -} - -NK_API struct nk_color -nk_hsva_bv(const nk_byte *c) -{ - return nk_hsva(c[0], c[1], c[2], c[3]); -} - -NK_API struct nk_color -nk_hsva_f(float h, float s, float v, float a) -{ - struct nk_colorf out = {0,0,0,0}; - float p, q, t, f; - int i; - - if (s <= 0.0f) { - out.r = v; out.g = v; out.b = v; - return nk_rgb_f(out.r, out.g, out.b); - } - - h = h / (60.0f/360.0f); - i = (int)h; - f = h - (float)i; - p = v * (1.0f - s); - q = v * (1.0f - (s * f)); - t = v * (1.0f - s * (1.0f - f)); - - switch (i) { - case 0: default: out.r = v; out.g = t; out.b = p; break; - case 1: out.r = q; out.g = v; out.b = p; break; - case 2: out.r = p; out.g = v; out.b = t; break; - case 3: out.r = p; out.g = q; out.b = v; break; - case 4: out.r = t; out.g = p; out.b = v; break; - case 5: out.r = v; out.g = p; out.b = q; break; - } - return nk_rgba_f(out.r, out.g, out.b, a); -} - -NK_API struct nk_color -nk_hsva_fv(const float *c) -{ - return nk_hsva_f(c[0], c[1], c[2], c[3]); -} - -NK_API nk_uint -nk_color_u32(struct nk_color in) -{ - nk_uint out = (nk_uint)in.r; - out |= ((nk_uint)in.g << 8); - out |= ((nk_uint)in.b << 16); - out |= ((nk_uint)in.a << 24); - return out; -} - -NK_API void -nk_color_f(float *r, float *g, float *b, float *a, struct nk_color in) -{ - NK_STORAGE const float s = 1.0f/255.0f; - *r = (float)in.r * s; - *g = (float)in.g * s; - *b = (float)in.b * s; - *a = (float)in.a * s; -} - -NK_API void -nk_color_fv(float *c, struct nk_color in) -{ - nk_color_f(&c[0], &c[1], &c[2], &c[3], in); -} - -NK_API void -nk_color_d(double *r, double *g, double *b, double *a, struct nk_color in) -{ - NK_STORAGE const double s = 1.0/255.0; - *r = (double)in.r * s; - *g = (double)in.g * s; - *b = (double)in.b * s; - *a = (double)in.a * s; -} - -NK_API void -nk_color_dv(double *c, struct nk_color in) -{ - nk_color_d(&c[0], &c[1], &c[2], &c[3], in); -} - -NK_API void -nk_color_hsv_f(float *out_h, float *out_s, float *out_v, struct nk_color in) -{ - float a; - nk_color_hsva_f(out_h, out_s, out_v, &a, in); -} - -NK_API void -nk_color_hsv_fv(float *out, struct nk_color in) -{ - float a; - nk_color_hsva_f(&out[0], &out[1], &out[2], &a, in); -} - -NK_API void -nk_color_hsva_f(float *out_h, float *out_s, - float *out_v, float *out_a, struct nk_color in) -{ - float chroma; - float K = 0.0f; - float r,g,b,a; - - nk_color_f(&r,&g,&b,&a, in); - if (g < b) { - const float t = g; g = b; b = t; - K = -1.f; - } - if (r < g) { - const float t = r; r = g; g = t; - K = -2.f/6.0f - K; - } - chroma = r - ((g < b) ? g: b); - *out_h = NK_ABS(K + (g - b)/(6.0f * chroma + 1e-20f)); - *out_s = chroma / (r + 1e-20f); - *out_v = r; - *out_a = (float)in.a / 255.0f; -} - -NK_API void -nk_color_hsva_fv(float *out, struct nk_color in) -{ - nk_color_hsva_f(&out[0], &out[1], &out[2], &out[3], in); -} - -NK_API void -nk_color_hsva_i(int *out_h, int *out_s, int *out_v, - int *out_a, struct nk_color in) -{ - float h,s,v,a; - nk_color_hsva_f(&h, &s, &v, &a, in); - *out_h = (nk_byte)(h * 255.0f); - *out_s = (nk_byte)(s * 255.0f); - *out_v = (nk_byte)(v * 255.0f); - *out_a = (nk_byte)(a * 255.0f); -} - -NK_API void -nk_color_hsva_iv(int *out, struct nk_color in) -{ - nk_color_hsva_i(&out[0], &out[1], &out[2], &out[3], in); -} - -NK_API void -nk_color_hsva_bv(nk_byte *out, struct nk_color in) -{ - int tmp[4]; - nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in); - out[0] = (nk_byte)tmp[0]; - out[1] = (nk_byte)tmp[1]; - out[2] = (nk_byte)tmp[2]; - out[3] = (nk_byte)tmp[3]; -} - -NK_API void -nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a, struct nk_color in) -{ - int tmp[4]; - nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in); - *h = (nk_byte)tmp[0]; - *s = (nk_byte)tmp[1]; - *v = (nk_byte)tmp[2]; - *a = (nk_byte)tmp[3]; -} - -NK_API void -nk_color_hsv_i(int *out_h, int *out_s, int *out_v, struct nk_color in) -{ - int a; - nk_color_hsva_i(out_h, out_s, out_v, &a, in); -} - -NK_API void -nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v, struct nk_color in) -{ - int tmp[4]; - nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in); - *out_h = (nk_byte)tmp[0]; - *out_s = (nk_byte)tmp[1]; - *out_v = (nk_byte)tmp[2]; -} - -NK_API void -nk_color_hsv_iv(int *out, struct nk_color in) -{ - nk_color_hsv_i(&out[0], &out[1], &out[2], in); -} - -NK_API void -nk_color_hsv_bv(nk_byte *out, struct nk_color in) -{ - int tmp[4]; - nk_color_hsv_i(&tmp[0], &tmp[1], &tmp[2], in); - out[0] = (nk_byte)tmp[0]; - out[1] = (nk_byte)tmp[1]; - out[2] = (nk_byte)tmp[2]; -} -/* - * ============================================================== - * - * IMAGE - * - * =============================================================== - */ -NK_API nk_handle -nk_handle_ptr(void *ptr) -{ - nk_handle handle = {0}; - handle.ptr = ptr; - return handle; -} - -NK_API nk_handle -nk_handle_id(int id) -{ - nk_handle handle; - nk_zero_struct(handle); - handle.id = id; - return handle; -} - -NK_API struct nk_image -nk_subimage_ptr(void *ptr, unsigned short w, unsigned short h, struct nk_rect r) -{ - struct nk_image s; - nk_zero(&s, sizeof(s)); - s.handle.ptr = ptr; - s.w = w; s.h = h; - s.region[0] = (unsigned short)r.x; - s.region[1] = (unsigned short)r.y; - s.region[2] = (unsigned short)r.w; - s.region[3] = (unsigned short)r.h; - return s; -} - -NK_API struct nk_image -nk_subimage_id(int id, unsigned short w, unsigned short h, struct nk_rect r) -{ - struct nk_image s; - nk_zero(&s, sizeof(s)); - s.handle.id = id; - s.w = w; s.h = h; - s.region[0] = (unsigned short)r.x; - s.region[1] = (unsigned short)r.y; - s.region[2] = (unsigned short)r.w; - s.region[3] = (unsigned short)r.h; - return s; -} - -NK_API struct nk_image -nk_subimage_handle(nk_handle handle, unsigned short w, unsigned short h, - struct nk_rect r) -{ - struct nk_image s; - nk_zero(&s, sizeof(s)); - s.handle = handle; - s.w = w; s.h = h; - s.region[0] = (unsigned short)r.x; - s.region[1] = (unsigned short)r.y; - s.region[2] = (unsigned short)r.w; - s.region[3] = (unsigned short)r.h; - return s; -} - -NK_API struct nk_image -nk_image_handle(nk_handle handle) -{ - struct nk_image s; - nk_zero(&s, sizeof(s)); - s.handle = handle; - s.w = 0; s.h = 0; - s.region[0] = 0; - s.region[1] = 0; - s.region[2] = 0; - s.region[3] = 0; - return s; -} - -NK_API struct nk_image -nk_image_ptr(void *ptr) -{ - struct nk_image s; - nk_zero(&s, sizeof(s)); - NK_ASSERT(ptr); - s.handle.ptr = ptr; - s.w = 0; s.h = 0; - s.region[0] = 0; - s.region[1] = 0; - s.region[2] = 0; - s.region[3] = 0; - return s; -} - -NK_API struct nk_image -nk_image_id(int id) -{ - struct nk_image s; - nk_zero(&s, sizeof(s)); - s.handle.id = id; - s.w = 0; s.h = 0; - s.region[0] = 0; - s.region[1] = 0; - s.region[2] = 0; - s.region[3] = 0; - return s; -} - -NK_API int -nk_image_is_subimage(const struct nk_image* img) -{ - NK_ASSERT(img); - return !(img->w == 0 && img->h == 0); -} - -NK_INTERN void -nk_unify(struct nk_rect *clip, const struct nk_rect *a, float x0, float y0, - float x1, float y1) -{ - NK_ASSERT(a); - NK_ASSERT(clip); - clip->x = NK_MAX(a->x, x0); - clip->y = NK_MAX(a->y, y0); - clip->w = NK_MIN(a->x + a->w, x1) - clip->x; - clip->h = NK_MIN(a->y + a->h, y1) - clip->y; - clip->w = NK_MAX(0, clip->w); - clip->h = NK_MAX(0, clip->h); -} - -NK_API void -nk_triangle_from_direction(struct nk_vec2 *result, struct nk_rect r, - float pad_x, float pad_y, enum nk_heading direction) -{ - float w_half, h_half; - NK_ASSERT(result); - - r.w = NK_MAX(2 * pad_x, r.w); - r.h = NK_MAX(2 * pad_y, r.h); - r.w = r.w - 2 * pad_x; - r.h = r.h - 2 * pad_y; - - r.x = r.x + pad_x; - r.y = r.y + pad_y; - - w_half = r.w / 2.0f; - h_half = r.h / 2.0f; - - if (direction == NK_UP) { - result[0] = nk_vec2(r.x + w_half, r.y); - result[1] = nk_vec2(r.x + r.w, r.y + r.h); - result[2] = nk_vec2(r.x, r.y + r.h); - } else if (direction == NK_RIGHT) { - result[0] = nk_vec2(r.x, r.y); - result[1] = nk_vec2(r.x + r.w, r.y + h_half); - result[2] = nk_vec2(r.x, r.y + r.h); - } else if (direction == NK_DOWN) { - result[0] = nk_vec2(r.x, r.y); - result[1] = nk_vec2(r.x + r.w, r.y); - result[2] = nk_vec2(r.x + w_half, r.y + r.h); - } else { - result[0] = nk_vec2(r.x, r.y + h_half); - result[1] = nk_vec2(r.x + r.w, r.y); - result[2] = nk_vec2(r.x + r.w, r.y + r.h); - } -} - -NK_INTERN 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) -{ - int i = 0; - int glyph_len = 0; - float last_width = 0; - nk_rune unicode = 0; - float width = 0; - int len = 0; - int g = 0; - float s; - - int sep_len = 0; - int sep_g = 0; - float sep_width = 0; - sep_count = NK_MAX(sep_count,0); - - glyph_len = nk_utf_decode(text, &unicode, text_len); - while (glyph_len && (width < space) && (len < text_len)) { - len += glyph_len; - s = font->width(font->userdata, font->height, text, len); - for (i = 0; i < sep_count; ++i) { - if (unicode != sep_list[i]) continue; - sep_width = last_width = width; - sep_g = g+1; - sep_len = len; - break; - } - if (i == NK_MAX(sep_count,0)){ - last_width = sep_width = width; - sep_g = g+1; - } - width = s; - glyph_len = nk_utf_decode(&text[len], &unicode, text_len - len); - g++; - } - if (len >= text_len) { - *glyphs = g; - *text_width = last_width; - return len; - } else { - *glyphs = sep_g; - *text_width = sep_width; - return (!sep_len) ? len: sep_len; - } -} - -enum {NK_DO_NOT_STOP_ON_NEW_LINE, NK_STOP_ON_NEW_LINE}; -NK_INTERN 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) -{ - float line_height = row_height; - struct nk_vec2 text_size = nk_vec2(0,0); - float line_width = 0.0f; - - float glyph_width; - int glyph_len = 0; - nk_rune unicode = 0; - int text_len = 0; - if (!begin || byte_len <= 0 || !font) - return nk_vec2(0,row_height); - - glyph_len = nk_utf_decode(begin, &unicode, byte_len); - if (!glyph_len) return text_size; - glyph_width = font->width(font->userdata, font->height, begin, glyph_len); - - *glyphs = 0; - while ((text_len < byte_len) && glyph_len) { - if (unicode == '\n') { - text_size.x = NK_MAX(text_size.x, line_width); - text_size.y += line_height; - line_width = 0; - *glyphs+=1; - if (op == NK_STOP_ON_NEW_LINE) - break; - - text_len++; - glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len); - continue; - } - - if (unicode == '\r') { - text_len++; - *glyphs+=1; - glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len); - continue; - } - - *glyphs = *glyphs + 1; - text_len += glyph_len; - line_width += (float)glyph_width; - glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len); - glyph_width = font->width(font->userdata, font->height, begin+text_len, glyph_len); - continue; - } - - if (text_size.x < line_width) - text_size.x = line_width; - if (out_offset) - *out_offset = nk_vec2(line_width, text_size.y + line_height); - if (line_width > 0 || text_size.y == 0.0f) - text_size.y += line_height; - if (remaining) - *remaining = begin+text_len; - return text_size; -} - -/* ============================================================== - * - * UTF-8 - * - * ===============================================================*/ -NK_GLOBAL const nk_byte nk_utfbyte[NK_UTF_SIZE+1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; -NK_GLOBAL const nk_byte nk_utfmask[NK_UTF_SIZE+1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; -NK_GLOBAL const nk_uint nk_utfmin[NK_UTF_SIZE+1] = {0, 0, 0x80, 0x800, 0x10000}; -NK_GLOBAL const nk_uint nk_utfmax[NK_UTF_SIZE+1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; - -NK_INTERN int -nk_utf_validate(nk_rune *u, int i) -{ - NK_ASSERT(u); - if (!u) return 0; - if (!NK_BETWEEN(*u, nk_utfmin[i], nk_utfmax[i]) || - NK_BETWEEN(*u, 0xD800, 0xDFFF)) - *u = NK_UTF_INVALID; - for (i = 1; *u > nk_utfmax[i]; ++i); - return i; -} - -NK_INTERN nk_rune -nk_utf_decode_byte(char c, int *i) -{ - NK_ASSERT(i); - if (!i) return 0; - for(*i = 0; *i < (int)NK_LEN(nk_utfmask); ++(*i)) { - if (((nk_byte)c & nk_utfmask[*i]) == nk_utfbyte[*i]) - return (nk_byte)(c & ~nk_utfmask[*i]); - } - return 0; -} - -NK_API int -nk_utf_decode(const char *c, nk_rune *u, int clen) -{ - int i, j, len, type=0; - nk_rune udecoded; - - NK_ASSERT(c); - NK_ASSERT(u); - - if (!c || !u) return 0; - if (!clen) return 0; - *u = NK_UTF_INVALID; - - udecoded = nk_utf_decode_byte(c[0], &len); - if (!NK_BETWEEN(len, 1, NK_UTF_SIZE)) - return 1; - - for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { - udecoded = (udecoded << 6) | nk_utf_decode_byte(c[i], &type); - if (type != 0) - return j; - } - if (j < len) - return 0; - *u = udecoded; - nk_utf_validate(u, len); - return len; -} - -NK_INTERN char -nk_utf_encode_byte(nk_rune u, int i) -{ - return (char)((nk_utfbyte[i]) | ((nk_byte)u & ~nk_utfmask[i])); -} - -NK_API int -nk_utf_encode(nk_rune u, char *c, int clen) -{ - int len, i; - len = nk_utf_validate(&u, 0); - if (clen < len || !len || len > NK_UTF_SIZE) - return 0; - - for (i = len - 1; i != 0; --i) { - c[i] = nk_utf_encode_byte(u, 0); - u >>= 6; - } - c[0] = nk_utf_encode_byte(u, len); - return len; -} - -NK_API int -nk_utf_len(const char *str, int len) -{ - const char *text; - int glyphs = 0; - int text_len; - int glyph_len; - int src_len = 0; - nk_rune unicode; - - NK_ASSERT(str); - if (!str || !len) return 0; - - text = str; - text_len = len; - glyph_len = nk_utf_decode(text, &unicode, text_len); - while (glyph_len && src_len < len) { - glyphs++; - src_len = src_len + glyph_len; - glyph_len = nk_utf_decode(text + src_len, &unicode, text_len - src_len); - } - return glyphs; -} - -NK_API const char* -nk_utf_at(const char *buffer, int length, int index, - nk_rune *unicode, int *len) -{ - int i = 0; - int src_len = 0; - int glyph_len = 0; - const char *text; - int text_len; - - NK_ASSERT(buffer); - NK_ASSERT(unicode); - NK_ASSERT(len); - - if (!buffer || !unicode || !len) return 0; - if (index < 0) { - *unicode = NK_UTF_INVALID; - *len = 0; - return 0; - } - - text = buffer; - text_len = length; - glyph_len = nk_utf_decode(text, unicode, text_len); - while (glyph_len) { - if (i == index) { - *len = glyph_len; - break; - } - - i++; - src_len = src_len + glyph_len; - glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len); - } - if (i != index) return 0; - return buffer + src_len; -} - -/* ============================================================== - * - * BUFFER - * - * ===============================================================*/ -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_INTERN void* nk_malloc(nk_handle unused, void *old,nk_size size) -{NK_UNUSED(unused); NK_UNUSED(old); return malloc(size);} -NK_INTERN void nk_mfree(nk_handle unused, void *ptr) -{NK_UNUSED(unused); free(ptr);} - -NK_API void -nk_buffer_init_default(struct nk_buffer *buffer) -{ - struct nk_allocator alloc; - alloc.userdata.ptr = 0; - alloc.alloc = nk_malloc; - alloc.free = nk_mfree; - nk_buffer_init(buffer, &alloc, NK_BUFFER_DEFAULT_INITIAL_SIZE); -} -#endif - -NK_API void -nk_buffer_init(struct nk_buffer *b, const struct nk_allocator *a, - nk_size initial_size) -{ - NK_ASSERT(b); - NK_ASSERT(a); - NK_ASSERT(initial_size); - if (!b || !a || !initial_size) return; - - nk_zero(b, sizeof(*b)); - b->type = NK_BUFFER_DYNAMIC; - b->memory.ptr = a->alloc(a->userdata,0, initial_size); - b->memory.size = initial_size; - b->size = initial_size; - b->grow_factor = 2.0f; - b->pool = *a; -} - -NK_API void -nk_buffer_init_fixed(struct nk_buffer *b, void *m, nk_size size) -{ - NK_ASSERT(b); - NK_ASSERT(m); - NK_ASSERT(size); - if (!b || !m || !size) return; - - nk_zero(b, sizeof(*b)); - b->type = NK_BUFFER_FIXED; - b->memory.ptr = m; - b->memory.size = size; - b->size = size; -} - -NK_INTERN void* -nk_buffer_align(void *unaligned, nk_size align, nk_size *alignment, - enum nk_buffer_allocation_type type) -{ - void *memory = 0; - switch (type) { - default: - case NK_BUFFER_MAX: - case NK_BUFFER_FRONT: - if (align) { - memory = NK_ALIGN_PTR(unaligned, align); - *alignment = (nk_size)((nk_byte*)memory - (nk_byte*)unaligned); - } else { - memory = unaligned; - *alignment = 0; - } - break; - case NK_BUFFER_BACK: - if (align) { - memory = NK_ALIGN_PTR_BACK(unaligned, align); - *alignment = (nk_size)((nk_byte*)unaligned - (nk_byte*)memory); - } else { - memory = unaligned; - *alignment = 0; - } - break; - } - return memory; -} - -NK_INTERN void* -nk_buffer_realloc(struct nk_buffer *b, nk_size capacity, nk_size *size) -{ - void *temp; - nk_size buffer_size; - - NK_ASSERT(b); - NK_ASSERT(size); - if (!b || !size || !b->pool.alloc || !b->pool.free) - return 0; - - buffer_size = b->memory.size; - temp = b->pool.alloc(b->pool.userdata, b->memory.ptr, capacity); - NK_ASSERT(temp); - if (!temp) return 0; - - *size = capacity; - if (temp != b->memory.ptr) { - NK_MEMCPY(temp, b->memory.ptr, buffer_size); - b->pool.free(b->pool.userdata, b->memory.ptr); - } - - if (b->size == buffer_size) { - /* no back buffer so just set correct size */ - b->size = capacity; - return temp; - } else { - /* copy back buffer to the end of the new buffer */ - void *dst, *src; - nk_size back_size; - back_size = buffer_size - b->size; - dst = nk_ptr_add(void, temp, capacity - back_size); - src = nk_ptr_add(void, temp, b->size); - NK_MEMCPY(dst, src, back_size); - b->size = capacity - back_size; - } - return temp; -} - -NK_INTERN void* -nk_buffer_alloc(struct nk_buffer *b, enum nk_buffer_allocation_type type, - nk_size size, nk_size align) -{ - int full; - nk_size alignment; - void *unaligned; - void *memory; - - NK_ASSERT(b); - NK_ASSERT(size); - if (!b || !size) return 0; - b->needed += size; - - /* calculate total size with needed alignment + size */ - if (type == NK_BUFFER_FRONT) - unaligned = nk_ptr_add(void, b->memory.ptr, b->allocated); - else unaligned = nk_ptr_add(void, b->memory.ptr, b->size - size); - memory = nk_buffer_align(unaligned, align, &alignment, type); - - /* check if buffer has enough memory*/ - if (type == NK_BUFFER_FRONT) - full = ((b->allocated + size + alignment) > b->size); - else full = ((b->size - (size + alignment)) <= b->allocated); - - if (full) { - nk_size capacity; - NK_ASSERT(b->type == NK_BUFFER_DYNAMIC); - NK_ASSERT(b->pool.alloc && b->pool.free); - if (b->type != NK_BUFFER_DYNAMIC || !b->pool.alloc || !b->pool.free) - return 0; - - /* buffer is full so allocate bigger buffer if dynamic */ - capacity = (nk_size)((float)b->memory.size * b->grow_factor); - capacity = NK_MAX(capacity, nk_round_up_pow2((nk_uint)(b->allocated + size))); - b->memory.ptr = nk_buffer_realloc(b, capacity, &b->memory.size); - if (!b->memory.ptr) return 0; - - /* align newly allocated pointer */ - if (type == NK_BUFFER_FRONT) - unaligned = nk_ptr_add(void, b->memory.ptr, b->allocated); - else unaligned = nk_ptr_add(void, b->memory.ptr, b->size - size); - memory = nk_buffer_align(unaligned, align, &alignment, type); - } - - if (type == NK_BUFFER_FRONT) - b->allocated += size + alignment; - else b->size -= (size + alignment); - b->needed += alignment; - b->calls++; - return memory; -} - -NK_API void -nk_buffer_push(struct nk_buffer *b, enum nk_buffer_allocation_type type, - const void *memory, nk_size size, nk_size align) -{ - void *mem = nk_buffer_alloc(b, type, size, align); - if (!mem) return; - NK_MEMCPY(mem, memory, size); -} - -NK_API void -nk_buffer_mark(struct nk_buffer *buffer, enum nk_buffer_allocation_type type) -{ - NK_ASSERT(buffer); - if (!buffer) return; - buffer->marker[type].active = nk_true; - if (type == NK_BUFFER_BACK) - buffer->marker[type].offset = buffer->size; - else buffer->marker[type].offset = buffer->allocated; -} - -NK_API void -nk_buffer_reset(struct nk_buffer *buffer, enum nk_buffer_allocation_type type) -{ - NK_ASSERT(buffer); - if (!buffer) return; - if (type == NK_BUFFER_BACK) { - /* reset back buffer either back to marker or empty */ - buffer->needed -= (buffer->memory.size - buffer->marker[type].offset); - if (buffer->marker[type].active) - buffer->size = buffer->marker[type].offset; - else buffer->size = buffer->memory.size; - buffer->marker[type].active = nk_false; - } else { - /* reset front buffer either back to back marker or empty */ - buffer->needed -= (buffer->allocated - buffer->marker[type].offset); - if (buffer->marker[type].active) - buffer->allocated = buffer->marker[type].offset; - else buffer->allocated = 0; - buffer->marker[type].active = nk_false; - } -} - -NK_API void -nk_buffer_clear(struct nk_buffer *b) -{ - NK_ASSERT(b); - if (!b) return; - b->allocated = 0; - b->size = b->memory.size; - b->calls = 0; - b->needed = 0; -} - -NK_API void -nk_buffer_free(struct nk_buffer *b) -{ - NK_ASSERT(b); - if (!b || !b->memory.ptr) return; - if (b->type == NK_BUFFER_FIXED) return; - if (!b->pool.free) return; - NK_ASSERT(b->pool.free); - b->pool.free(b->pool.userdata, b->memory.ptr); -} - -NK_API void -nk_buffer_info(struct nk_memory_status *s, struct nk_buffer *b) -{ - NK_ASSERT(b); - NK_ASSERT(s); - if (!s || !b) return; - s->allocated = b->allocated; - s->size = b->memory.size; - s->needed = b->needed; - s->memory = b->memory.ptr; - s->calls = b->calls; -} - -NK_API void* -nk_buffer_memory(struct nk_buffer *buffer) -{ - NK_ASSERT(buffer); - if (!buffer) return 0; - return buffer->memory.ptr; -} - -NK_API const void* -nk_buffer_memory_const(const struct nk_buffer *buffer) -{ - NK_ASSERT(buffer); - if (!buffer) return 0; - return buffer->memory.ptr; -} - -NK_API nk_size -nk_buffer_total(struct nk_buffer *buffer) -{ - NK_ASSERT(buffer); - if (!buffer) return 0; - return buffer->memory.size; -} - -/* - * ============================================================== - * - * STRING - * - * =============================================================== - */ -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_API void -nk_str_init_default(struct nk_str *str) -{ - struct nk_allocator alloc; - alloc.userdata.ptr = 0; - alloc.alloc = nk_malloc; - alloc.free = nk_mfree; - nk_buffer_init(&str->buffer, &alloc, 32); - str->len = 0; -} -#endif - -NK_API void -nk_str_init(struct nk_str *str, const struct nk_allocator *alloc, nk_size size) -{ - nk_buffer_init(&str->buffer, alloc, size); - str->len = 0; -} - -NK_API void -nk_str_init_fixed(struct nk_str *str, void *memory, nk_size size) -{ - nk_buffer_init_fixed(&str->buffer, memory, size); - str->len = 0; -} - -NK_API int -nk_str_append_text_char(struct nk_str *s, const char *str, int len) -{ - char *mem; - NK_ASSERT(s); - NK_ASSERT(str); - if (!s || !str || !len) return 0; - mem = (char*)nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len * sizeof(char), 0); - if (!mem) return 0; - NK_MEMCPY(mem, str, (nk_size)len * sizeof(char)); - s->len += nk_utf_len(str, len); - return len; -} - -NK_API int -nk_str_append_str_char(struct nk_str *s, const char *str) -{ - return nk_str_append_text_char(s, str, nk_strlen(str)); -} - -NK_API int -nk_str_append_text_utf8(struct nk_str *str, const char *text, int len) -{ - int i = 0; - int byte_len = 0; - nk_rune unicode; - if (!str || !text || !len) return 0; - for (i = 0; i < len; ++i) - byte_len += nk_utf_decode(text+byte_len, &unicode, 4); - nk_str_append_text_char(str, text, byte_len); - return len; -} - -NK_API int -nk_str_append_str_utf8(struct nk_str *str, const char *text) -{ - int runes = 0; - int byte_len = 0; - int num_runes = 0; - int glyph_len = 0; - nk_rune unicode; - if (!str || !text) return 0; - - glyph_len = byte_len = nk_utf_decode(text+byte_len, &unicode, 4); - while (unicode != '\0' && glyph_len) { - glyph_len = nk_utf_decode(text+byte_len, &unicode, 4); - byte_len += glyph_len; - num_runes++; - } - nk_str_append_text_char(str, text, byte_len); - return runes; -} - -NK_API int -nk_str_append_text_runes(struct nk_str *str, const nk_rune *text, int len) -{ - int i = 0; - int byte_len = 0; - nk_glyph glyph; - - NK_ASSERT(str); - if (!str || !text || !len) return 0; - for (i = 0; i < len; ++i) { - byte_len = nk_utf_encode(text[i], glyph, NK_UTF_SIZE); - if (!byte_len) break; - nk_str_append_text_char(str, glyph, byte_len); - } - return len; -} - -NK_API int -nk_str_append_str_runes(struct nk_str *str, const nk_rune *runes) -{ - int i = 0; - nk_glyph glyph; - int byte_len; - NK_ASSERT(str); - if (!str || !runes) return 0; - while (runes[i] != '\0') { - byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE); - nk_str_append_text_char(str, glyph, byte_len); - i++; - } - return i; -} - -NK_API int -nk_str_insert_at_char(struct nk_str *s, int pos, const char *str, int len) -{ - int i; - void *mem; - char *src; - char *dst; - - int copylen; - NK_ASSERT(s); - NK_ASSERT(str); - NK_ASSERT(len >= 0); - if (!s || !str || !len || (nk_size)pos > s->buffer.allocated) return 0; - if ((s->buffer.allocated + (nk_size)len >= s->buffer.memory.size) && - (s->buffer.type == NK_BUFFER_FIXED)) return 0; - - copylen = (int)s->buffer.allocated - pos; - if (!copylen) { - nk_str_append_text_char(s, str, len); - return 1; - } - mem = nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len * sizeof(char), 0); - if (!mem) return 0; - - /* memmove */ - NK_ASSERT(((int)pos + (int)len + ((int)copylen - 1)) >= 0); - NK_ASSERT(((int)pos + ((int)copylen - 1)) >= 0); - dst = nk_ptr_add(char, s->buffer.memory.ptr, pos + len + (copylen - 1)); - src = nk_ptr_add(char, s->buffer.memory.ptr, pos + (copylen-1)); - for (i = 0; i < copylen; ++i) *dst-- = *src--; - mem = nk_ptr_add(void, s->buffer.memory.ptr, pos); - NK_MEMCPY(mem, str, (nk_size)len * sizeof(char)); - s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated); - return 1; -} - -NK_API int -nk_str_insert_at_rune(struct nk_str *str, int pos, const char *cstr, int len) -{ - int glyph_len; - nk_rune unicode; - const char *begin; - const char *buffer; - - NK_ASSERT(str); - NK_ASSERT(cstr); - NK_ASSERT(len); - if (!str || !cstr || !len) return 0; - begin = nk_str_at_rune(str, pos, &unicode, &glyph_len); - if (!str->len) - return nk_str_append_text_char(str, cstr, len); - buffer = nk_str_get_const(str); - if (!begin) return 0; - return nk_str_insert_at_char(str, (int)(begin - buffer), cstr, len); -} - -NK_API int -nk_str_insert_text_char(struct nk_str *str, int pos, const char *text, int len) -{ - return nk_str_insert_text_utf8(str, pos, text, len); -} - -NK_API int -nk_str_insert_str_char(struct nk_str *str, int pos, const char *text) -{ - return nk_str_insert_text_utf8(str, pos, text, nk_strlen(text)); -} - -NK_API int -nk_str_insert_text_utf8(struct nk_str *str, int pos, const char *text, int len) -{ - int i = 0; - int byte_len = 0; - nk_rune unicode; - - NK_ASSERT(str); - NK_ASSERT(text); - if (!str || !text || !len) return 0; - for (i = 0; i < len; ++i) - byte_len += nk_utf_decode(text+byte_len, &unicode, 4); - nk_str_insert_at_rune(str, pos, text, byte_len); - return len; -} - -NK_API int -nk_str_insert_str_utf8(struct nk_str *str, int pos, const char *text) -{ - int runes = 0; - int byte_len = 0; - int num_runes = 0; - int glyph_len = 0; - nk_rune unicode; - if (!str || !text) return 0; - - glyph_len = byte_len = nk_utf_decode(text+byte_len, &unicode, 4); - while (unicode != '\0' && glyph_len) { - glyph_len = nk_utf_decode(text+byte_len, &unicode, 4); - byte_len += glyph_len; - num_runes++; - } - nk_str_insert_at_rune(str, pos, text, byte_len); - return runes; -} - -NK_API int -nk_str_insert_text_runes(struct nk_str *str, int pos, const nk_rune *runes, int len) -{ - int i = 0; - int byte_len = 0; - nk_glyph glyph; - - NK_ASSERT(str); - if (!str || !runes || !len) return 0; - for (i = 0; i < len; ++i) { - byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE); - if (!byte_len) break; - nk_str_insert_at_rune(str, pos+i, glyph, byte_len); - } - return len; -} - -NK_API int -nk_str_insert_str_runes(struct nk_str *str, int pos, const nk_rune *runes) -{ - int i = 0; - nk_glyph glyph; - int byte_len; - NK_ASSERT(str); - if (!str || !runes) return 0; - while (runes[i] != '\0') { - byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE); - nk_str_insert_at_rune(str, pos+i, glyph, byte_len); - i++; - } - return i; -} - -NK_API void -nk_str_remove_chars(struct nk_str *s, int len) -{ - NK_ASSERT(s); - NK_ASSERT(len >= 0); - if (!s || len < 0 || (nk_size)len > s->buffer.allocated) return; - NK_ASSERT(((int)s->buffer.allocated - (int)len) >= 0); - s->buffer.allocated -= (nk_size)len; - s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated); -} - -NK_API void -nk_str_remove_runes(struct nk_str *str, int len) -{ - int index; - const char *begin; - const char *end; - nk_rune unicode; - - NK_ASSERT(str); - NK_ASSERT(len >= 0); - if (!str || len < 0) return; - if (len >= str->len) { - str->len = 0; - return; - } - - index = str->len - len; - begin = nk_str_at_rune(str, index, &unicode, &len); - end = (const char*)str->buffer.memory.ptr + str->buffer.allocated; - nk_str_remove_chars(str, (int)(end-begin)+1); -} - -NK_API void -nk_str_delete_chars(struct nk_str *s, int pos, int len) -{ - NK_ASSERT(s); - if (!s || !len || (nk_size)pos > s->buffer.allocated || - (nk_size)(pos + len) > s->buffer.allocated) return; - - if ((nk_size)(pos + len) < s->buffer.allocated) { - /* memmove */ - char *dst = nk_ptr_add(char, s->buffer.memory.ptr, pos); - char *src = nk_ptr_add(char, s->buffer.memory.ptr, pos + len); - NK_MEMCPY(dst, src, s->buffer.allocated - (nk_size)(pos + len)); - NK_ASSERT(((int)s->buffer.allocated - (int)len) >= 0); - s->buffer.allocated -= (nk_size)len; - } else nk_str_remove_chars(s, len); - s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated); -} - -NK_API void -nk_str_delete_runes(struct nk_str *s, int pos, int len) -{ - char *temp; - nk_rune unicode; - char *begin; - char *end; - int unused; - - NK_ASSERT(s); - NK_ASSERT(s->len >= pos + len); - if (s->len < pos + len) - len = NK_CLAMP(0, (s->len - pos), s->len); - if (!len) return; - - temp = (char *)s->buffer.memory.ptr; - begin = nk_str_at_rune(s, pos, &unicode, &unused); - if (!begin) return; - s->buffer.memory.ptr = begin; - end = nk_str_at_rune(s, len, &unicode, &unused); - s->buffer.memory.ptr = temp; - if (!end) return; - nk_str_delete_chars(s, (int)(begin - temp), (int)(end - begin)); -} - -NK_API char* -nk_str_at_char(struct nk_str *s, int pos) -{ - NK_ASSERT(s); - if (!s || pos > (int)s->buffer.allocated) return 0; - return nk_ptr_add(char, s->buffer.memory.ptr, pos); -} - -NK_API char* -nk_str_at_rune(struct nk_str *str, int pos, nk_rune *unicode, int *len) -{ - int i = 0; - int src_len = 0; - int glyph_len = 0; - char *text; - int text_len; - - NK_ASSERT(str); - NK_ASSERT(unicode); - NK_ASSERT(len); - - if (!str || !unicode || !len) return 0; - if (pos < 0) { - *unicode = 0; - *len = 0; - return 0; - } - - text = (char*)str->buffer.memory.ptr; - text_len = (int)str->buffer.allocated; - glyph_len = nk_utf_decode(text, unicode, text_len); - while (glyph_len) { - if (i == pos) { - *len = glyph_len; - break; - } - - i++; - src_len = src_len + glyph_len; - glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len); - } - if (i != pos) return 0; - return text + src_len; -} - -NK_API const char* -nk_str_at_char_const(const struct nk_str *s, int pos) -{ - NK_ASSERT(s); - if (!s || pos > (int)s->buffer.allocated) return 0; - return nk_ptr_add(char, s->buffer.memory.ptr, pos); -} - -NK_API const char* -nk_str_at_const(const struct nk_str *str, int pos, nk_rune *unicode, int *len) -{ - int i = 0; - int src_len = 0; - int glyph_len = 0; - char *text; - int text_len; - - NK_ASSERT(str); - NK_ASSERT(unicode); - NK_ASSERT(len); - - if (!str || !unicode || !len) return 0; - if (pos < 0) { - *unicode = 0; - *len = 0; - return 0; - } - - text = (char*)str->buffer.memory.ptr; - text_len = (int)str->buffer.allocated; - glyph_len = nk_utf_decode(text, unicode, text_len); - while (glyph_len) { - if (i == pos) { - *len = glyph_len; - break; - } - - i++; - src_len = src_len + glyph_len; - glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len); - } - if (i != pos) return 0; - return text + src_len; -} - -NK_API nk_rune -nk_str_rune_at(const struct nk_str *str, int pos) -{ - int len; - nk_rune unicode = 0; - nk_str_at_const(str, pos, &unicode, &len); - return unicode; -} - -NK_API char* -nk_str_get(struct nk_str *s) -{ - NK_ASSERT(s); - if (!s || !s->len || !s->buffer.allocated) return 0; - return (char*)s->buffer.memory.ptr; -} - -NK_API const char* -nk_str_get_const(const struct nk_str *s) -{ - NK_ASSERT(s); - if (!s || !s->len || !s->buffer.allocated) return 0; - return (const char*)s->buffer.memory.ptr; -} - -NK_API int -nk_str_len(struct nk_str *s) -{ - NK_ASSERT(s); - if (!s || !s->len || !s->buffer.allocated) return 0; - return s->len; -} - -NK_API int -nk_str_len_char(struct nk_str *s) -{ - NK_ASSERT(s); - if (!s || !s->len || !s->buffer.allocated) return 0; - return (int)s->buffer.allocated; -} - -NK_API void -nk_str_clear(struct nk_str *str) -{ - NK_ASSERT(str); - nk_buffer_clear(&str->buffer); - str->len = 0; -} - -NK_API void -nk_str_free(struct nk_str *str) -{ - NK_ASSERT(str); - nk_buffer_free(&str->buffer); - str->len = 0; -} - -/* - * ============================================================== - * - * Command buffer - * - * =============================================================== -*/ -NK_INTERN void -nk_command_buffer_init(struct nk_command_buffer *cmdbuf, - struct nk_buffer *buffer, enum nk_command_clipping clip) -{ - NK_ASSERT(cmdbuf); - NK_ASSERT(buffer); - if (!cmdbuf || !buffer) return; - cmdbuf->base = buffer; - cmdbuf->use_clipping = clip; - cmdbuf->begin = buffer->allocated; - cmdbuf->end = buffer->allocated; - cmdbuf->last = buffer->allocated; -} - -NK_INTERN void -nk_command_buffer_reset(struct nk_command_buffer *buffer) -{ - NK_ASSERT(buffer); - if (!buffer) return; - buffer->begin = 0; - buffer->end = 0; - buffer->last = 0; - buffer->clip = nk_null_rect; -#ifdef NK_INCLUDE_COMMAND_USERDATA - buffer->userdata.ptr = 0; -#endif -} - -NK_INTERN void* -nk_command_buffer_push(struct nk_command_buffer* b, - enum nk_command_type t, nk_size size) -{ - NK_STORAGE const nk_size align = NK_ALIGNOF(struct nk_command); - struct nk_command *cmd; - nk_size alignment; - void *unaligned; - void *memory; - - NK_ASSERT(b); - NK_ASSERT(b->base); - if (!b) return 0; - cmd = (struct nk_command*)nk_buffer_alloc(b->base,NK_BUFFER_FRONT,size,align); - if (!cmd) return 0; - - /* make sure the offset to the next command is aligned */ - b->last = (nk_size)((nk_byte*)cmd - (nk_byte*)b->base->memory.ptr); - unaligned = (nk_byte*)cmd + size; - memory = NK_ALIGN_PTR(unaligned, align); - alignment = (nk_size)((nk_byte*)memory - (nk_byte*)unaligned); -#ifdef NK_ZERO_COMMAND_MEMORY - NK_MEMSET(cmd, 0, size + alignment); -#endif - - cmd->type = t; - cmd->next = b->base->allocated + alignment; -#ifdef NK_INCLUDE_COMMAND_USERDATA - cmd->userdata = b->userdata; -#endif - b->end = cmd->next; - return cmd; -} - -NK_API void -nk_push_scissor(struct nk_command_buffer *b, struct nk_rect r) -{ - struct nk_command_scissor *cmd; - NK_ASSERT(b); - if (!b) return; - - b->clip.x = r.x; - b->clip.y = r.y; - b->clip.w = r.w; - b->clip.h = r.h; - cmd = (struct nk_command_scissor*) - nk_command_buffer_push(b, NK_COMMAND_SCISSOR, sizeof(*cmd)); - - if (!cmd) return; - cmd->x = (short)r.x; - cmd->y = (short)r.y; - cmd->w = (unsigned short)NK_MAX(0, r.w); - cmd->h = (unsigned short)NK_MAX(0, r.h); -} - -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 c) -{ - struct nk_command_line *cmd; - NK_ASSERT(b); - if (!b) return; - cmd = (struct nk_command_line*) - nk_command_buffer_push(b, NK_COMMAND_LINE, sizeof(*cmd)); - if (!cmd) return; - cmd->line_thickness = (unsigned short)line_thickness; - cmd->begin.x = (short)x0; - cmd->begin.y = (short)y0; - cmd->end.x = (short)x1; - cmd->end.y = (short)y1; - cmd->color = c; -} - -NK_API void -nk_stroke_curve(struct nk_command_buffer *b, float ax, float ay, - float ctrl0x, float ctrl0y, float ctrl1x, float ctrl1y, - float bx, float by, float line_thickness, struct nk_color col) -{ - struct nk_command_curve *cmd; - NK_ASSERT(b); - if (!b || col.a == 0) return; - - cmd = (struct nk_command_curve*) - nk_command_buffer_push(b, NK_COMMAND_CURVE, sizeof(*cmd)); - if (!cmd) return; - cmd->line_thickness = (unsigned short)line_thickness; - cmd->begin.x = (short)ax; - cmd->begin.y = (short)ay; - cmd->ctrl[0].x = (short)ctrl0x; - cmd->ctrl[0].y = (short)ctrl0y; - cmd->ctrl[1].x = (short)ctrl1x; - cmd->ctrl[1].y = (short)ctrl1y; - cmd->end.x = (short)bx; - cmd->end.y = (short)by; - cmd->color = col; -} - -NK_API void -nk_stroke_rect(struct nk_command_buffer *b, struct nk_rect rect, - float rounding, float line_thickness, struct nk_color c) -{ - struct nk_command_rect *cmd; - NK_ASSERT(b); - if (!b || c.a == 0 || rect.w == 0 || rect.h == 0) return; - if (b->use_clipping) { - const struct nk_rect *clip = &b->clip; - if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h, - clip->x, clip->y, clip->w, clip->h)) return; - } - - cmd = (struct nk_command_rect*) - nk_command_buffer_push(b, NK_COMMAND_RECT, sizeof(*cmd)); - if (!cmd) return; - cmd->rounding = (unsigned short)rounding; - cmd->line_thickness = (unsigned short)line_thickness; - cmd->x = (short)rect.x; - cmd->y = (short)rect.y; - cmd->w = (unsigned short)NK_MAX(0, rect.w); - cmd->h = (unsigned short)NK_MAX(0, rect.h); - cmd->color = c; -} - -NK_API void -nk_fill_rect(struct nk_command_buffer *b, struct nk_rect rect, - float rounding, struct nk_color c) -{ - struct nk_command_rect_filled *cmd; - NK_ASSERT(b); - if (!b || c.a == 0 || rect.w == 0 || rect.h == 0) return; - if (b->use_clipping) { - const struct nk_rect *clip = &b->clip; - if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h, - clip->x, clip->y, clip->w, clip->h)) return; - } - - cmd = (struct nk_command_rect_filled*) - nk_command_buffer_push(b, NK_COMMAND_RECT_FILLED, sizeof(*cmd)); - if (!cmd) return; - cmd->rounding = (unsigned short)rounding; - cmd->x = (short)rect.x; - cmd->y = (short)rect.y; - cmd->w = (unsigned short)NK_MAX(0, rect.w); - cmd->h = (unsigned short)NK_MAX(0, rect.h); - cmd->color = c; -} - -NK_API void -nk_fill_rect_multi_color(struct nk_command_buffer *b, struct nk_rect rect, - struct nk_color left, struct nk_color top, struct nk_color right, - struct nk_color bottom) -{ - struct nk_command_rect_multi_color *cmd; - NK_ASSERT(b); - if (!b || rect.w == 0 || rect.h == 0) return; - if (b->use_clipping) { - const struct nk_rect *clip = &b->clip; - if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h, - clip->x, clip->y, clip->w, clip->h)) return; - } - - cmd = (struct nk_command_rect_multi_color*) - nk_command_buffer_push(b, NK_COMMAND_RECT_MULTI_COLOR, sizeof(*cmd)); - if (!cmd) return; - cmd->x = (short)rect.x; - cmd->y = (short)rect.y; - cmd->w = (unsigned short)NK_MAX(0, rect.w); - cmd->h = (unsigned short)NK_MAX(0, rect.h); - cmd->left = left; - cmd->top = top; - cmd->right = right; - cmd->bottom = bottom; -} - -NK_API void -nk_stroke_circle(struct nk_command_buffer *b, struct nk_rect r, - float line_thickness, struct nk_color c) -{ - struct nk_command_circle *cmd; - if (!b || r.w == 0 || r.h == 0) return; - if (b->use_clipping) { - const struct nk_rect *clip = &b->clip; - if (!NK_INTERSECT(r.x, r.y, r.w, r.h, clip->x, clip->y, clip->w, clip->h)) - return; - } - - cmd = (struct nk_command_circle*) - nk_command_buffer_push(b, NK_COMMAND_CIRCLE, sizeof(*cmd)); - if (!cmd) return; - cmd->line_thickness = (unsigned short)line_thickness; - cmd->x = (short)r.x; - cmd->y = (short)r.y; - cmd->w = (unsigned short)NK_MAX(r.w, 0); - cmd->h = (unsigned short)NK_MAX(r.h, 0); - cmd->color = c; -} - -NK_API void -nk_fill_circle(struct nk_command_buffer *b, struct nk_rect r, struct nk_color c) -{ - struct nk_command_circle_filled *cmd; - NK_ASSERT(b); - if (!b || c.a == 0 || r.w == 0 || r.h == 0) return; - if (b->use_clipping) { - const struct nk_rect *clip = &b->clip; - if (!NK_INTERSECT(r.x, r.y, r.w, r.h, clip->x, clip->y, clip->w, clip->h)) - return; - } - - cmd = (struct nk_command_circle_filled*) - nk_command_buffer_push(b, NK_COMMAND_CIRCLE_FILLED, sizeof(*cmd)); - if (!cmd) return; - cmd->x = (short)r.x; - cmd->y = (short)r.y; - cmd->w = (unsigned short)NK_MAX(r.w, 0); - cmd->h = (unsigned short)NK_MAX(r.h, 0); - cmd->color = c; -} - -NK_API void -nk_stroke_arc(struct nk_command_buffer *b, float cx, float cy, float radius, - float a_min, float a_max, float line_thickness, struct nk_color c) -{ - struct nk_command_arc *cmd; - if (!b || c.a == 0) return; - cmd = (struct nk_command_arc*) - nk_command_buffer_push(b, NK_COMMAND_ARC, sizeof(*cmd)); - if (!cmd) return; - cmd->line_thickness = (unsigned short)line_thickness; - cmd->cx = (short)cx; - cmd->cy = (short)cy; - cmd->r = (unsigned short)radius; - cmd->a[0] = a_min; - cmd->a[1] = a_max; - cmd->color = c; -} - -NK_API void -nk_fill_arc(struct nk_command_buffer *b, float cx, float cy, float radius, - float a_min, float a_max, struct nk_color c) -{ - struct nk_command_arc_filled *cmd; - NK_ASSERT(b); - if (!b || c.a == 0) return; - cmd = (struct nk_command_arc_filled*) - nk_command_buffer_push(b, NK_COMMAND_ARC_FILLED, sizeof(*cmd)); - if (!cmd) return; - cmd->cx = (short)cx; - cmd->cy = (short)cy; - cmd->r = (unsigned short)radius; - cmd->a[0] = a_min; - cmd->a[1] = a_max; - cmd->color = c; -} - -NK_API void -nk_stroke_triangle(struct nk_command_buffer *b, float x0, float y0, float x1, - float y1, float x2, float y2, float line_thickness, struct nk_color c) -{ - struct nk_command_triangle *cmd; - NK_ASSERT(b); - if (!b || c.a == 0) return; - if (b->use_clipping) { - const struct nk_rect *clip = &b->clip; - if (!NK_INBOX(x0, y0, clip->x, clip->y, clip->w, clip->h) && - !NK_INBOX(x1, y1, clip->x, clip->y, clip->w, clip->h) && - !NK_INBOX(x2, y2, clip->x, clip->y, clip->w, clip->h)) - return; - } - - cmd = (struct nk_command_triangle*) - nk_command_buffer_push(b, NK_COMMAND_TRIANGLE, sizeof(*cmd)); - if (!cmd) return; - cmd->line_thickness = (unsigned short)line_thickness; - cmd->a.x = (short)x0; - cmd->a.y = (short)y0; - cmd->b.x = (short)x1; - cmd->b.y = (short)y1; - cmd->c.x = (short)x2; - cmd->c.y = (short)y2; - cmd->color = c; -} - -NK_API void -nk_fill_triangle(struct nk_command_buffer *b, float x0, float y0, float x1, - float y1, float x2, float y2, struct nk_color c) -{ - struct nk_command_triangle_filled *cmd; - NK_ASSERT(b); - if (!b || c.a == 0) return; - if (!b) return; - if (b->use_clipping) { - const struct nk_rect *clip = &b->clip; - if (!NK_INBOX(x0, y0, clip->x, clip->y, clip->w, clip->h) && - !NK_INBOX(x1, y1, clip->x, clip->y, clip->w, clip->h) && - !NK_INBOX(x2, y2, clip->x, clip->y, clip->w, clip->h)) - return; - } - - cmd = (struct nk_command_triangle_filled*) - nk_command_buffer_push(b, NK_COMMAND_TRIANGLE_FILLED, sizeof(*cmd)); - if (!cmd) return; - cmd->a.x = (short)x0; - cmd->a.y = (short)y0; - cmd->b.x = (short)x1; - cmd->b.y = (short)y1; - cmd->c.x = (short)x2; - cmd->c.y = (short)y2; - cmd->color = c; -} - -NK_API void -nk_stroke_polygon(struct nk_command_buffer *b, float *points, int point_count, - float line_thickness, struct nk_color col) -{ - int i; - nk_size size = 0; - struct nk_command_polygon *cmd; - - NK_ASSERT(b); - if (!b || col.a == 0) return; - size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count; - cmd = (struct nk_command_polygon*) nk_command_buffer_push(b, NK_COMMAND_POLYGON, size); - if (!cmd) return; - cmd->color = col; - cmd->line_thickness = (unsigned short)line_thickness; - cmd->point_count = (unsigned short)point_count; - for (i = 0; i < point_count; ++i) { - cmd->points[i].x = (short)points[i*2]; - cmd->points[i].y = (short)points[i*2+1]; - } -} - -NK_API void -nk_fill_polygon(struct nk_command_buffer *b, float *points, int point_count, - struct nk_color col) -{ - int i; - nk_size size = 0; - struct nk_command_polygon_filled *cmd; - - NK_ASSERT(b); - if (!b || col.a == 0) return; - size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count; - cmd = (struct nk_command_polygon_filled*) - nk_command_buffer_push(b, NK_COMMAND_POLYGON_FILLED, size); - if (!cmd) return; - cmd->color = col; - cmd->point_count = (unsigned short)point_count; - for (i = 0; i < point_count; ++i) { - cmd->points[i].x = (short)points[i*2+0]; - cmd->points[i].y = (short)points[i*2+1]; - } -} - -NK_API void -nk_stroke_polyline(struct nk_command_buffer *b, float *points, int point_count, - float line_thickness, struct nk_color col) -{ - int i; - nk_size size = 0; - struct nk_command_polyline *cmd; - - NK_ASSERT(b); - if (!b || col.a == 0) return; - size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count; - cmd = (struct nk_command_polyline*) nk_command_buffer_push(b, NK_COMMAND_POLYLINE, size); - if (!cmd) return; - cmd->color = col; - cmd->point_count = (unsigned short)point_count; - cmd->line_thickness = (unsigned short)line_thickness; - for (i = 0; i < point_count; ++i) { - cmd->points[i].x = (short)points[i*2]; - cmd->points[i].y = (short)points[i*2+1]; - } -} - -NK_API void -nk_draw_image(struct nk_command_buffer *b, struct nk_rect r, - const struct nk_image *img, struct nk_color col) -{ - struct nk_command_image *cmd; - NK_ASSERT(b); - if (!b) return; - if (b->use_clipping) { - const struct nk_rect *c = &b->clip; - 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)) - return; - } - - cmd = (struct nk_command_image*) - nk_command_buffer_push(b, NK_COMMAND_IMAGE, sizeof(*cmd)); - if (!cmd) return; - cmd->x = (short)r.x; - cmd->y = (short)r.y; - cmd->w = (unsigned short)NK_MAX(0, r.w); - cmd->h = (unsigned short)NK_MAX(0, r.h); - cmd->img = *img; - cmd->col = col; -} - -NK_API void -nk_draw_text(struct nk_command_buffer *b, struct nk_rect r, - const char *string, int length, const struct nk_user_font *font, - struct nk_color bg, struct nk_color fg) -{ - float text_width = 0; - struct nk_command_text *cmd; - - NK_ASSERT(b); - NK_ASSERT(font); - if (!b || !string || !length || (bg.a == 0 && fg.a == 0)) return; - if (b->use_clipping) { - const struct nk_rect *c = &b->clip; - 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)) - return; - } - - /* make sure text fits inside bounds */ - text_width = font->width(font->userdata, font->height, string, length); - if (text_width > r.w){ - int glyphs = 0; - float txt_width = (float)text_width; - length = nk_text_clamp(font, string, length, r.w, &glyphs, &txt_width, 0,0); - } - - if (!length) return; - cmd = (struct nk_command_text*) - nk_command_buffer_push(b, NK_COMMAND_TEXT, sizeof(*cmd) + (nk_size)(length + 1)); - if (!cmd) return; - cmd->x = (short)r.x; - cmd->y = (short)r.y; - cmd->w = (unsigned short)r.w; - cmd->h = (unsigned short)r.h; - cmd->background = bg; - cmd->foreground = fg; - cmd->font = font; - cmd->length = length; - cmd->height = font->height; - NK_MEMCPY(cmd->string, string, (nk_size)length); - cmd->string[length] = '\0'; -} - -/* ============================================================== - * - * DRAW LIST - * - * ===============================================================*/ -#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT -NK_API void -nk_draw_list_init(struct nk_draw_list *list) -{ - nk_size i = 0; - NK_ASSERT(list); - if (!list) return; - nk_zero(list, sizeof(*list)); - for (i = 0; i < NK_LEN(list->circle_vtx); ++i) { - const float a = ((float)i / (float)NK_LEN(list->circle_vtx)) * 2 * NK_PI; - list->circle_vtx[i].x = (float)NK_COS(a); - list->circle_vtx[i].y = (float)NK_SIN(a); - } -} - -NK_API void -nk_draw_list_setup(struct nk_draw_list *canvas, const struct nk_convert_config *config, - struct nk_buffer *cmds, struct nk_buffer *vertices, struct nk_buffer *elements) -{ - NK_ASSERT(canvas); - NK_ASSERT(config); - NK_ASSERT(cmds); - NK_ASSERT(vertices); - NK_ASSERT(elements); - if (!canvas || !config || !cmds || !vertices || !elements) - return; - - canvas->buffer = cmds; - canvas->config = *config; - canvas->elements = elements; - canvas->vertices = vertices; - canvas->clip_rect = nk_null_rect; -} - -NK_API const struct nk_draw_command* -nk__draw_list_begin(const struct nk_draw_list *canvas, const struct nk_buffer *buffer) -{ - nk_byte *memory; - nk_size offset; - const struct nk_draw_command *cmd; - - NK_ASSERT(buffer); - if (!buffer || !buffer->size || !canvas->cmd_count) - return 0; - - memory = (nk_byte*)buffer->memory.ptr; - offset = buffer->memory.size - canvas->cmd_offset; - cmd = nk_ptr_add(const struct nk_draw_command, memory, offset); - return cmd; -} - -NK_API const struct nk_draw_command* -nk__draw_list_end(const struct nk_draw_list *canvas, const struct nk_buffer *buffer) -{ - nk_size size; - nk_size offset; - nk_byte *memory; - const struct nk_draw_command *end; - - NK_ASSERT(buffer); - NK_ASSERT(canvas); - if (!buffer || !canvas) - return 0; - - memory = (nk_byte*)buffer->memory.ptr; - size = buffer->memory.size; - offset = size - canvas->cmd_offset; - end = nk_ptr_add(const struct nk_draw_command, memory, offset); - end -= (canvas->cmd_count-1); - return end; -} - -NK_API const struct nk_draw_command* -nk__draw_list_next(const struct nk_draw_command *cmd, - const struct nk_buffer *buffer, const struct nk_draw_list *canvas) -{ - const struct nk_draw_command *end; - NK_ASSERT(buffer); - NK_ASSERT(canvas); - if (!cmd || !buffer || !canvas) - return 0; - - end = nk__draw_list_end(canvas, buffer); - if (cmd <= end) return 0; - return (cmd-1); -} - -NK_API void -nk_draw_list_clear(struct nk_draw_list *list) -{ - NK_ASSERT(list); - if (!list) return; - if (list->buffer) - nk_buffer_clear(list->buffer); - if (list->vertices) - nk_buffer_clear(list->vertices); - if (list->elements) - nk_buffer_clear(list->elements); - - list->element_count = 0; - list->vertex_count = 0; - list->cmd_offset = 0; - list->cmd_count = 0; - list->path_count = 0; - list->vertices = 0; - list->elements = 0; - list->clip_rect = nk_null_rect; -} - -NK_INTERN struct nk_vec2* -nk_draw_list_alloc_path(struct nk_draw_list *list, int count) -{ - struct nk_vec2 *points; - NK_STORAGE const nk_size point_align = NK_ALIGNOF(struct nk_vec2); - NK_STORAGE const nk_size point_size = sizeof(struct nk_vec2); - points = (struct nk_vec2*) - nk_buffer_alloc(list->buffer, NK_BUFFER_FRONT, - point_size * (nk_size)count, point_align); - - if (!points) return 0; - if (!list->path_offset) { - void *memory = nk_buffer_memory(list->buffer); - list->path_offset = (unsigned int)((nk_byte*)points - (nk_byte*)memory); - } - list->path_count += (unsigned int)count; - return points; -} - -NK_INTERN struct nk_vec2 -nk_draw_list_path_last(struct nk_draw_list *list) -{ - void *memory; - struct nk_vec2 *point; - NK_ASSERT(list->path_count); - memory = nk_buffer_memory(list->buffer); - point = nk_ptr_add(struct nk_vec2, memory, list->path_offset); - point += (list->path_count-1); - return *point; -} - -NK_INTERN struct nk_draw_command* -nk_draw_list_push_command(struct nk_draw_list *list, struct nk_rect clip, - nk_handle texture) -{ - NK_STORAGE const nk_size cmd_align = NK_ALIGNOF(struct nk_draw_command); - NK_STORAGE const nk_size cmd_size = sizeof(struct nk_draw_command); - struct nk_draw_command *cmd; - - NK_ASSERT(list); - cmd = (struct nk_draw_command*) - nk_buffer_alloc(list->buffer, NK_BUFFER_BACK, cmd_size, cmd_align); - - if (!cmd) return 0; - if (!list->cmd_count) { - nk_byte *memory = (nk_byte*)nk_buffer_memory(list->buffer); - nk_size total = nk_buffer_total(list->buffer); - memory = nk_ptr_add(nk_byte, memory, total); - list->cmd_offset = (nk_size)(memory - (nk_byte*)cmd); - } - - cmd->elem_count = 0; - cmd->clip_rect = clip; - cmd->texture = texture; -#ifdef NK_INCLUDE_COMMAND_USERDATA - cmd->userdata = list->userdata; -#endif - - list->cmd_count++; - list->clip_rect = clip; - return cmd; -} - -NK_INTERN struct nk_draw_command* -nk_draw_list_command_last(struct nk_draw_list *list) -{ - void *memory; - nk_size size; - struct nk_draw_command *cmd; - NK_ASSERT(list->cmd_count); - - memory = nk_buffer_memory(list->buffer); - size = nk_buffer_total(list->buffer); - cmd = nk_ptr_add(struct nk_draw_command, memory, size - list->cmd_offset); - return (cmd - (list->cmd_count-1)); -} - -NK_INTERN void -nk_draw_list_add_clip(struct nk_draw_list *list, struct nk_rect rect) -{ - NK_ASSERT(list); - if (!list) return; - if (!list->cmd_count) { - nk_draw_list_push_command(list, rect, list->config.null.texture); - } else { - struct nk_draw_command *prev = nk_draw_list_command_last(list); - if (prev->elem_count == 0) - prev->clip_rect = rect; - nk_draw_list_push_command(list, rect, prev->texture); - } -} - -NK_INTERN void -nk_draw_list_push_image(struct nk_draw_list *list, nk_handle texture) -{ - NK_ASSERT(list); - if (!list) return; - if (!list->cmd_count) { - nk_draw_list_push_command(list, nk_null_rect, texture); - } else { - struct nk_draw_command *prev = nk_draw_list_command_last(list); - if (prev->elem_count == 0) - prev->texture = texture; - else if (prev->texture.id != texture.id) - nk_draw_list_push_command(list, prev->clip_rect, texture); - } -} - -#ifdef NK_INCLUDE_COMMAND_USERDATA -NK_API void -nk_draw_list_push_userdata(struct nk_draw_list *list, nk_handle userdata) -{ - list->userdata = userdata; -} -#endif - -NK_INTERN void* -nk_draw_list_alloc_vertices(struct nk_draw_list *list, nk_size count) -{ - void *vtx; - NK_ASSERT(list); - if (!list) return 0; - vtx = nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, - list->config.vertex_size*count, list->config.vertex_alignment); - if (!vtx) return 0; - list->vertex_count += (unsigned int)count; - return vtx; -} - -NK_INTERN nk_draw_index* -nk_draw_list_alloc_elements(struct nk_draw_list *list, nk_size count) -{ - nk_draw_index *ids; - struct nk_draw_command *cmd; - NK_STORAGE const nk_size elem_align = NK_ALIGNOF(nk_draw_index); - NK_STORAGE const nk_size elem_size = sizeof(nk_draw_index); - NK_ASSERT(list); - if (!list) return 0; - - ids = (nk_draw_index*) - nk_buffer_alloc(list->elements, NK_BUFFER_FRONT, elem_size*count, elem_align); - if (!ids) return 0; - cmd = nk_draw_list_command_last(list); - list->element_count += (unsigned int)count; - cmd->elem_count += (unsigned int)count; - return ids; -} - -static int -nk_draw_vertex_layout_element_is_end_of_layout( - const struct nk_draw_vertex_layout_element *element) -{ - return (element->attribute == NK_VERTEX_ATTRIBUTE_COUNT || - element->format == NK_FORMAT_COUNT); -} - -static void -nk_draw_vertex_color(void *attribute, const float *values, - enum nk_draw_vertex_layout_format format) -{ - /* if this triggers you tried to provide a value format for a color */ - NK_ASSERT(format >= NK_FORMAT_COLOR_BEGIN); - NK_ASSERT(format <= NK_FORMAT_COLOR_END); - if (format < NK_FORMAT_COLOR_BEGIN || format > NK_FORMAT_COLOR_END) return; - - switch (format) { - default: NK_ASSERT(0 && "Invalid vertex layout color format"); break; - case NK_FORMAT_R8G8B8A8: - case NK_FORMAT_R8G8B8: { - struct nk_color col = nk_rgba_fv(values); - NK_MEMCPY(attribute, &col.r, sizeof(col)); - } break; - case NK_FORMAT_R16G15B16: { - nk_ushort col[3]; - col[0] = (nk_ushort)NK_CLAMP(NK_USHORT_MIN, values[0] * NK_USHORT_MAX, NK_USHORT_MAX); - col[1] = (nk_ushort)NK_CLAMP(NK_USHORT_MIN, values[1] * NK_USHORT_MAX, NK_USHORT_MAX); - col[2] = (nk_ushort)NK_CLAMP(NK_USHORT_MIN, values[2] * NK_USHORT_MAX, NK_USHORT_MAX); - NK_MEMCPY(attribute, col, sizeof(col)); - } break; - case NK_FORMAT_R16G15B16A16: { - nk_ushort col[4]; - col[0] = (nk_ushort)NK_CLAMP(NK_USHORT_MIN, values[0] * NK_USHORT_MAX, NK_USHORT_MAX); - col[1] = (nk_ushort)NK_CLAMP(NK_USHORT_MIN, values[1] * NK_USHORT_MAX, NK_USHORT_MAX); - col[2] = (nk_ushort)NK_CLAMP(NK_USHORT_MIN, values[2] * NK_USHORT_MAX, NK_USHORT_MAX); - col[3] = (nk_ushort)NK_CLAMP(NK_USHORT_MIN, values[3] * NK_USHORT_MAX, NK_USHORT_MAX); - NK_MEMCPY(attribute, col, sizeof(col)); - } break; - case NK_FORMAT_R32G32B32: { - nk_uint col[3]; - col[0] = (nk_uint)NK_CLAMP(NK_UINT_MIN, values[0] * NK_UINT_MAX, NK_UINT_MAX); - col[1] = (nk_uint)NK_CLAMP(NK_UINT_MIN, values[1] * NK_UINT_MAX, NK_UINT_MAX); - col[2] = (nk_uint)NK_CLAMP(NK_UINT_MIN, values[2] * NK_UINT_MAX, NK_UINT_MAX); - NK_MEMCPY(attribute, col, sizeof(col)); - } break; - case NK_FORMAT_R32G32B32A32: { - nk_uint col[4]; - col[0] = (nk_uint)NK_CLAMP(NK_UINT_MIN, values[0] * NK_UINT_MAX, NK_UINT_MAX); - col[1] = (nk_uint)NK_CLAMP(NK_UINT_MIN, values[1] * NK_UINT_MAX, NK_UINT_MAX); - col[2] = (nk_uint)NK_CLAMP(NK_UINT_MIN, values[2] * NK_UINT_MAX, NK_UINT_MAX); - col[3] = (nk_uint)NK_CLAMP(NK_UINT_MIN, values[3] * NK_UINT_MAX, NK_UINT_MAX); - NK_MEMCPY(attribute, col, sizeof(col)); - } break; - case NK_FORMAT_R32G32B32A32_FLOAT: - NK_MEMCPY(attribute, values, sizeof(float)*4); - break; - case NK_FORMAT_R32G32B32A32_DOUBLE: { - double col[4]; - col[0] = (double)NK_SATURATE(values[0]); - col[1] = (double)NK_SATURATE(values[1]); - col[2] = (double)NK_SATURATE(values[2]); - col[3] = (double)NK_SATURATE(values[3]); - NK_MEMCPY(attribute, col, sizeof(col)); - } break; - case NK_FORMAT_RGB32: - case NK_FORMAT_RGBA32: { - struct nk_color col = nk_rgba_fv(values); - nk_uint color = nk_color_u32(col); - NK_MEMCPY(attribute, &color, sizeof(color)); - } break; - } -} - -static void -nk_draw_vertex_element(void *dst, const float *values, int value_count, - enum nk_draw_vertex_layout_format format) -{ - int value_index; - void *attribute = dst; - /* if this triggers you tried to provide a color format for a value */ - NK_ASSERT(format < NK_FORMAT_COLOR_BEGIN); - if (format >= NK_FORMAT_COLOR_BEGIN && format <= NK_FORMAT_COLOR_END) return; - for (value_index = 0; value_index < value_count; ++value_index) { - switch (format) { - default: NK_ASSERT(0 && "invalid vertex layout format"); break; - case NK_FORMAT_SCHAR: { - char value = (char)NK_CLAMP(NK_SCHAR_MIN, values[value_index], NK_SCHAR_MAX); - NK_MEMCPY(attribute, &value, sizeof(value)); - attribute = (void*)((char*)attribute + sizeof(char)); - } break; - case NK_FORMAT_SSHORT: { - nk_short value = (nk_short)NK_CLAMP(NK_SSHORT_MIN, values[value_index], NK_SSHORT_MAX); - NK_MEMCPY(attribute, &value, sizeof(value)); - attribute = (void*)((char*)attribute + sizeof(value)); - } break; - case NK_FORMAT_SINT: { - nk_int value = (nk_int)NK_CLAMP(NK_SINT_MIN, values[value_index], NK_SINT_MAX); - NK_MEMCPY(attribute, &value, sizeof(value)); - attribute = (void*)((char*)attribute + sizeof(nk_int)); - } break; - case NK_FORMAT_UCHAR: { - unsigned char value = (unsigned char)NK_CLAMP(NK_UCHAR_MIN, values[value_index], NK_UCHAR_MAX); - NK_MEMCPY(attribute, &value, sizeof(value)); - attribute = (void*)((char*)attribute + sizeof(unsigned char)); - } break; - case NK_FORMAT_USHORT: { - nk_ushort value = (nk_ushort)NK_CLAMP(NK_USHORT_MIN, values[value_index], NK_USHORT_MAX); - NK_MEMCPY(attribute, &value, sizeof(value)); - attribute = (void*)((char*)attribute + sizeof(value)); - } break; - case NK_FORMAT_UINT: { - nk_uint value = (nk_uint)NK_CLAMP(NK_UINT_MIN, values[value_index], NK_UINT_MAX); - NK_MEMCPY(attribute, &value, sizeof(value)); - attribute = (void*)((char*)attribute + sizeof(nk_uint)); - } break; - case NK_FORMAT_FLOAT: - NK_MEMCPY(attribute, &values[value_index], sizeof(values[value_index])); - attribute = (void*)((char*)attribute + sizeof(float)); - break; - case NK_FORMAT_DOUBLE: { - double value = (double)values[value_index]; - NK_MEMCPY(attribute, &value, sizeof(value)); - attribute = (void*)((char*)attribute + sizeof(double)); - } break; - } - } -} - -NK_INTERN void* -nk_draw_vertex(void *dst, const struct nk_convert_config *config, - struct nk_vec2 pos, struct nk_vec2 uv, struct nk_colorf color) -{ - void *result = (void*)((char*)dst + config->vertex_size); - const struct nk_draw_vertex_layout_element *elem_iter = config->vertex_layout; - while (!nk_draw_vertex_layout_element_is_end_of_layout(elem_iter)) { - void *address = (void*)((char*)dst + elem_iter->offset); - switch (elem_iter->attribute) { - case NK_VERTEX_ATTRIBUTE_COUNT: - default: NK_ASSERT(0 && "wrong element attribute"); - case NK_VERTEX_POSITION: nk_draw_vertex_element(address, &pos.x, 2, elem_iter->format); break; - case NK_VERTEX_TEXCOORD: nk_draw_vertex_element(address, &uv.x, 2, elem_iter->format); break; - case NK_VERTEX_COLOR: nk_draw_vertex_color(address, &color.r, elem_iter->format); break; - } - elem_iter++; - } - return result; -} - -NK_API void -nk_draw_list_stroke_poly_line(struct nk_draw_list *list, const struct nk_vec2 *points, - const unsigned int points_count, struct nk_color color, enum nk_draw_list_stroke closed, - float thickness, enum nk_anti_aliasing aliasing) -{ - nk_size count; - int thick_line; - struct nk_colorf col; - struct nk_colorf col_trans; - NK_ASSERT(list); - if (!list || points_count < 2) return; - - color.a = (nk_byte)((float)color.a * list->config.global_alpha); - count = points_count; - if (!closed) count = points_count-1; - thick_line = thickness > 1.0f; - -#ifdef NK_INCLUDE_COMMAND_USERDATA - nk_draw_list_push_userdata(list, list->userdata); -#endif - - color.a = (nk_byte)((float)color.a * list->config.global_alpha); - nk_color_fv(&col.r, color); - col_trans = col; - col_trans.a = 0; - - if (aliasing == NK_ANTI_ALIASING_ON) { - /* ANTI-ALIASED STROKE */ - const float AA_SIZE = 1.0f; - NK_STORAGE const nk_size pnt_align = NK_ALIGNOF(struct nk_vec2); - NK_STORAGE const nk_size pnt_size = sizeof(struct nk_vec2); - - /* allocate vertices and elements */ - nk_size i1 = 0; - nk_size vertex_offset; - nk_size index = list->vertex_count; - - const nk_size idx_count = (thick_line) ? (count * 18) : (count * 12); - const nk_size vtx_count = (thick_line) ? (points_count * 4): (points_count *3); - - void *vtx = nk_draw_list_alloc_vertices(list, vtx_count); - nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count); - - nk_size size; - struct nk_vec2 *normals, *temp; - NK_ASSERT(vtx && ids); - if (!vtx || !ids) return; - - /* temporary allocate normals + points */ - vertex_offset = (nk_size)((nk_byte*)vtx - (nk_byte*)list->vertices->memory.ptr); - nk_buffer_mark(list->vertices, NK_BUFFER_FRONT); - size = pnt_size * ((thick_line) ? 5 : 3) * points_count; - normals = (struct nk_vec2*) nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, size, pnt_align); - NK_ASSERT(normals); - if (!normals) return; - temp = normals + points_count; - - /* make sure vertex pointer is still correct */ - vtx = (void*)((nk_byte*)list->vertices->memory.ptr + vertex_offset); - - /* calculate normals */ - for (i1 = 0; i1 < count; ++i1) { - const nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1); - struct nk_vec2 diff = nk_vec2_sub(points[i2], points[i1]); - float len; - - /* vec2 inverted length */ - len = nk_vec2_len_sqr(diff); - if (len != 0.0f) - len = nk_inv_sqrt(len); - else len = 1.0f; - - diff = nk_vec2_muls(diff, len); - normals[i1].x = diff.y; - normals[i1].y = -diff.x; - } - - if (!closed) - normals[points_count-1] = normals[points_count-2]; - - if (!thick_line) { - nk_size idx1, i; - if (!closed) { - struct nk_vec2 d; - temp[0] = nk_vec2_add(points[0], nk_vec2_muls(normals[0], AA_SIZE)); - temp[1] = nk_vec2_sub(points[0], nk_vec2_muls(normals[0], AA_SIZE)); - d = nk_vec2_muls(normals[points_count-1], AA_SIZE); - temp[(points_count-1) * 2 + 0] = nk_vec2_add(points[points_count-1], d); - temp[(points_count-1) * 2 + 1] = nk_vec2_sub(points[points_count-1], d); - } - - /* fill elements */ - idx1 = index; - for (i1 = 0; i1 < count; i1++) { - struct nk_vec2 dm; - float dmr2; - nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1); - nk_size idx2 = ((i1+1) == points_count) ? index: (idx1 + 3); - - /* average normals */ - dm = nk_vec2_muls(nk_vec2_add(normals[i1], normals[i2]), 0.5f); - dmr2 = dm.x * dm.x + dm.y* dm.y; - if (dmr2 > 0.000001f) { - float scale = 1.0f/dmr2; - scale = NK_MIN(100.0f, scale); - dm = nk_vec2_muls(dm, scale); - } - - dm = nk_vec2_muls(dm, AA_SIZE); - temp[i2*2+0] = nk_vec2_add(points[i2], dm); - temp[i2*2+1] = nk_vec2_sub(points[i2], dm); - - ids[0] = (nk_draw_index)(idx2 + 0); ids[1] = (nk_draw_index)(idx1+0); - ids[2] = (nk_draw_index)(idx1 + 2); ids[3] = (nk_draw_index)(idx1+2); - ids[4] = (nk_draw_index)(idx2 + 2); ids[5] = (nk_draw_index)(idx2+0); - ids[6] = (nk_draw_index)(idx2 + 1); ids[7] = (nk_draw_index)(idx1+1); - ids[8] = (nk_draw_index)(idx1 + 0); ids[9] = (nk_draw_index)(idx1+0); - ids[10]= (nk_draw_index)(idx2 + 0); ids[11]= (nk_draw_index)(idx2+1); - ids += 12; - idx1 = idx2; - } - - /* fill vertices */ - for (i = 0; i < points_count; ++i) { - const struct nk_vec2 uv = list->config.null.uv; - vtx = nk_draw_vertex(vtx, &list->config, points[i], uv, col); - vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+0], uv, col_trans); - vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+1], uv, col_trans); - } - } else { - nk_size idx1, i; - const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f; - if (!closed) { - struct nk_vec2 d1 = nk_vec2_muls(normals[0], half_inner_thickness + AA_SIZE); - struct nk_vec2 d2 = nk_vec2_muls(normals[0], half_inner_thickness); - - temp[0] = nk_vec2_add(points[0], d1); - temp[1] = nk_vec2_add(points[0], d2); - temp[2] = nk_vec2_sub(points[0], d2); - temp[3] = nk_vec2_sub(points[0], d1); - - d1 = nk_vec2_muls(normals[points_count-1], half_inner_thickness + AA_SIZE); - d2 = nk_vec2_muls(normals[points_count-1], half_inner_thickness); - - temp[(points_count-1)*4+0] = nk_vec2_add(points[points_count-1], d1); - temp[(points_count-1)*4+1] = nk_vec2_add(points[points_count-1], d2); - temp[(points_count-1)*4+2] = nk_vec2_sub(points[points_count-1], d2); - temp[(points_count-1)*4+3] = nk_vec2_sub(points[points_count-1], d1); - } - - /* add all elements */ - idx1 = index; - for (i1 = 0; i1 < count; ++i1) { - struct nk_vec2 dm_out, dm_in; - const nk_size i2 = ((i1+1) == points_count) ? 0: (i1 + 1); - nk_size idx2 = ((i1+1) == points_count) ? index: (idx1 + 4); - - /* average normals */ - struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(normals[i1], normals[i2]), 0.5f); - float dmr2 = dm.x * dm.x + dm.y* dm.y; - if (dmr2 > 0.000001f) { - float scale = 1.0f/dmr2; - scale = NK_MIN(100.0f, scale); - dm = nk_vec2_muls(dm, scale); - } - - dm_out = nk_vec2_muls(dm, ((half_inner_thickness) + AA_SIZE)); - dm_in = nk_vec2_muls(dm, half_inner_thickness); - temp[i2*4+0] = nk_vec2_add(points[i2], dm_out); - temp[i2*4+1] = nk_vec2_add(points[i2], dm_in); - temp[i2*4+2] = nk_vec2_sub(points[i2], dm_in); - temp[i2*4+3] = nk_vec2_sub(points[i2], dm_out); - - /* add indexes */ - ids[0] = (nk_draw_index)(idx2 + 1); ids[1] = (nk_draw_index)(idx1+1); - ids[2] = (nk_draw_index)(idx1 + 2); ids[3] = (nk_draw_index)(idx1+2); - ids[4] = (nk_draw_index)(idx2 + 2); ids[5] = (nk_draw_index)(idx2+1); - ids[6] = (nk_draw_index)(idx2 + 1); ids[7] = (nk_draw_index)(idx1+1); - ids[8] = (nk_draw_index)(idx1 + 0); ids[9] = (nk_draw_index)(idx1+0); - ids[10]= (nk_draw_index)(idx2 + 0); ids[11] = (nk_draw_index)(idx2+1); - ids[12]= (nk_draw_index)(idx2 + 2); ids[13] = (nk_draw_index)(idx1+2); - ids[14]= (nk_draw_index)(idx1 + 3); ids[15] = (nk_draw_index)(idx1+3); - ids[16]= (nk_draw_index)(idx2 + 3); ids[17] = (nk_draw_index)(idx2+2); - ids += 18; - idx1 = idx2; - } - - /* add vertices */ - for (i = 0; i < points_count; ++i) { - const struct nk_vec2 uv = list->config.null.uv; - vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+0], uv, col_trans); - vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+1], uv, col); - vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+2], uv, col); - vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+3], uv, col_trans); - } - } - /* free temporary normals + points */ - nk_buffer_reset(list->vertices, NK_BUFFER_FRONT); - } else { - /* NON ANTI-ALIASED STROKE */ - nk_size i1 = 0; - nk_size idx = list->vertex_count; - const nk_size idx_count = count * 6; - const nk_size vtx_count = count * 4; - void *vtx = nk_draw_list_alloc_vertices(list, vtx_count); - nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count); - if (!vtx || !ids) return; - - for (i1 = 0; i1 < count; ++i1) { - float dx, dy; - const struct nk_vec2 uv = list->config.null.uv; - const nk_size i2 = ((i1+1) == points_count) ? 0 : i1 + 1; - const struct nk_vec2 p1 = points[i1]; - const struct nk_vec2 p2 = points[i2]; - struct nk_vec2 diff = nk_vec2_sub(p2, p1); - float len; - - /* vec2 inverted length */ - len = nk_vec2_len_sqr(diff); - if (len != 0.0f) - len = nk_inv_sqrt(len); - else len = 1.0f; - diff = nk_vec2_muls(diff, len); - - /* add vertices */ - dx = diff.x * (thickness * 0.5f); - dy = diff.y * (thickness * 0.5f); - - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p1.x + dy, p1.y - dx), uv, col); - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p2.x + dy, p2.y - dx), uv, col); - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p2.x - dy, p2.y + dx), uv, col); - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p1.x - dy, p1.y + dx), uv, col); - - ids[0] = (nk_draw_index)(idx+0); ids[1] = (nk_draw_index)(idx+1); - ids[2] = (nk_draw_index)(idx+2); ids[3] = (nk_draw_index)(idx+0); - ids[4] = (nk_draw_index)(idx+2); ids[5] = (nk_draw_index)(idx+3); - - ids += 6; - idx += 4; - } - } -} - -NK_API void -nk_draw_list_fill_poly_convex(struct nk_draw_list *list, - const struct nk_vec2 *points, const unsigned int points_count, - struct nk_color color, enum nk_anti_aliasing aliasing) -{ - struct nk_colorf col; - struct nk_colorf col_trans; - - NK_STORAGE const nk_size pnt_align = NK_ALIGNOF(struct nk_vec2); - NK_STORAGE const nk_size pnt_size = sizeof(struct nk_vec2); - NK_ASSERT(list); - if (!list || points_count < 3) return; - -#ifdef NK_INCLUDE_COMMAND_USERDATA - nk_draw_list_push_userdata(list, list->userdata); -#endif - - color.a = (nk_byte)((float)color.a * list->config.global_alpha); - nk_color_fv(&col.r, color); - col_trans = col; - col_trans.a = 0; - - if (aliasing == NK_ANTI_ALIASING_ON) { - nk_size i = 0; - nk_size i0 = 0; - nk_size i1 = 0; - - const float AA_SIZE = 1.0f; - nk_size vertex_offset = 0; - nk_size index = list->vertex_count; - - const nk_size idx_count = (points_count-2)*3 + points_count*6; - const nk_size vtx_count = (points_count*2); - - void *vtx = nk_draw_list_alloc_vertices(list, vtx_count); - nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count); - - nk_size size = 0; - struct nk_vec2 *normals = 0; - unsigned int vtx_inner_idx = (unsigned int)(index + 0); - unsigned int vtx_outer_idx = (unsigned int)(index + 1); - if (!vtx || !ids) return; - - /* temporary allocate normals */ - vertex_offset = (nk_size)((nk_byte*)vtx - (nk_byte*)list->vertices->memory.ptr); - nk_buffer_mark(list->vertices, NK_BUFFER_FRONT); - size = pnt_size * points_count; - normals = (struct nk_vec2*) nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, size, pnt_align); - NK_ASSERT(normals); - if (!normals) return; - vtx = (void*)((nk_byte*)list->vertices->memory.ptr + vertex_offset); - - /* add elements */ - for (i = 2; i < points_count; i++) { - ids[0] = (nk_draw_index)(vtx_inner_idx); - ids[1] = (nk_draw_index)(vtx_inner_idx + ((i-1) << 1)); - ids[2] = (nk_draw_index)(vtx_inner_idx + (i << 1)); - ids += 3; - } - - /* compute normals */ - for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) { - struct nk_vec2 p0 = points[i0]; - struct nk_vec2 p1 = points[i1]; - struct nk_vec2 diff = nk_vec2_sub(p1, p0); - - /* vec2 inverted length */ - float len = nk_vec2_len_sqr(diff); - if (len != 0.0f) - len = nk_inv_sqrt(len); - else len = 1.0f; - diff = nk_vec2_muls(diff, len); - - normals[i0].x = diff.y; - normals[i0].y = -diff.x; - } - - /* add vertices + indexes */ - for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) { - const struct nk_vec2 uv = list->config.null.uv; - struct nk_vec2 n0 = normals[i0]; - struct nk_vec2 n1 = normals[i1]; - struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(n0, n1), 0.5f); - float dmr2 = dm.x*dm.x + dm.y*dm.y; - if (dmr2 > 0.000001f) { - float scale = 1.0f / dmr2; - scale = NK_MIN(scale, 100.0f); - dm = nk_vec2_muls(dm, scale); - } - dm = nk_vec2_muls(dm, AA_SIZE * 0.5f); - - /* add vertices */ - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2_sub(points[i1], dm), uv, col); - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2_add(points[i1], dm), uv, col_trans); - - /* add indexes */ - ids[0] = (nk_draw_index)(vtx_inner_idx+(i1<<1)); - ids[1] = (nk_draw_index)(vtx_inner_idx+(i0<<1)); - ids[2] = (nk_draw_index)(vtx_outer_idx+(i0<<1)); - ids[3] = (nk_draw_index)(vtx_outer_idx+(i0<<1)); - ids[4] = (nk_draw_index)(vtx_outer_idx+(i1<<1)); - ids[5] = (nk_draw_index)(vtx_inner_idx+(i1<<1)); - ids += 6; - } - /* free temporary normals + points */ - nk_buffer_reset(list->vertices, NK_BUFFER_FRONT); - } else { - nk_size i = 0; - nk_size index = list->vertex_count; - const nk_size idx_count = (points_count-2)*3; - const nk_size vtx_count = points_count; - void *vtx = nk_draw_list_alloc_vertices(list, vtx_count); - nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count); - - if (!vtx || !ids) return; - for (i = 0; i < vtx_count; ++i) - vtx = nk_draw_vertex(vtx, &list->config, points[i], list->config.null.uv, col); - for (i = 2; i < points_count; ++i) { - ids[0] = (nk_draw_index)index; - ids[1] = (nk_draw_index)(index+ i - 1); - ids[2] = (nk_draw_index)(index+i); - ids += 3; - } - } -} - -NK_API void -nk_draw_list_path_clear(struct nk_draw_list *list) -{ - NK_ASSERT(list); - if (!list) return; - nk_buffer_reset(list->buffer, NK_BUFFER_FRONT); - list->path_count = 0; - list->path_offset = 0; -} - -NK_API void -nk_draw_list_path_line_to(struct nk_draw_list *list, struct nk_vec2 pos) -{ - struct nk_vec2 *points = 0; - struct nk_draw_command *cmd = 0; - NK_ASSERT(list); - if (!list) return; - if (!list->cmd_count) - nk_draw_list_add_clip(list, nk_null_rect); - - cmd = nk_draw_list_command_last(list); - if (cmd && cmd->texture.ptr != list->config.null.texture.ptr) - nk_draw_list_push_image(list, list->config.null.texture); - - points = nk_draw_list_alloc_path(list, 1); - if (!points) return; - points[0] = pos; -} - -NK_API void -nk_draw_list_path_arc_to_fast(struct nk_draw_list *list, struct nk_vec2 center, - float radius, int a_min, int a_max) -{ - int a = 0; - NK_ASSERT(list); - if (!list) return; - if (a_min <= a_max) { - for (a = a_min; a <= a_max; a++) { - const struct nk_vec2 c = list->circle_vtx[(nk_size)a % NK_LEN(list->circle_vtx)]; - const float x = center.x + c.x * radius; - const float y = center.y + c.y * radius; - nk_draw_list_path_line_to(list, nk_vec2(x, y)); - } - } -} - -NK_API void -nk_draw_list_path_arc_to(struct nk_draw_list *list, struct nk_vec2 center, - float radius, float a_min, float a_max, unsigned int segments) -{ - unsigned int i = 0; - NK_ASSERT(list); - if (!list) return; - if (radius == 0.0f) return; - for (i = 0; i <= segments; ++i) { - const float a = a_min + ((float)i / ((float)segments) * (a_max - a_min)); - const float x = center.x + (float)NK_COS(a) * radius; - const float y = center.y + (float)NK_SIN(a) * radius; - nk_draw_list_path_line_to(list, nk_vec2(x, y)); - } -} - -NK_API void -nk_draw_list_path_rect_to(struct nk_draw_list *list, struct nk_vec2 a, - struct nk_vec2 b, float rounding) -{ - float r; - NK_ASSERT(list); - if (!list) return; - r = rounding; - r = NK_MIN(r, ((b.x-a.x) < 0) ? -(b.x-a.x): (b.x-a.x)); - r = NK_MIN(r, ((b.y-a.y) < 0) ? -(b.y-a.y): (b.y-a.y)); - - if (r == 0.0f) { - nk_draw_list_path_line_to(list, a); - nk_draw_list_path_line_to(list, nk_vec2(b.x,a.y)); - nk_draw_list_path_line_to(list, b); - nk_draw_list_path_line_to(list, nk_vec2(a.x,b.y)); - } else { - nk_draw_list_path_arc_to_fast(list, nk_vec2(a.x + r, a.y + r), r, 6, 9); - nk_draw_list_path_arc_to_fast(list, nk_vec2(b.x - r, a.y + r), r, 9, 12); - nk_draw_list_path_arc_to_fast(list, nk_vec2(b.x - r, b.y - r), r, 0, 3); - nk_draw_list_path_arc_to_fast(list, nk_vec2(a.x + r, b.y - r), r, 3, 6); - } -} - -NK_API void -nk_draw_list_path_curve_to(struct nk_draw_list *list, struct nk_vec2 p2, - struct nk_vec2 p3, struct nk_vec2 p4, unsigned int num_segments) -{ - float t_step; - unsigned int i_step; - struct nk_vec2 p1; - - NK_ASSERT(list); - NK_ASSERT(list->path_count); - if (!list || !list->path_count) return; - num_segments = NK_MAX(num_segments, 1); - - p1 = nk_draw_list_path_last(list); - t_step = 1.0f/(float)num_segments; - for (i_step = 1; i_step <= num_segments; ++i_step) { - float t = t_step * (float)i_step; - float u = 1.0f - t; - float w1 = u*u*u; - float w2 = 3*u*u*t; - float w3 = 3*u*t*t; - float w4 = t * t *t; - float x = w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x; - float y = w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y; - nk_draw_list_path_line_to(list, nk_vec2(x,y)); - } -} - -NK_API void -nk_draw_list_path_fill(struct nk_draw_list *list, struct nk_color color) -{ - struct nk_vec2 *points; - NK_ASSERT(list); - if (!list) return; - points = (struct nk_vec2*)nk_buffer_memory(list->buffer); - nk_draw_list_fill_poly_convex(list, points, list->path_count, color, list->config.shape_AA); - nk_draw_list_path_clear(list); -} - -NK_API void -nk_draw_list_path_stroke(struct nk_draw_list *list, struct nk_color color, - enum nk_draw_list_stroke closed, float thickness) -{ - struct nk_vec2 *points; - NK_ASSERT(list); - if (!list) return; - points = (struct nk_vec2*)nk_buffer_memory(list->buffer); - nk_draw_list_stroke_poly_line(list, points, list->path_count, color, - closed, thickness, list->config.line_AA); - nk_draw_list_path_clear(list); -} - -NK_API void -nk_draw_list_stroke_line(struct nk_draw_list *list, struct nk_vec2 a, - struct nk_vec2 b, struct nk_color col, float thickness) -{ - NK_ASSERT(list); - if (!list || !col.a) return; - nk_draw_list_path_line_to(list, nk_vec2_add(a, nk_vec2(0.5f, 0.5f))); - nk_draw_list_path_line_to(list, nk_vec2_add(b, nk_vec2(0.5f, 0.5f))); - nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness); -} - -NK_API void -nk_draw_list_fill_rect(struct nk_draw_list *list, struct nk_rect rect, - struct nk_color col, float rounding) -{ - NK_ASSERT(list); - if (!list || !col.a) return; - nk_draw_list_path_rect_to(list, nk_vec2(rect.x + 0.5f, rect.y + 0.5f), - nk_vec2(rect.x + rect.w + 0.5f, rect.y + rect.h + 0.5f), rounding); - nk_draw_list_path_fill(list, col); -} - -NK_API void -nk_draw_list_stroke_rect(struct nk_draw_list *list, struct nk_rect rect, - struct nk_color col, float rounding, float thickness) -{ - NK_ASSERT(list); - if (!list || !col.a) return; - nk_draw_list_path_rect_to(list, nk_vec2(rect.x + 0.5f, rect.y + 0.5f), - nk_vec2(rect.x + rect.w + 0.5f, rect.y + rect.h + 0.5f), rounding); - nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness); -} - -NK_API void -nk_draw_list_fill_rect_multi_color(struct nk_draw_list *list, struct nk_rect rect, - struct nk_color left, struct nk_color top, struct nk_color right, - struct nk_color bottom) -{ - void *vtx; - struct nk_colorf col_left, col_top; - struct nk_colorf col_right, col_bottom; - nk_draw_index *idx; - nk_draw_index index; - - nk_color_fv(&col_left.r, left); - nk_color_fv(&col_right.r, right); - nk_color_fv(&col_top.r, top); - nk_color_fv(&col_bottom.r, bottom); - - NK_ASSERT(list); - if (!list) return; - - nk_draw_list_push_image(list, list->config.null.texture); - index = (nk_draw_index)list->vertex_count; - vtx = nk_draw_list_alloc_vertices(list, 4); - idx = nk_draw_list_alloc_elements(list, 6); - if (!vtx || !idx) return; - - idx[0] = (nk_draw_index)(index+0); idx[1] = (nk_draw_index)(index+1); - idx[2] = (nk_draw_index)(index+2); idx[3] = (nk_draw_index)(index+0); - idx[4] = (nk_draw_index)(index+2); idx[5] = (nk_draw_index)(index+3); - - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x, rect.y), list->config.null.uv, col_left); - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x + rect.w, rect.y), list->config.null.uv, col_top); - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x + rect.w, rect.y + rect.h), list->config.null.uv, col_right); - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x, rect.y + rect.h), list->config.null.uv, col_bottom); -} - -NK_API void -nk_draw_list_fill_triangle(struct nk_draw_list *list, struct nk_vec2 a, - struct nk_vec2 b, struct nk_vec2 c, struct nk_color col) -{ - NK_ASSERT(list); - if (!list || !col.a) return; - nk_draw_list_path_line_to(list, a); - nk_draw_list_path_line_to(list, b); - nk_draw_list_path_line_to(list, c); - nk_draw_list_path_fill(list, col); -} - -NK_API void -nk_draw_list_stroke_triangle(struct nk_draw_list *list, struct nk_vec2 a, - struct nk_vec2 b, struct nk_vec2 c, struct nk_color col, float thickness) -{ - NK_ASSERT(list); - if (!list || !col.a) return; - nk_draw_list_path_line_to(list, a); - nk_draw_list_path_line_to(list, b); - nk_draw_list_path_line_to(list, c); - nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness); -} - -NK_API void -nk_draw_list_fill_circle(struct nk_draw_list *list, struct nk_vec2 center, - float radius, struct nk_color col, unsigned int segs) -{ - float a_max; - NK_ASSERT(list); - if (!list || !col.a) return; - a_max = NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs; - nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs); - nk_draw_list_path_fill(list, col); -} - -NK_API void -nk_draw_list_stroke_circle(struct nk_draw_list *list, struct nk_vec2 center, - float radius, struct nk_color col, unsigned int segs, float thickness) -{ - float a_max; - NK_ASSERT(list); - if (!list || !col.a) return; - a_max = NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs; - nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs); - nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness); -} - -NK_API void -nk_draw_list_stroke_curve(struct nk_draw_list *list, struct nk_vec2 p0, - struct nk_vec2 cp0, struct nk_vec2 cp1, struct nk_vec2 p1, - struct nk_color col, unsigned int segments, float thickness) -{ - NK_ASSERT(list); - if (!list || !col.a) return; - nk_draw_list_path_line_to(list, p0); - nk_draw_list_path_curve_to(list, cp0, cp1, p1, segments); - nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness); -} - -NK_INTERN void -nk_draw_list_push_rect_uv(struct nk_draw_list *list, struct nk_vec2 a, - struct nk_vec2 c, struct nk_vec2 uva, struct nk_vec2 uvc, - struct nk_color color) -{ - void *vtx; - struct nk_vec2 uvb; - struct nk_vec2 uvd; - struct nk_vec2 b; - struct nk_vec2 d; - - struct nk_colorf col; - nk_draw_index *idx; - nk_draw_index index; - NK_ASSERT(list); - if (!list) return; - - nk_color_fv(&col.r, color); - uvb = nk_vec2(uvc.x, uva.y); - uvd = nk_vec2(uva.x, uvc.y); - b = nk_vec2(c.x, a.y); - d = nk_vec2(a.x, c.y); - - index = (nk_draw_index)list->vertex_count; - vtx = nk_draw_list_alloc_vertices(list, 4); - idx = nk_draw_list_alloc_elements(list, 6); - if (!vtx || !idx) return; - - idx[0] = (nk_draw_index)(index+0); idx[1] = (nk_draw_index)(index+1); - idx[2] = (nk_draw_index)(index+2); idx[3] = (nk_draw_index)(index+0); - idx[4] = (nk_draw_index)(index+2); idx[5] = (nk_draw_index)(index+3); - - vtx = nk_draw_vertex(vtx, &list->config, a, uva, col); - vtx = nk_draw_vertex(vtx, &list->config, b, uvb, col); - vtx = nk_draw_vertex(vtx, &list->config, c, uvc, col); - vtx = nk_draw_vertex(vtx, &list->config, d, uvd, col); -} - -NK_API void -nk_draw_list_add_image(struct nk_draw_list *list, struct nk_image texture, - struct nk_rect rect, struct nk_color color) -{ - NK_ASSERT(list); - if (!list) return; - /* push new command with given texture */ - nk_draw_list_push_image(list, texture.handle); - if (nk_image_is_subimage(&texture)) { - /* add region inside of the texture */ - struct nk_vec2 uv[2]; - uv[0].x = (float)texture.region[0]/(float)texture.w; - uv[0].y = (float)texture.region[1]/(float)texture.h; - uv[1].x = (float)(texture.region[0] + texture.region[2])/(float)texture.w; - uv[1].y = (float)(texture.region[1] + texture.region[3])/(float)texture.h; - nk_draw_list_push_rect_uv(list, nk_vec2(rect.x, rect.y), - nk_vec2(rect.x + rect.w, rect.y + rect.h), uv[0], uv[1], color); - } else nk_draw_list_push_rect_uv(list, nk_vec2(rect.x, rect.y), - nk_vec2(rect.x + rect.w, rect.y + rect.h), - nk_vec2(0.0f, 0.0f), nk_vec2(1.0f, 1.0f),color); -} - -NK_API void -nk_draw_list_add_text(struct nk_draw_list *list, const struct nk_user_font *font, - struct nk_rect rect, const char *text, int len, float font_height, - struct nk_color fg) -{ - float x = 0; - int text_len = 0; - nk_rune unicode = 0; - nk_rune next = 0; - int glyph_len = 0; - int next_glyph_len = 0; - struct nk_user_font_glyph g; - - NK_ASSERT(list); - if (!list || !len || !text) return; - if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h, - list->clip_rect.x, list->clip_rect.y, list->clip_rect.w, list->clip_rect.h)) return; - - nk_draw_list_push_image(list, font->texture); - x = rect.x; - glyph_len = nk_utf_decode(text, &unicode, len); - if (!glyph_len) return; - - /* draw every glyph image */ - fg.a = (nk_byte)((float)fg.a * list->config.global_alpha); - while (text_len < len && glyph_len) { - float gx, gy, gh, gw; - float char_width = 0; - if (unicode == NK_UTF_INVALID) break; - - /* query currently drawn glyph information */ - next_glyph_len = nk_utf_decode(text + text_len + glyph_len, &next, (int)len - text_len); - font->query(font->userdata, font_height, &g, unicode, - (next == NK_UTF_INVALID) ? '\0' : next); - - /* calculate and draw glyph drawing rectangle and image */ - gx = x + g.offset.x; - gy = rect.y + g.offset.y; - gw = g.width; gh = g.height; - char_width = g.xadvance; - nk_draw_list_push_rect_uv(list, nk_vec2(gx,gy), nk_vec2(gx + gw, gy+ gh), - g.uv[0], g.uv[1], fg); - - /* offset next glyph */ - text_len += glyph_len; - x += char_width; - glyph_len = next_glyph_len; - unicode = next; - } -} - -NK_API void -nk_convert(struct nk_context *ctx, struct nk_buffer *cmds, - struct nk_buffer *vertices, struct nk_buffer *elements, - const struct nk_convert_config *config) -{ - const struct nk_command *cmd; - NK_ASSERT(ctx); - NK_ASSERT(cmds); - NK_ASSERT(vertices); - NK_ASSERT(elements); - NK_ASSERT(config); - NK_ASSERT(config->vertex_layout); - NK_ASSERT(config->vertex_size); - if (!ctx || !cmds || !vertices || !elements || !config || !config->vertex_layout) - return; - - nk_draw_list_setup(&ctx->draw_list, config, cmds, vertices, elements); - nk_foreach(cmd, ctx) - { -#ifdef NK_INCLUDE_COMMAND_USERDATA - ctx->draw_list.userdata = cmd->userdata; -#endif - switch (cmd->type) { - case NK_COMMAND_NOP: break; - case NK_COMMAND_SCISSOR: { - const struct nk_command_scissor *s = (const struct nk_command_scissor*)cmd; - nk_draw_list_add_clip(&ctx->draw_list, nk_rect(s->x, s->y, s->w, s->h)); - } break; - case NK_COMMAND_LINE: { - const struct nk_command_line *l = (const struct nk_command_line*)cmd; - nk_draw_list_stroke_line(&ctx->draw_list, nk_vec2(l->begin.x, l->begin.y), - nk_vec2(l->end.x, l->end.y), l->color, l->line_thickness); - } break; - case NK_COMMAND_CURVE: { - const struct nk_command_curve *q = (const struct nk_command_curve*)cmd; - nk_draw_list_stroke_curve(&ctx->draw_list, nk_vec2(q->begin.x, q->begin.y), - nk_vec2(q->ctrl[0].x, q->ctrl[0].y), nk_vec2(q->ctrl[1].x, - q->ctrl[1].y), nk_vec2(q->end.x, q->end.y), q->color, - config->curve_segment_count, q->line_thickness); - } break; - case NK_COMMAND_RECT: { - const struct nk_command_rect *r = (const struct nk_command_rect*)cmd; - nk_draw_list_stroke_rect(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h), - r->color, (float)r->rounding, r->line_thickness); - } break; - case NK_COMMAND_RECT_FILLED: { - const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled*)cmd; - nk_draw_list_fill_rect(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h), - r->color, (float)r->rounding); - } break; - case NK_COMMAND_RECT_MULTI_COLOR: { - const struct nk_command_rect_multi_color *r = (const struct nk_command_rect_multi_color*)cmd; - nk_draw_list_fill_rect_multi_color(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h), - r->left, r->top, r->right, r->bottom); - } break; - case NK_COMMAND_CIRCLE: { - const struct nk_command_circle *c = (const struct nk_command_circle*)cmd; - nk_draw_list_stroke_circle(&ctx->draw_list, nk_vec2((float)c->x + (float)c->w/2, - (float)c->y + (float)c->h/2), (float)c->w/2, c->color, - config->circle_segment_count, c->line_thickness); - } break; - case NK_COMMAND_CIRCLE_FILLED: { - const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd; - nk_draw_list_fill_circle(&ctx->draw_list, nk_vec2((float)c->x + (float)c->w/2, - (float)c->y + (float)c->h/2), (float)c->w/2, c->color, - config->circle_segment_count); - } break; - case NK_COMMAND_ARC: { - const struct nk_command_arc *c = (const struct nk_command_arc*)cmd; - nk_draw_list_path_line_to(&ctx->draw_list, nk_vec2(c->cx, c->cy)); - nk_draw_list_path_arc_to(&ctx->draw_list, nk_vec2(c->cx, c->cy), c->r, - c->a[0], c->a[1], config->arc_segment_count); - nk_draw_list_path_stroke(&ctx->draw_list, c->color, NK_STROKE_CLOSED, c->line_thickness); - } break; - case NK_COMMAND_ARC_FILLED: { - const struct nk_command_arc_filled *c = (const struct nk_command_arc_filled*)cmd; - nk_draw_list_path_line_to(&ctx->draw_list, nk_vec2(c->cx, c->cy)); - nk_draw_list_path_arc_to(&ctx->draw_list, nk_vec2(c->cx, c->cy), c->r, - c->a[0], c->a[1], config->arc_segment_count); - nk_draw_list_path_fill(&ctx->draw_list, c->color); - } break; - case NK_COMMAND_TRIANGLE: { - const struct nk_command_triangle *t = (const struct nk_command_triangle*)cmd; - nk_draw_list_stroke_triangle(&ctx->draw_list, nk_vec2(t->a.x, t->a.y), - nk_vec2(t->b.x, t->b.y), nk_vec2(t->c.x, t->c.y), t->color, - t->line_thickness); - } break; - case NK_COMMAND_TRIANGLE_FILLED: { - const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled*)cmd; - nk_draw_list_fill_triangle(&ctx->draw_list, nk_vec2(t->a.x, t->a.y), - nk_vec2(t->b.x, t->b.y), nk_vec2(t->c.x, t->c.y), t->color); - } break; - case NK_COMMAND_POLYGON: { - int i; - const struct nk_command_polygon*p = (const struct nk_command_polygon*)cmd; - for (i = 0; i < p->point_count; ++i) { - struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y); - nk_draw_list_path_line_to(&ctx->draw_list, pnt); - } - nk_draw_list_path_stroke(&ctx->draw_list, p->color, NK_STROKE_CLOSED, p->line_thickness); - } break; - case NK_COMMAND_POLYGON_FILLED: { - int i; - const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled*)cmd; - for (i = 0; i < p->point_count; ++i) { - struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y); - nk_draw_list_path_line_to(&ctx->draw_list, pnt); - } - nk_draw_list_path_fill(&ctx->draw_list, p->color); - } break; - case NK_COMMAND_POLYLINE: { - int i; - const struct nk_command_polyline *p = (const struct nk_command_polyline*)cmd; - for (i = 0; i < p->point_count; ++i) { - struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y); - nk_draw_list_path_line_to(&ctx->draw_list, pnt); - } - nk_draw_list_path_stroke(&ctx->draw_list, p->color, NK_STROKE_OPEN, p->line_thickness); - } break; - case NK_COMMAND_TEXT: { - const struct nk_command_text *t = (const struct nk_command_text*)cmd; - nk_draw_list_add_text(&ctx->draw_list, t->font, nk_rect(t->x, t->y, t->w, t->h), - t->string, t->length, t->height, t->foreground); - } break; - case NK_COMMAND_IMAGE: { - const struct nk_command_image *i = (const struct nk_command_image*)cmd; - nk_draw_list_add_image(&ctx->draw_list, i->img, nk_rect(i->x, i->y, i->w, i->h), i->col); - } break; - default: break; - } - } -} - -NK_API const struct nk_draw_command* -nk__draw_begin(const struct nk_context *ctx, - const struct nk_buffer *buffer) -{return nk__draw_list_begin(&ctx->draw_list, buffer);} - -NK_API const struct nk_draw_command* -nk__draw_end(const struct nk_context *ctx, const struct nk_buffer *buffer) -{return nk__draw_list_end(&ctx->draw_list, buffer);} - -NK_API const struct nk_draw_command* -nk__draw_next(const struct nk_draw_command *cmd, - const struct nk_buffer *buffer, const struct nk_context *ctx) -{return nk__draw_list_next(cmd, buffer, &ctx->draw_list);} - -#endif - -/* - * ============================================================== - * - * FONT HANDLING - * - * =============================================================== - */ -#ifdef NK_INCLUDE_FONT_BAKING -/* ------------------------------------------------------------- - * - * RECT PACK - * - * --------------------------------------------------------------*/ -/* stb_rect_pack.h - v0.05 - public domain - rectangle packing */ -/* Sean Barrett 2014 */ -#define NK_RP__MAXVAL 0xffff -typedef unsigned short nk_rp_coord; - -struct nk_rp_rect { - /* reserved for your use: */ - int id; - /* input: */ - nk_rp_coord w, h; - /* output: */ - nk_rp_coord x, y; - int was_packed; - /* non-zero if valid packing */ -}; /* 16 bytes, nominally */ - -struct nk_rp_node { - nk_rp_coord x,y; - struct nk_rp_node *next; -}; - -struct nk_rp_context { - int width; - int height; - int align; - int init_mode; - int heuristic; - int num_nodes; - struct nk_rp_node *active_head; - struct nk_rp_node *free_head; - struct nk_rp_node extra[2]; - /* we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' */ -}; - -struct nk_rp__findresult { - int x,y; - struct nk_rp_node **prev_link; -}; - -enum NK_RP_HEURISTIC { - NK_RP_HEURISTIC_Skyline_default=0, - NK_RP_HEURISTIC_Skyline_BL_sortHeight = NK_RP_HEURISTIC_Skyline_default, - NK_RP_HEURISTIC_Skyline_BF_sortHeight -}; -enum NK_RP_INIT_STATE{NK_RP__INIT_skyline = 1}; - -NK_INTERN void -nk_rp_setup_allow_out_of_mem(struct nk_rp_context *context, int allow_out_of_mem) -{ - if (allow_out_of_mem) - /* if it's ok to run out of memory, then don't bother aligning them; */ - /* this gives better packing, but may fail due to OOM (even though */ - /* the rectangles easily fit). @TODO a smarter approach would be to only */ - /* quantize once we've hit OOM, then we could get rid of this parameter. */ - context->align = 1; - else { - /* if it's not ok to run out of memory, then quantize the widths */ - /* so that num_nodes is always enough nodes. */ - /* */ - /* I.e. num_nodes * align >= width */ - /* align >= width / num_nodes */ - /* align = ceil(width/num_nodes) */ - context->align = (context->width + context->num_nodes-1) / context->num_nodes; - } -} - -NK_INTERN void -nk_rp_init_target(struct nk_rp_context *context, int width, int height, - struct nk_rp_node *nodes, int num_nodes) -{ - int i; -#ifndef STBRP_LARGE_RECTS - NK_ASSERT(width <= 0xffff && height <= 0xffff); -#endif - - for (i=0; i < num_nodes-1; ++i) - nodes[i].next = &nodes[i+1]; - nodes[i].next = 0; - context->init_mode = NK_RP__INIT_skyline; - context->heuristic = NK_RP_HEURISTIC_Skyline_default; - context->free_head = &nodes[0]; - context->active_head = &context->extra[0]; - context->width = width; - context->height = height; - context->num_nodes = num_nodes; - nk_rp_setup_allow_out_of_mem(context, 0); - - /* node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) */ - context->extra[0].x = 0; - context->extra[0].y = 0; - context->extra[0].next = &context->extra[1]; - context->extra[1].x = (nk_rp_coord) width; - context->extra[1].y = 65535; - context->extra[1].next = 0; -} - -/* find minimum y position if it starts at x1 */ -NK_INTERN int -nk_rp__skyline_find_min_y(struct nk_rp_context *c, struct nk_rp_node *first, - int x0, int width, int *pwaste) -{ - struct nk_rp_node *node = first; - int x1 = x0 + width; - int min_y, visited_width, waste_area; - NK_ASSERT(first->x <= x0); - NK_UNUSED(c); - - NK_ASSERT(node->next->x > x0); - /* we ended up handling this in the caller for efficiency */ - NK_ASSERT(node->x <= x0); - - min_y = 0; - waste_area = 0; - visited_width = 0; - while (node->x < x1) - { - if (node->y > min_y) { - /* raise min_y higher. */ - /* we've accounted for all waste up to min_y, */ - /* but we'll now add more waste for everything we've visited */ - waste_area += visited_width * (node->y - min_y); - min_y = node->y; - /* the first time through, visited_width might be reduced */ - if (node->x < x0) - visited_width += node->next->x - x0; - else - visited_width += node->next->x - node->x; - } else { - /* add waste area */ - int under_width = node->next->x - node->x; - if (under_width + visited_width > width) - under_width = width - visited_width; - waste_area += under_width * (min_y - node->y); - visited_width += under_width; - } - node = node->next; - } - *pwaste = waste_area; - return min_y; -} - -NK_INTERN struct nk_rp__findresult -nk_rp__skyline_find_best_pos(struct nk_rp_context *c, int width, int height) -{ - int best_waste = (1<<30), best_x, best_y = (1 << 30); - struct nk_rp__findresult fr; - struct nk_rp_node **prev, *node, *tail, **best = 0; - - /* align to multiple of c->align */ - width = (width + c->align - 1); - width -= width % c->align; - NK_ASSERT(width % c->align == 0); - - node = c->active_head; - prev = &c->active_head; - while (node->x + width <= c->width) { - int y,waste; - y = nk_rp__skyline_find_min_y(c, node, node->x, width, &waste); - /* actually just want to test BL */ - if (c->heuristic == NK_RP_HEURISTIC_Skyline_BL_sortHeight) { - /* bottom left */ - if (y < best_y) { - best_y = y; - best = prev; - } - } else { - /* best-fit */ - if (y + height <= c->height) { - /* can only use it if it first vertically */ - if (y < best_y || (y == best_y && waste < best_waste)) { - best_y = y; - best_waste = waste; - best = prev; - } - } - } - prev = &node->next; - node = node->next; - } - best_x = (best == 0) ? 0 : (*best)->x; - - /* if doing best-fit (BF), we also have to try aligning right edge to each node position */ - /* */ - /* e.g, if fitting */ - /* */ - /* ____________________ */ - /* |____________________| */ - /* */ - /* into */ - /* */ - /* | | */ - /* | ____________| */ - /* |____________| */ - /* */ - /* then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned */ - /* */ - /* This makes BF take about 2x the time */ - if (c->heuristic == NK_RP_HEURISTIC_Skyline_BF_sortHeight) - { - tail = c->active_head; - node = c->active_head; - prev = &c->active_head; - /* find first node that's admissible */ - while (tail->x < width) - tail = tail->next; - while (tail) - { - int xpos = tail->x - width; - int y,waste; - NK_ASSERT(xpos >= 0); - /* find the left position that matches this */ - while (node->next->x <= xpos) { - prev = &node->next; - node = node->next; - } - NK_ASSERT(node->next->x > xpos && node->x <= xpos); - y = nk_rp__skyline_find_min_y(c, node, xpos, width, &waste); - if (y + height < c->height) { - if (y <= best_y) { - if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) { - best_x = xpos; - NK_ASSERT(y <= best_y); - best_y = y; - best_waste = waste; - best = prev; - } - } - } - tail = tail->next; - } - } - fr.prev_link = best; - fr.x = best_x; - fr.y = best_y; - return fr; -} - -NK_INTERN struct nk_rp__findresult -nk_rp__skyline_pack_rectangle(struct nk_rp_context *context, int width, int height) -{ - /* find best position according to heuristic */ - struct nk_rp__findresult res = nk_rp__skyline_find_best_pos(context, width, height); - struct nk_rp_node *node, *cur; - - /* bail if: */ - /* 1. it failed */ - /* 2. the best node doesn't fit (we don't always check this) */ - /* 3. we're out of memory */ - if (res.prev_link == 0 || res.y + height > context->height || context->free_head == 0) { - res.prev_link = 0; - return res; - } - - /* on success, create new node */ - node = context->free_head; - node->x = (nk_rp_coord) res.x; - node->y = (nk_rp_coord) (res.y + height); - - context->free_head = node->next; - - /* insert the new node into the right starting point, and */ - /* let 'cur' point to the remaining nodes needing to be */ - /* stitched back in */ - cur = *res.prev_link; - if (cur->x < res.x) { - /* preserve the existing one, so start testing with the next one */ - struct nk_rp_node *next = cur->next; - cur->next = node; - cur = next; - } else { - *res.prev_link = node; - } - - /* from here, traverse cur and free the nodes, until we get to one */ - /* that shouldn't be freed */ - while (cur->next && cur->next->x <= res.x + width) { - struct nk_rp_node *next = cur->next; - /* move the current node to the free list */ - cur->next = context->free_head; - context->free_head = cur; - cur = next; - } - /* stitch the list back in */ - node->next = cur; - - if (cur->x < res.x + width) - cur->x = (nk_rp_coord) (res.x + width); - return res; -} - -NK_INTERN int -nk_rect_height_compare(const void *a, const void *b) -{ - const struct nk_rp_rect *p = (const struct nk_rp_rect *) a; - const struct nk_rp_rect *q = (const struct nk_rp_rect *) b; - if (p->h > q->h) - return -1; - if (p->h < q->h) - return 1; - return (p->w > q->w) ? -1 : (p->w < q->w); -} - -NK_INTERN int -nk_rect_original_order(const void *a, const void *b) -{ - const struct nk_rp_rect *p = (const struct nk_rp_rect *) a; - const struct nk_rp_rect *q = (const struct nk_rp_rect *) b; - return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed); -} - -static void -nk_rp_qsort(struct nk_rp_rect *array, unsigned int len, int(*cmp)(const void*,const void*)) -{ - /* iterative quick sort */ - #define NK_MAX_SORT_STACK 64 - unsigned right, left = 0, stack[NK_MAX_SORT_STACK], pos = 0; - unsigned seed = len/2 * 69069+1; - for (;;) { - for (; left+1 < len; len++) { - struct nk_rp_rect pivot, tmp; - if (pos == NK_MAX_SORT_STACK) len = stack[pos = 0]; - pivot = array[left+seed%(len-left)]; - seed = seed * 69069 + 1; - stack[pos++] = len; - for (right = left-1;;) { - while (cmp(&array[++right], &pivot) < 0); - while (cmp(&pivot, &array[--len]) < 0); - if (right >= len) break; - tmp = array[right]; - array[right] = array[len]; - array[len] = tmp; - } - } - if (pos == 0) break; - left = len; - len = stack[--pos]; - } - #undef NK_MAX_SORT_STACK -} - -NK_INTERN void -nk_rp_pack_rects(struct nk_rp_context *context, struct nk_rp_rect *rects, int num_rects) -{ - int i; - /* we use the 'was_packed' field internally to allow sorting/unsorting */ - for (i=0; i < num_rects; ++i) { - rects[i].was_packed = i; - } - - /* sort according to heuristic */ - nk_rp_qsort(rects, (unsigned)num_rects, nk_rect_height_compare); - - for (i=0; i < num_rects; ++i) { - struct nk_rp__findresult fr = nk_rp__skyline_pack_rectangle(context, rects[i].w, rects[i].h); - if (fr.prev_link) { - rects[i].x = (nk_rp_coord) fr.x; - rects[i].y = (nk_rp_coord) fr.y; - } else { - rects[i].x = rects[i].y = NK_RP__MAXVAL; - } - } - - /* unsort */ - nk_rp_qsort(rects, (unsigned)num_rects, nk_rect_original_order); - - /* set was_packed flags */ - for (i=0; i < num_rects; ++i) - rects[i].was_packed = !(rects[i].x == NK_RP__MAXVAL && rects[i].y == NK_RP__MAXVAL); -} - -/* - * ============================================================== - * - * TRUETYPE - * - * =============================================================== - */ -/* stb_truetype.h - v1.07 - public domain */ -#define NK_TT_MAX_OVERSAMPLE 8 -#define NK_TT__OVER_MASK (NK_TT_MAX_OVERSAMPLE-1) - -struct nk_tt_bakedchar { - unsigned short x0,y0,x1,y1; - /* coordinates of bbox in bitmap */ - float xoff,yoff,xadvance; -}; - -struct nk_tt_aligned_quad{ - float x0,y0,s0,t0; /* top-left */ - float x1,y1,s1,t1; /* bottom-right */ -}; - -struct nk_tt_packedchar { - unsigned short x0,y0,x1,y1; - /* coordinates of bbox in bitmap */ - float xoff,yoff,xadvance; - float xoff2,yoff2; -}; - -struct nk_tt_pack_range { - float font_size; - int first_unicode_codepoint_in_range; - /* if non-zero, then the chars are continuous, and this is the first codepoint */ - int *array_of_unicode_codepoints; - /* if non-zero, then this is an array of unicode codepoints */ - int num_chars; - struct nk_tt_packedchar *chardata_for_range; /* output */ - unsigned char h_oversample, v_oversample; - /* don't set these, they're used internally */ -}; - -struct nk_tt_pack_context { - void *pack_info; - int width; - int height; - int stride_in_bytes; - int padding; - unsigned int h_oversample, v_oversample; - unsigned char *pixels; - void *nodes; -}; - -struct nk_tt_fontinfo { - const unsigned char* data; /* pointer to .ttf file */ - int fontstart;/* offset of start of font */ - int numGlyphs;/* number of glyphs, needed for range checking */ - int loca,head,glyf,hhea,hmtx,kern; /* table locations as offset from start of .ttf */ - int index_map; /* a cmap mapping for our chosen character encoding */ - int indexToLocFormat; /* format needed to map from glyph index to glyph */ -}; - -enum { - NK_TT_vmove=1, - NK_TT_vline, - NK_TT_vcurve -}; - -struct nk_tt_vertex { - short x,y,cx,cy; - unsigned char type,padding; -}; - -struct nk_tt__bitmap{ - int w,h,stride; - unsigned char *pixels; -}; - -struct nk_tt__hheap_chunk { - struct nk_tt__hheap_chunk *next; -}; -struct nk_tt__hheap { - struct nk_allocator alloc; - struct nk_tt__hheap_chunk *head; - void *first_free; - int num_remaining_in_head_chunk; -}; - -struct nk_tt__edge { - float x0,y0, x1,y1; - int invert; -}; - -struct nk_tt__active_edge { - struct nk_tt__active_edge *next; - float fx,fdx,fdy; - float direction; - float sy; - float ey; -}; -struct nk_tt__point {float x,y;}; - -#define NK_TT_MACSTYLE_DONTCARE 0 -#define NK_TT_MACSTYLE_BOLD 1 -#define NK_TT_MACSTYLE_ITALIC 2 -#define NK_TT_MACSTYLE_UNDERSCORE 4 -#define NK_TT_MACSTYLE_NONE 8 -/* <= not same as 0, this makes us check the bitfield is 0 */ - -enum { /* platformID */ - NK_TT_PLATFORM_ID_UNICODE =0, - NK_TT_PLATFORM_ID_MAC =1, - NK_TT_PLATFORM_ID_ISO =2, - NK_TT_PLATFORM_ID_MICROSOFT =3 -}; - -enum { /* encodingID for NK_TT_PLATFORM_ID_UNICODE */ - NK_TT_UNICODE_EID_UNICODE_1_0 =0, - NK_TT_UNICODE_EID_UNICODE_1_1 =1, - NK_TT_UNICODE_EID_ISO_10646 =2, - NK_TT_UNICODE_EID_UNICODE_2_0_BMP=3, - NK_TT_UNICODE_EID_UNICODE_2_0_FULL=4 -}; - -enum { /* encodingID for NK_TT_PLATFORM_ID_MICROSOFT */ - NK_TT_MS_EID_SYMBOL =0, - NK_TT_MS_EID_UNICODE_BMP =1, - NK_TT_MS_EID_SHIFTJIS =2, - NK_TT_MS_EID_UNICODE_FULL =10 -}; - -enum { /* encodingID for NK_TT_PLATFORM_ID_MAC; same as Script Manager codes */ - NK_TT_MAC_EID_ROMAN =0, NK_TT_MAC_EID_ARABIC =4, - NK_TT_MAC_EID_JAPANESE =1, NK_TT_MAC_EID_HEBREW =5, - NK_TT_MAC_EID_CHINESE_TRAD =2, NK_TT_MAC_EID_GREEK =6, - NK_TT_MAC_EID_KOREAN =3, NK_TT_MAC_EID_RUSSIAN =7 -}; - -enum { /* languageID for NK_TT_PLATFORM_ID_MICROSOFT; same as LCID... */ - /* problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs */ - NK_TT_MS_LANG_ENGLISH =0x0409, NK_TT_MS_LANG_ITALIAN =0x0410, - NK_TT_MS_LANG_CHINESE =0x0804, NK_TT_MS_LANG_JAPANESE =0x0411, - NK_TT_MS_LANG_DUTCH =0x0413, NK_TT_MS_LANG_KOREAN =0x0412, - NK_TT_MS_LANG_FRENCH =0x040c, NK_TT_MS_LANG_RUSSIAN =0x0419, - NK_TT_MS_LANG_GERMAN =0x0407, NK_TT_MS_LANG_SPANISH =0x0409, - NK_TT_MS_LANG_HEBREW =0x040d, NK_TT_MS_LANG_SWEDISH =0x041D -}; - -enum { /* languageID for NK_TT_PLATFORM_ID_MAC */ - NK_TT_MAC_LANG_ENGLISH =0 , NK_TT_MAC_LANG_JAPANESE =11, - NK_TT_MAC_LANG_ARABIC =12, NK_TT_MAC_LANG_KOREAN =23, - NK_TT_MAC_LANG_DUTCH =4 , NK_TT_MAC_LANG_RUSSIAN =32, - NK_TT_MAC_LANG_FRENCH =1 , NK_TT_MAC_LANG_SPANISH =6 , - NK_TT_MAC_LANG_GERMAN =2 , NK_TT_MAC_LANG_SWEDISH =5 , - NK_TT_MAC_LANG_HEBREW =10, NK_TT_MAC_LANG_CHINESE_SIMPLIFIED =33, - NK_TT_MAC_LANG_ITALIAN =3 , NK_TT_MAC_LANG_CHINESE_TRAD =19 -}; - -#define nk_ttBYTE(p) (* (const nk_byte *) (p)) -#define nk_ttCHAR(p) (* (const char *) (p)) - -#if defined(NK_BIGENDIAN) && !defined(NK_ALLOW_UNALIGNED_TRUETYPE) - #define nk_ttUSHORT(p) (* (nk_ushort *) (p)) - #define nk_ttSHORT(p) (* (nk_short *) (p)) - #define nk_ttULONG(p) (* (nk_uint *) (p)) - #define nk_ttLONG(p) (* (nk_int *) (p)) -#else - static nk_ushort nk_ttUSHORT(const nk_byte *p) { return (nk_ushort)(p[0]*256 + p[1]); } - static nk_short nk_ttSHORT(const nk_byte *p) { return (nk_short)(p[0]*256 + p[1]); } - static nk_uint nk_ttULONG(const nk_byte *p) { return (nk_uint)((p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]); } -#endif - -#define nk_tt_tag4(p,c0,c1,c2,c3)\ - ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3)) -#define nk_tt_tag(p,str) nk_tt_tag4(p,str[0],str[1],str[2],str[3]) - -NK_INTERN int nk_tt_GetGlyphShape(const struct nk_tt_fontinfo *info, struct nk_allocator *alloc, - int glyph_index, struct nk_tt_vertex **pvertices); - -NK_INTERN nk_uint -nk_tt__find_table(const nk_byte *data, nk_uint fontstart, const char *tag) -{ - /* @OPTIMIZE: binary search */ - nk_int num_tables = nk_ttUSHORT(data+fontstart+4); - nk_uint tabledir = fontstart + 12; - nk_int i; - for (i = 0; i < num_tables; ++i) { - nk_uint loc = tabledir + (nk_uint)(16*i); - if (nk_tt_tag(data+loc+0, tag)) - return nk_ttULONG(data+loc+8); - } - return 0; -} - -NK_INTERN int -nk_tt_InitFont(struct nk_tt_fontinfo *info, const unsigned char *data2, int fontstart) -{ - nk_uint cmap, t; - nk_int i,numTables; - const nk_byte *data = (const nk_byte *) data2; - - info->data = data; - info->fontstart = fontstart; - - cmap = nk_tt__find_table(data, (nk_uint)fontstart, "cmap"); /* required */ - info->loca = (int)nk_tt__find_table(data, (nk_uint)fontstart, "loca"); /* required */ - info->head = (int)nk_tt__find_table(data, (nk_uint)fontstart, "head"); /* required */ - info->glyf = (int)nk_tt__find_table(data, (nk_uint)fontstart, "glyf"); /* required */ - info->hhea = (int)nk_tt__find_table(data, (nk_uint)fontstart, "hhea"); /* required */ - info->hmtx = (int)nk_tt__find_table(data, (nk_uint)fontstart, "hmtx"); /* required */ - info->kern = (int)nk_tt__find_table(data, (nk_uint)fontstart, "kern"); /* not required */ - if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx) - return 0; - - t = nk_tt__find_table(data, (nk_uint)fontstart, "maxp"); - if (t) info->numGlyphs = nk_ttUSHORT(data+t+4); - else info->numGlyphs = 0xffff; - - /* find a cmap encoding table we understand *now* to avoid searching */ - /* later. (todo: could make this installable) */ - /* the same regardless of glyph. */ - numTables = nk_ttUSHORT(data + cmap + 2); - info->index_map = 0; - for (i=0; i < numTables; ++i) - { - nk_uint encoding_record = cmap + 4 + 8 * (nk_uint)i; - /* find an encoding we understand: */ - switch(nk_ttUSHORT(data+encoding_record)) { - case NK_TT_PLATFORM_ID_MICROSOFT: - switch (nk_ttUSHORT(data+encoding_record+2)) { - case NK_TT_MS_EID_UNICODE_BMP: - case NK_TT_MS_EID_UNICODE_FULL: - /* MS/Unicode */ - info->index_map = (int)(cmap + nk_ttULONG(data+encoding_record+4)); - break; - default: break; - } break; - case NK_TT_PLATFORM_ID_UNICODE: - /* Mac/iOS has these */ - /* all the encodingIDs are unicode, so we don't bother to check it */ - info->index_map = (int)(cmap + nk_ttULONG(data+encoding_record+4)); - break; - default: break; - } - } - if (info->index_map == 0) - return 0; - info->indexToLocFormat = nk_ttUSHORT(data+info->head + 50); - return 1; -} - -NK_INTERN int -nk_tt_FindGlyphIndex(const struct nk_tt_fontinfo *info, int unicode_codepoint) -{ - const nk_byte *data = info->data; - nk_uint index_map = (nk_uint)info->index_map; - - nk_ushort format = nk_ttUSHORT(data + index_map + 0); - if (format == 0) { /* apple byte encoding */ - nk_int bytes = nk_ttUSHORT(data + index_map + 2); - if (unicode_codepoint < bytes-6) - return nk_ttBYTE(data + index_map + 6 + unicode_codepoint); - return 0; - } else if (format == 6) { - nk_uint first = nk_ttUSHORT(data + index_map + 6); - nk_uint count = nk_ttUSHORT(data + index_map + 8); - if ((nk_uint) unicode_codepoint >= first && (nk_uint) unicode_codepoint < first+count) - return nk_ttUSHORT(data + index_map + 10 + (unicode_codepoint - (int)first)*2); - return 0; - } else if (format == 2) { - NK_ASSERT(0); /* @TODO: high-byte mapping for japanese/chinese/korean */ - return 0; - } else if (format == 4) { /* standard mapping for windows fonts: binary search collection of ranges */ - nk_ushort segcount = nk_ttUSHORT(data+index_map+6) >> 1; - nk_ushort searchRange = nk_ttUSHORT(data+index_map+8) >> 1; - nk_ushort entrySelector = nk_ttUSHORT(data+index_map+10); - nk_ushort rangeShift = nk_ttUSHORT(data+index_map+12) >> 1; - - /* do a binary search of the segments */ - nk_uint endCount = index_map + 14; - nk_uint search = endCount; - - if (unicode_codepoint > 0xffff) - return 0; - - /* they lie from endCount .. endCount + segCount */ - /* but searchRange is the nearest power of two, so... */ - if (unicode_codepoint >= nk_ttUSHORT(data + search + rangeShift*2)) - search += (nk_uint)(rangeShift*2); - - /* now decrement to bias correctly to find smallest */ - search -= 2; - while (entrySelector) { - nk_ushort end; - searchRange >>= 1; - end = nk_ttUSHORT(data + search + searchRange*2); - if (unicode_codepoint > end) - search += (nk_uint)(searchRange*2); - --entrySelector; - } - search += 2; - - { - nk_ushort offset, start; - nk_ushort item = (nk_ushort) ((search - endCount) >> 1); - - NK_ASSERT(unicode_codepoint <= nk_ttUSHORT(data + endCount + 2*item)); - start = nk_ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item); - if (unicode_codepoint < start) - return 0; - - offset = nk_ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item); - if (offset == 0) - return (nk_ushort) (unicode_codepoint + nk_ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item)); - - return nk_ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item); - } - } else if (format == 12 || format == 13) { - nk_uint ngroups = nk_ttULONG(data+index_map+12); - nk_int low,high; - low = 0; high = (nk_int)ngroups; - /* Binary search the right group. */ - while (low < high) { - nk_int mid = low + ((high-low) >> 1); /* rounds down, so low <= mid < high */ - nk_uint start_char = nk_ttULONG(data+index_map+16+mid*12); - nk_uint end_char = nk_ttULONG(data+index_map+16+mid*12+4); - if ((nk_uint) unicode_codepoint < start_char) - high = mid; - else if ((nk_uint) unicode_codepoint > end_char) - low = mid+1; - else { - nk_uint start_glyph = nk_ttULONG(data+index_map+16+mid*12+8); - if (format == 12) - return (int)start_glyph + (int)unicode_codepoint - (int)start_char; - else /* format == 13 */ - return (int)start_glyph; - } - } - return 0; /* not found */ - } - /* @TODO */ - NK_ASSERT(0); - return 0; -} - -NK_INTERN void -nk_tt_setvertex(struct nk_tt_vertex *v, nk_byte type, nk_int x, nk_int y, nk_int cx, nk_int cy) -{ - v->type = type; - v->x = (nk_short) x; - v->y = (nk_short) y; - v->cx = (nk_short) cx; - v->cy = (nk_short) cy; -} - -NK_INTERN int -nk_tt__GetGlyfOffset(const struct nk_tt_fontinfo *info, int glyph_index) -{ - int g1,g2; - if (glyph_index >= info->numGlyphs) return -1; /* glyph index out of range */ - if (info->indexToLocFormat >= 2) return -1; /* unknown index->glyph map format */ - - if (info->indexToLocFormat == 0) { - g1 = info->glyf + nk_ttUSHORT(info->data + info->loca + glyph_index * 2) * 2; - g2 = info->glyf + nk_ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2; - } else { - g1 = info->glyf + (int)nk_ttULONG (info->data + info->loca + glyph_index * 4); - g2 = info->glyf + (int)nk_ttULONG (info->data + info->loca + glyph_index * 4 + 4); - } - return g1==g2 ? -1 : g1; /* if length is 0, return -1 */ -} - -NK_INTERN int -nk_tt_GetGlyphBox(const struct nk_tt_fontinfo *info, int glyph_index, - int *x0, int *y0, int *x1, int *y1) -{ - int g = nk_tt__GetGlyfOffset(info, glyph_index); - if (g < 0) return 0; - - if (x0) *x0 = nk_ttSHORT(info->data + g + 2); - if (y0) *y0 = nk_ttSHORT(info->data + g + 4); - if (x1) *x1 = nk_ttSHORT(info->data + g + 6); - if (y1) *y1 = nk_ttSHORT(info->data + g + 8); - return 1; -} - -NK_INTERN int -stbtt__close_shape(struct nk_tt_vertex *vertices, int num_vertices, int was_off, - int start_off, nk_int sx, nk_int sy, nk_int scx, nk_int scy, nk_int cx, nk_int cy) -{ - if (start_off) { - if (was_off) - nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy); - nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, sx,sy,scx,scy); - } else { - if (was_off) - nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve,sx,sy,cx,cy); - else - nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vline,sx,sy,0,0); - } - return num_vertices; -} - -NK_INTERN int -nk_tt_GetGlyphShape(const struct nk_tt_fontinfo *info, struct nk_allocator *alloc, - int glyph_index, struct nk_tt_vertex **pvertices) -{ - nk_short numberOfContours; - const nk_byte *endPtsOfContours; - const nk_byte *data = info->data; - struct nk_tt_vertex *vertices=0; - int num_vertices=0; - int g = nk_tt__GetGlyfOffset(info, glyph_index); - *pvertices = 0; - - if (g < 0) return 0; - numberOfContours = nk_ttSHORT(data + g); - if (numberOfContours > 0) { - nk_byte flags=0,flagcount; - nk_int ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0; - nk_int x,y,cx,cy,sx,sy, scx,scy; - const nk_byte *points; - endPtsOfContours = (data + g + 10); - ins = nk_ttUSHORT(data + g + 10 + numberOfContours * 2); - points = data + g + 10 + numberOfContours * 2 + 2 + ins; - - n = 1+nk_ttUSHORT(endPtsOfContours + numberOfContours*2-2); - m = n + 2*numberOfContours; /* a loose bound on how many vertices we might need */ - vertices = (struct nk_tt_vertex *)alloc->alloc(alloc->userdata, 0, (nk_size)m * sizeof(vertices[0])); - if (vertices == 0) - return 0; - - next_move = 0; - flagcount=0; - - /* in first pass, we load uninterpreted data into the allocated array */ - /* above, shifted to the end of the array so we won't overwrite it when */ - /* we create our final data starting from the front */ - off = m - n; /* starting offset for uninterpreted data, regardless of how m ends up being calculated */ - - /* first load flags */ - for (i=0; i < n; ++i) { - if (flagcount == 0) { - flags = *points++; - if (flags & 8) - flagcount = *points++; - } else --flagcount; - vertices[off+i].type = flags; - } - - /* now load x coordinates */ - x=0; - for (i=0; i < n; ++i) { - flags = vertices[off+i].type; - if (flags & 2) { - nk_short dx = *points++; - x += (flags & 16) ? dx : -dx; /* ??? */ - } else { - if (!(flags & 16)) { - x = x + (nk_short) (points[0]*256 + points[1]); - points += 2; - } - } - vertices[off+i].x = (nk_short) x; - } - - /* now load y coordinates */ - y=0; - for (i=0; i < n; ++i) { - flags = vertices[off+i].type; - if (flags & 4) { - nk_short dy = *points++; - y += (flags & 32) ? dy : -dy; /* ??? */ - } else { - if (!(flags & 32)) { - y = y + (nk_short) (points[0]*256 + points[1]); - points += 2; - } - } - vertices[off+i].y = (nk_short) y; - } - - /* now convert them to our format */ - num_vertices=0; - sx = sy = cx = cy = scx = scy = 0; - for (i=0; i < n; ++i) - { - flags = vertices[off+i].type; - x = (nk_short) vertices[off+i].x; - y = (nk_short) vertices[off+i].y; - - if (next_move == i) { - if (i != 0) - num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); - - /* now start the new one */ - start_off = !(flags & 1); - if (start_off) { - /* if we start off with an off-curve point, then when we need to find a point on the curve */ - /* where we can start, and we need to save some state for when we wraparound. */ - scx = x; - scy = y; - if (!(vertices[off+i+1].type & 1)) { - /* next point is also a curve point, so interpolate an on-point curve */ - sx = (x + (nk_int) vertices[off+i+1].x) >> 1; - sy = (y + (nk_int) vertices[off+i+1].y) >> 1; - } else { - /* otherwise just use the next point as our start point */ - sx = (nk_int) vertices[off+i+1].x; - sy = (nk_int) vertices[off+i+1].y; - ++i; /* we're using point i+1 as the starting point, so skip it */ - } - } else { - sx = x; - sy = y; - } - nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vmove,sx,sy,0,0); - was_off = 0; - next_move = 1 + nk_ttUSHORT(endPtsOfContours+j*2); - ++j; - } else { - if (!(flags & 1)) - { /* if it's a curve */ - if (was_off) /* two off-curve control points in a row means interpolate an on-curve midpoint */ - nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy); - cx = x; - cy = y; - was_off = 1; - } else { - if (was_off) - nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, x,y, cx, cy); - else nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vline, x,y,0,0); - was_off = 0; - } - } - } - num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); - } else if (numberOfContours == -1) { - /* Compound shapes. */ - int more = 1; - const nk_byte *comp = data + g + 10; - num_vertices = 0; - vertices = 0; - - while (more) - { - nk_ushort flags, gidx; - int comp_num_verts = 0, i; - struct nk_tt_vertex *comp_verts = 0, *tmp = 0; - float mtx[6] = {1,0,0,1,0,0}, m, n; - - flags = (nk_ushort)nk_ttSHORT(comp); comp+=2; - gidx = (nk_ushort)nk_ttSHORT(comp); comp+=2; - - if (flags & 2) { /* XY values */ - if (flags & 1) { /* shorts */ - mtx[4] = nk_ttSHORT(comp); comp+=2; - mtx[5] = nk_ttSHORT(comp); comp+=2; - } else { - mtx[4] = nk_ttCHAR(comp); comp+=1; - mtx[5] = nk_ttCHAR(comp); comp+=1; - } - } else { - /* @TODO handle matching point */ - NK_ASSERT(0); - } - if (flags & (1<<3)) { /* WE_HAVE_A_SCALE */ - mtx[0] = mtx[3] = nk_ttSHORT(comp)/16384.0f; comp+=2; - mtx[1] = mtx[2] = 0; - } else if (flags & (1<<6)) { /* WE_HAVE_AN_X_AND_YSCALE */ - mtx[0] = nk_ttSHORT(comp)/16384.0f; comp+=2; - mtx[1] = mtx[2] = 0; - mtx[3] = nk_ttSHORT(comp)/16384.0f; comp+=2; - } else if (flags & (1<<7)) { /* WE_HAVE_A_TWO_BY_TWO */ - mtx[0] = nk_ttSHORT(comp)/16384.0f; comp+=2; - mtx[1] = nk_ttSHORT(comp)/16384.0f; comp+=2; - mtx[2] = nk_ttSHORT(comp)/16384.0f; comp+=2; - mtx[3] = nk_ttSHORT(comp)/16384.0f; comp+=2; - } - - /* Find transformation scales. */ - m = (float) NK_SQRT(mtx[0]*mtx[0] + mtx[1]*mtx[1]); - n = (float) NK_SQRT(mtx[2]*mtx[2] + mtx[3]*mtx[3]); - - /* Get indexed glyph. */ - comp_num_verts = nk_tt_GetGlyphShape(info, alloc, gidx, &comp_verts); - if (comp_num_verts > 0) - { - /* Transform vertices. */ - for (i = 0; i < comp_num_verts; ++i) { - struct nk_tt_vertex* v = &comp_verts[i]; - short x,y; - x=v->x; y=v->y; - v->x = (short)(m * (mtx[0]*x + mtx[2]*y + mtx[4])); - v->y = (short)(n * (mtx[1]*x + mtx[3]*y + mtx[5])); - x=v->cx; y=v->cy; - v->cx = (short)(m * (mtx[0]*x + mtx[2]*y + mtx[4])); - v->cy = (short)(n * (mtx[1]*x + mtx[3]*y + mtx[5])); - } - /* Append vertices. */ - tmp = (struct nk_tt_vertex*)alloc->alloc(alloc->userdata, 0, - (nk_size)(num_vertices+comp_num_verts)*sizeof(struct nk_tt_vertex)); - if (!tmp) { - if (vertices) alloc->free(alloc->userdata, vertices); - if (comp_verts) alloc->free(alloc->userdata, comp_verts); - return 0; - } - if (num_vertices > 0) NK_MEMCPY(tmp, vertices, (nk_size)num_vertices*sizeof(struct nk_tt_vertex)); - NK_MEMCPY(tmp+num_vertices, comp_verts, (nk_size)comp_num_verts*sizeof(struct nk_tt_vertex)); - if (vertices) alloc->free(alloc->userdata,vertices); - vertices = tmp; - alloc->free(alloc->userdata,comp_verts); - num_vertices += comp_num_verts; - } - /* More components ? */ - more = flags & (1<<5); - } - } else if (numberOfContours < 0) { - /* @TODO other compound variations? */ - NK_ASSERT(0); - } else { - /* numberOfCounters == 0, do nothing */ - } - *pvertices = vertices; - return num_vertices; -} - -NK_INTERN void -nk_tt_GetGlyphHMetrics(const struct nk_tt_fontinfo *info, int glyph_index, - int *advanceWidth, int *leftSideBearing) -{ - nk_ushort numOfLongHorMetrics = nk_ttUSHORT(info->data+info->hhea + 34); - if (glyph_index < numOfLongHorMetrics) { - if (advanceWidth) - *advanceWidth = nk_ttSHORT(info->data + info->hmtx + 4*glyph_index); - if (leftSideBearing) - *leftSideBearing = nk_ttSHORT(info->data + info->hmtx + 4*glyph_index + 2); - } else { - if (advanceWidth) - *advanceWidth = nk_ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1)); - if (leftSideBearing) - *leftSideBearing = nk_ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics)); - } -} - -NK_INTERN void -nk_tt_GetFontVMetrics(const struct nk_tt_fontinfo *info, - int *ascent, int *descent, int *lineGap) -{ - if (ascent ) *ascent = nk_ttSHORT(info->data+info->hhea + 4); - if (descent) *descent = nk_ttSHORT(info->data+info->hhea + 6); - if (lineGap) *lineGap = nk_ttSHORT(info->data+info->hhea + 8); -} - -NK_INTERN float -nk_tt_ScaleForPixelHeight(const struct nk_tt_fontinfo *info, float height) -{ - int fheight = nk_ttSHORT(info->data + info->hhea + 4) - nk_ttSHORT(info->data + info->hhea + 6); - return (float) height / (float)fheight; -} - -NK_INTERN float -nk_tt_ScaleForMappingEmToPixels(const struct nk_tt_fontinfo *info, float pixels) -{ - int unitsPerEm = nk_ttUSHORT(info->data + info->head + 18); - return pixels / (float)unitsPerEm; -} - -/*------------------------------------------------------------- - * antialiasing software rasterizer - * --------------------------------------------------------------*/ -NK_INTERN void -nk_tt_GetGlyphBitmapBoxSubpixel(const struct nk_tt_fontinfo *font, - int glyph, float scale_x, float scale_y,float shift_x, float shift_y, - int *ix0, int *iy0, int *ix1, int *iy1) -{ - int x0,y0,x1,y1; - if (!nk_tt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) { - /* e.g. space character */ - if (ix0) *ix0 = 0; - if (iy0) *iy0 = 0; - if (ix1) *ix1 = 0; - if (iy1) *iy1 = 0; - } else { - /* move to integral bboxes (treating pixels as little squares, what pixels get touched)? */ - if (ix0) *ix0 = nk_ifloorf((float)x0 * scale_x + shift_x); - if (iy0) *iy0 = nk_ifloorf((float)-y1 * scale_y + shift_y); - if (ix1) *ix1 = nk_iceilf ((float)x1 * scale_x + shift_x); - if (iy1) *iy1 = nk_iceilf ((float)-y0 * scale_y + shift_y); - } -} - -NK_INTERN void -nk_tt_GetGlyphBitmapBox(const struct nk_tt_fontinfo *font, int glyph, - float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) -{ - nk_tt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1); -} - -/*------------------------------------------------------------- - * Rasterizer - * --------------------------------------------------------------*/ -NK_INTERN void* -nk_tt__hheap_alloc(struct nk_tt__hheap *hh, nk_size size) -{ - if (hh->first_free) { - void *p = hh->first_free; - hh->first_free = * (void **) p; - return p; - } else { - if (hh->num_remaining_in_head_chunk == 0) { - int count = (size < 32 ? 2000 : size < 128 ? 800 : 100); - struct nk_tt__hheap_chunk *c = (struct nk_tt__hheap_chunk *) - hh->alloc.alloc(hh->alloc.userdata, 0, - sizeof(struct nk_tt__hheap_chunk) + size * (nk_size)count); - if (c == 0) return 0; - c->next = hh->head; - hh->head = c; - hh->num_remaining_in_head_chunk = count; - } - --hh->num_remaining_in_head_chunk; - return (char *) (hh->head) + size * (nk_size)hh->num_remaining_in_head_chunk; - } -} - -NK_INTERN void -nk_tt__hheap_free(struct nk_tt__hheap *hh, void *p) -{ - *(void **) p = hh->first_free; - hh->first_free = p; -} - -NK_INTERN void -nk_tt__hheap_cleanup(struct nk_tt__hheap *hh) -{ - struct nk_tt__hheap_chunk *c = hh->head; - while (c) { - struct nk_tt__hheap_chunk *n = c->next; - hh->alloc.free(hh->alloc.userdata, c); - c = n; - } -} - -NK_INTERN struct nk_tt__active_edge* -nk_tt__new_active(struct nk_tt__hheap *hh, struct nk_tt__edge *e, - int off_x, float start_point) -{ - struct nk_tt__active_edge *z = (struct nk_tt__active_edge *) - nk_tt__hheap_alloc(hh, sizeof(*z)); - float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); - /*STBTT_assert(e->y0 <= start_point); */ - if (!z) return z; - z->fdx = dxdy; - z->fdy = (dxdy != 0) ? (1/dxdy): 0; - z->fx = e->x0 + dxdy * (start_point - e->y0); - z->fx -= (float)off_x; - z->direction = e->invert ? 1.0f : -1.0f; - z->sy = e->y0; - z->ey = e->y1; - z->next = 0; - return z; -} - -NK_INTERN void -nk_tt__handle_clipped_edge(float *scanline, int x, struct nk_tt__active_edge *e, - float x0, float y0, float x1, float y1) -{ - if (y0 == y1) return; - NK_ASSERT(y0 < y1); - NK_ASSERT(e->sy <= e->ey); - if (y0 > e->ey) return; - if (y1 < e->sy) return; - if (y0 < e->sy) { - x0 += (x1-x0) * (e->sy - y0) / (y1-y0); - y0 = e->sy; - } - if (y1 > e->ey) { - x1 += (x1-x0) * (e->ey - y1) / (y1-y0); - y1 = e->ey; - } - - if (x0 == x) NK_ASSERT(x1 <= x+1); - else if (x0 == x+1) NK_ASSERT(x1 >= x); - else if (x0 <= x) NK_ASSERT(x1 <= x); - else if (x0 >= x+1) NK_ASSERT(x1 >= x+1); - else NK_ASSERT(x1 >= x && x1 <= x+1); - - if (x0 <= x && x1 <= x) - scanline[x] += e->direction * (y1-y0); - else if (x0 >= x+1 && x1 >= x+1); - else { - NK_ASSERT(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1); - /* coverage = 1 - average x position */ - scanline[x] += (float)e->direction * (float)(y1-y0) * (1.0f-((x0-(float)x)+(x1-(float)x))/2.0f); - } -} - -NK_INTERN void -nk_tt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, - struct nk_tt__active_edge *e, float y_top) -{ - float y_bottom = y_top+1; - while (e) - { - /* brute force every pixel */ - /* compute intersection points with top & bottom */ - NK_ASSERT(e->ey >= y_top); - if (e->fdx == 0) { - float x0 = e->fx; - if (x0 < len) { - if (x0 >= 0) { - nk_tt__handle_clipped_edge(scanline,(int) x0,e, x0,y_top, x0,y_bottom); - nk_tt__handle_clipped_edge(scanline_fill-1,(int) x0+1,e, x0,y_top, x0,y_bottom); - } else { - nk_tt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom); - } - } - } else { - float x0 = e->fx; - float dx = e->fdx; - float xb = x0 + dx; - float x_top, x_bottom; - float y0,y1; - float dy = e->fdy; - NK_ASSERT(e->sy <= y_bottom && e->ey >= y_top); - - /* compute endpoints of line segment clipped to this scanline (if the */ - /* line segment starts on this scanline. x0 is the intersection of the */ - /* line with y_top, but that may be off the line segment. */ - if (e->sy > y_top) { - x_top = x0 + dx * (e->sy - y_top); - y0 = e->sy; - } else { - x_top = x0; - y0 = y_top; - } - - if (e->ey < y_bottom) { - x_bottom = x0 + dx * (e->ey - y_top); - y1 = e->ey; - } else { - x_bottom = xb; - y1 = y_bottom; - } - - if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) - { - /* from here on, we don't have to range check x values */ - if ((int) x_top == (int) x_bottom) { - float height; - /* simple case, only spans one pixel */ - int x = (int) x_top; - height = y1 - y0; - NK_ASSERT(x >= 0 && x < len); - scanline[x] += e->direction * (1.0f-(((float)x_top - (float)x) + ((float)x_bottom-(float)x))/2.0f) * (float)height; - scanline_fill[x] += e->direction * (float)height; /* everything right of this pixel is filled */ - } else { - int x,x1,x2; - float y_crossing, step, sign, area; - /* covers 2+ pixels */ - if (x_top > x_bottom) - { - /* flip scanline vertically; signed area is the same */ - float t; - y0 = y_bottom - (y0 - y_top); - y1 = y_bottom - (y1 - y_top); - t = y0; y0 = y1; y1 = t; - t = x_bottom; x_bottom = x_top; x_top = t; - dx = -dx; - dy = -dy; - t = x0; x0 = xb; xb = t; - } - - x1 = (int) x_top; - x2 = (int) x_bottom; - /* compute intersection with y axis at x1+1 */ - y_crossing = ((float)x1+1 - (float)x0) * (float)dy + (float)y_top; - - sign = e->direction; - /* area of the rectangle covered from y0..y_crossing */ - area = sign * (y_crossing-y0); - /* area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing) */ - scanline[x1] += area * (1.0f-((float)((float)x_top - (float)x1)+(float)(x1+1-x1))/2.0f); - - step = sign * dy; - for (x = x1+1; x < x2; ++x) { - scanline[x] += area + step/2; - area += step; - } - y_crossing += (float)dy * (float)(x2 - (x1+1)); - - scanline[x2] += area + sign * (1.0f-((float)(x2-x2)+((float)x_bottom-(float)x2))/2.0f) * (y1-y_crossing); - scanline_fill[x2] += sign * (y1-y0); - } - } - else - { - /* if edge goes outside of box we're drawing, we require */ - /* clipping logic. since this does not match the intended use */ - /* of this library, we use a different, very slow brute */ - /* force implementation */ - int x; - for (x=0; x < len; ++x) - { - /* cases: */ - /* */ - /* there can be up to two intersections with the pixel. any intersection */ - /* with left or right edges can be handled by splitting into two (or three) */ - /* regions. intersections with top & bottom do not necessitate case-wise logic. */ - /* */ - /* the old way of doing this found the intersections with the left & right edges, */ - /* then used some simple logic to produce up to three segments in sorted order */ - /* from top-to-bottom. however, this had a problem: if an x edge was epsilon */ - /* across the x border, then the corresponding y position might not be distinct */ - /* from the other y segment, and it might ignored as an empty segment. to avoid */ - /* that, we need to explicitly produce segments based on x positions. */ - - /* rename variables to clear pairs */ - float ya = y_top; - float x1 = (float) (x); - float x2 = (float) (x+1); - float x3 = xb; - float y3 = y_bottom; - float yb,y2; - - yb = ((float)x - x0) / dx + y_top; - y2 = ((float)x+1 - x0) / dx + y_top; - - if (x0 < x1 && x3 > x2) { /* three segments descending down-right */ - nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x1,yb); - nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x2,y2); - nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); - } else if (x3 < x1 && x0 > x2) { /* three segments descending down-left */ - nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x2,y2); - nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x1,yb); - nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x3,y3); - } else if (x0 < x1 && x3 > x1) { /* two segments across x, down-right */ - nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x1,yb); - nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x3,y3); - } else if (x3 < x1 && x0 > x1) { /* two segments across x, down-left */ - nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x1,yb); - nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x3,y3); - } else if (x0 < x2 && x3 > x2) { /* two segments across x+1, down-right */ - nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x2,y2); - nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); - } else if (x3 < x2 && x0 > x2) { /* two segments across x+1, down-left */ - nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x2,y2); - nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); - } else { /* one segment */ - nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x3,y3); - } - } - } - } - e = e->next; - } -} - -/* directly AA rasterize edges w/o supersampling */ -NK_INTERN void -nk_tt__rasterize_sorted_edges(struct nk_tt__bitmap *result, struct nk_tt__edge *e, - int n, int vsubsample, int off_x, int off_y, struct nk_allocator *alloc) -{ - struct nk_tt__hheap hh; - struct nk_tt__active_edge *active = 0; - int y,j=0, i; - float scanline_data[129], *scanline, *scanline2; - - NK_UNUSED(vsubsample); - nk_zero_struct(hh); - hh.alloc = *alloc; - - if (result->w > 64) - scanline = (float *) alloc->alloc(alloc->userdata,0, (nk_size)(result->w*2+1) * sizeof(float)); - else scanline = scanline_data; - - scanline2 = scanline + result->w; - y = off_y; - e[n].y0 = (float) (off_y + result->h) + 1; - - while (j < result->h) - { - /* find center of pixel for this scanline */ - float scan_y_top = (float)y + 0.0f; - float scan_y_bottom = (float)y + 1.0f; - struct nk_tt__active_edge **step = &active; - - NK_MEMSET(scanline , 0, (nk_size)result->w*sizeof(scanline[0])); - NK_MEMSET(scanline2, 0, (nk_size)(result->w+1)*sizeof(scanline[0])); - - /* update all active edges; */ - /* remove all active edges that terminate before the top of this scanline */ - while (*step) { - struct nk_tt__active_edge * z = *step; - if (z->ey <= scan_y_top) { - *step = z->next; /* delete from list */ - NK_ASSERT(z->direction); - z->direction = 0; - nk_tt__hheap_free(&hh, z); - } else { - step = &((*step)->next); /* advance through list */ - } - } - - /* insert all edges that start before the bottom of this scanline */ - while (e->y0 <= scan_y_bottom) { - if (e->y0 != e->y1) { - struct nk_tt__active_edge *z = nk_tt__new_active(&hh, e, off_x, scan_y_top); - if (z != 0) { - NK_ASSERT(z->ey >= scan_y_top); - /* insert at front */ - z->next = active; - active = z; - } - } - ++e; - } - - /* now process all active edges */ - if (active) - nk_tt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top); - - { - float sum = 0; - for (i=0; i < result->w; ++i) { - float k; - int m; - sum += scanline2[i]; - k = scanline[i] + sum; - k = (float) NK_ABS(k) * 255.0f + 0.5f; - m = (int) k; - if (m > 255) m = 255; - result->pixels[j*result->stride + i] = (unsigned char) m; - } - } - /* advance all the edges */ - step = &active; - while (*step) { - struct nk_tt__active_edge *z = *step; - z->fx += z->fdx; /* advance to position for current scanline */ - step = &((*step)->next); /* advance through list */ - } - ++y; - ++j; - } - nk_tt__hheap_cleanup(&hh); - if (scanline != scanline_data) - alloc->free(alloc->userdata, scanline); -} - -#define NK_TT__COMPARE(a,b) ((a)->y0 < (b)->y0) -NK_INTERN void -nk_tt__sort_edges_ins_sort(struct nk_tt__edge *p, int n) -{ - int i,j; - for (i=1; i < n; ++i) { - struct nk_tt__edge t = p[i], *a = &t; - j = i; - while (j > 0) { - struct nk_tt__edge *b = &p[j-1]; - int c = NK_TT__COMPARE(a,b); - if (!c) break; - p[j] = p[j-1]; - --j; - } - if (i != j) - p[j] = t; - } -} - -NK_INTERN void -nk_tt__sort_edges_quicksort(struct nk_tt__edge *p, int n) -{ - /* threshold for transitioning to insertion sort */ - while (n > 12) { - struct nk_tt__edge t; - int c01,c12,c,m,i,j; - - /* compute median of three */ - m = n >> 1; - c01 = NK_TT__COMPARE(&p[0],&p[m]); - c12 = NK_TT__COMPARE(&p[m],&p[n-1]); - - /* if 0 >= mid >= end, or 0 < mid < end, then use mid */ - if (c01 != c12) { - /* otherwise, we'll need to swap something else to middle */ - int z; - c = NK_TT__COMPARE(&p[0],&p[n-1]); - /* 0>mid && midn => n; 0 0 */ - /* 0n: 0>n => 0; 0 n */ - z = (c == c12) ? 0 : n-1; - t = p[z]; - p[z] = p[m]; - p[m] = t; - } - - /* now p[m] is the median-of-three */ - /* swap it to the beginning so it won't move around */ - t = p[0]; - p[0] = p[m]; - p[m] = t; - - /* partition loop */ - i=1; - j=n-1; - for(;;) { - /* handling of equality is crucial here */ - /* for sentinels & efficiency with duplicates */ - for (;;++i) { - if (!NK_TT__COMPARE(&p[i], &p[0])) break; - } - for (;;--j) { - if (!NK_TT__COMPARE(&p[0], &p[j])) break; - } - - /* make sure we haven't crossed */ - if (i >= j) break; - t = p[i]; - p[i] = p[j]; - p[j] = t; - - ++i; - --j; - - } - - /* recurse on smaller side, iterate on larger */ - if (j < (n-i)) { - nk_tt__sort_edges_quicksort(p,j); - p = p+i; - n = n-i; - } else { - nk_tt__sort_edges_quicksort(p+i, n-i); - n = j; - } - } -} - -NK_INTERN void -nk_tt__sort_edges(struct nk_tt__edge *p, int n) -{ - nk_tt__sort_edges_quicksort(p, n); - nk_tt__sort_edges_ins_sort(p, n); -} - -NK_INTERN void -nk_tt__rasterize(struct nk_tt__bitmap *result, struct nk_tt__point *pts, - int *wcount, int windings, float scale_x, float scale_y, - float shift_x, float shift_y, int off_x, int off_y, int invert, - struct nk_allocator *alloc) -{ - float y_scale_inv = invert ? -scale_y : scale_y; - struct nk_tt__edge *e; - int n,i,j,k,m; - int vsubsample = 1; - /* vsubsample should divide 255 evenly; otherwise we won't reach full opacity */ - - /* now we have to blow out the windings into explicit edge lists */ - n = 0; - for (i=0; i < windings; ++i) - n += wcount[i]; - - e = (struct nk_tt__edge*) - alloc->alloc(alloc->userdata, 0,(sizeof(*e) * (nk_size)(n+1))); - if (e == 0) return; - n = 0; - - m=0; - for (i=0; i < windings; ++i) - { - struct nk_tt__point *p = pts + m; - m += wcount[i]; - j = wcount[i]-1; - for (k=0; k < wcount[i]; j=k++) { - int a=k,b=j; - /* skip the edge if horizontal */ - if (p[j].y == p[k].y) - continue; - - /* add edge from j to k to the list */ - e[n].invert = 0; - if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) { - e[n].invert = 1; - a=j,b=k; - } - e[n].x0 = p[a].x * scale_x + shift_x; - e[n].y0 = (p[a].y * y_scale_inv + shift_y) * (float)vsubsample; - e[n].x1 = p[b].x * scale_x + shift_x; - e[n].y1 = (p[b].y * y_scale_inv + shift_y) * (float)vsubsample; - ++n; - } - } - - /* now sort the edges by their highest point (should snap to integer, and then by x) */ - /*STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare); */ - nk_tt__sort_edges(e, n); - /* now, traverse the scanlines and find the intersections on each scanline, use xor winding rule */ - nk_tt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, alloc); - alloc->free(alloc->userdata, e); -} - -NK_INTERN void -nk_tt__add_point(struct nk_tt__point *points, int n, float x, float y) -{ - if (!points) return; /* during first pass, it's unallocated */ - points[n].x = x; - points[n].y = y; -} - -NK_INTERN int -nk_tt__tesselate_curve(struct nk_tt__point *points, int *num_points, - float x0, float y0, float x1, float y1, float x2, float y2, - float objspace_flatness_squared, int n) -{ - /* tesselate until threshold p is happy... - * @TODO warped to compensate for non-linear stretching */ - /* midpoint */ - float mx = (x0 + 2*x1 + x2)/4; - float my = (y0 + 2*y1 + y2)/4; - /* versus directly drawn line */ - float dx = (x0+x2)/2 - mx; - float dy = (y0+y2)/2 - my; - if (n > 16) /* 65536 segments on one curve better be enough! */ - return 1; - - /* half-pixel error allowed... need to be smaller if AA */ - if (dx*dx+dy*dy > objspace_flatness_squared) { - nk_tt__tesselate_curve(points, num_points, x0,y0, - (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1); - nk_tt__tesselate_curve(points, num_points, mx,my, - (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1); - } else { - nk_tt__add_point(points, *num_points,x2,y2); - *num_points = *num_points+1; - } - return 1; -} - -/* returns number of contours */ -NK_INTERN struct nk_tt__point* -nk_tt_FlattenCurves(struct nk_tt_vertex *vertices, int num_verts, - float objspace_flatness, int **contour_lengths, int *num_contours, - struct nk_allocator *alloc) -{ - struct nk_tt__point *points=0; - int num_points=0; - float objspace_flatness_squared = objspace_flatness * objspace_flatness; - int i; - int n=0; - int start=0; - int pass; - - /* count how many "moves" there are to get the contour count */ - for (i=0; i < num_verts; ++i) - if (vertices[i].type == NK_TT_vmove) ++n; - - *num_contours = n; - if (n == 0) return 0; - - *contour_lengths = (int *) - alloc->alloc(alloc->userdata,0, (sizeof(**contour_lengths) * (nk_size)n)); - if (*contour_lengths == 0) { - *num_contours = 0; - return 0; - } - - /* make two passes through the points so we don't need to realloc */ - for (pass=0; pass < 2; ++pass) - { - float x=0,y=0; - if (pass == 1) { - points = (struct nk_tt__point *) - alloc->alloc(alloc->userdata,0, (nk_size)num_points * sizeof(points[0])); - if (points == 0) goto error; - } - num_points = 0; - n= -1; - - for (i=0; i < num_verts; ++i) - { - switch (vertices[i].type) { - case NK_TT_vmove: - /* start the next contour */ - if (n >= 0) - (*contour_lengths)[n] = num_points - start; - ++n; - start = num_points; - - x = vertices[i].x, y = vertices[i].y; - nk_tt__add_point(points, num_points++, x,y); - break; - case NK_TT_vline: - x = vertices[i].x, y = vertices[i].y; - nk_tt__add_point(points, num_points++, x, y); - break; - case NK_TT_vcurve: - nk_tt__tesselate_curve(points, &num_points, x,y, - vertices[i].cx, vertices[i].cy, - vertices[i].x, vertices[i].y, - objspace_flatness_squared, 0); - x = vertices[i].x, y = vertices[i].y; - break; - default: break; - } - } - (*contour_lengths)[n] = num_points - start; - } - return points; - -error: - alloc->free(alloc->userdata, points); - alloc->free(alloc->userdata, *contour_lengths); - *contour_lengths = 0; - *num_contours = 0; - return 0; -} - -NK_INTERN void -nk_tt_Rasterize(struct nk_tt__bitmap *result, float flatness_in_pixels, - struct nk_tt_vertex *vertices, int num_verts, - float scale_x, float scale_y, float shift_x, float shift_y, - int x_off, int y_off, int invert, struct nk_allocator *alloc) -{ - float scale = scale_x > scale_y ? scale_y : scale_x; - int winding_count, *winding_lengths; - struct nk_tt__point *windings = nk_tt_FlattenCurves(vertices, num_verts, - flatness_in_pixels / scale, &winding_lengths, &winding_count, alloc); - - NK_ASSERT(alloc); - if (windings) { - nk_tt__rasterize(result, windings, winding_lengths, winding_count, - scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, alloc); - alloc->free(alloc->userdata, winding_lengths); - alloc->free(alloc->userdata, windings); - } -} - -NK_INTERN void -nk_tt_MakeGlyphBitmapSubpixel(const struct nk_tt_fontinfo *info, unsigned char *output, - int out_w, int out_h, int out_stride, float scale_x, float scale_y, - float shift_x, float shift_y, int glyph, struct nk_allocator *alloc) -{ - int ix0,iy0; - struct nk_tt_vertex *vertices; - int num_verts = nk_tt_GetGlyphShape(info, alloc, glyph, &vertices); - struct nk_tt__bitmap gbm; - - nk_tt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, - shift_y, &ix0,&iy0,0,0); - gbm.pixels = output; - gbm.w = out_w; - gbm.h = out_h; - gbm.stride = out_stride; - - if (gbm.w && gbm.h) - nk_tt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, - shift_x, shift_y, ix0,iy0, 1, alloc); - alloc->free(alloc->userdata, vertices); -} - -/*------------------------------------------------------------- - * Bitmap baking - * --------------------------------------------------------------*/ -NK_INTERN int -nk_tt_PackBegin(struct nk_tt_pack_context *spc, unsigned char *pixels, - int pw, int ph, int stride_in_bytes, int padding, struct nk_allocator *alloc) -{ - int num_nodes = pw - padding; - struct nk_rp_context *context = (struct nk_rp_context *) - alloc->alloc(alloc->userdata,0, sizeof(*context)); - struct nk_rp_node *nodes = (struct nk_rp_node*) - alloc->alloc(alloc->userdata,0, (sizeof(*nodes ) * (nk_size)num_nodes)); - - if (context == 0 || nodes == 0) { - if (context != 0) alloc->free(alloc->userdata, context); - if (nodes != 0) alloc->free(alloc->userdata, nodes); - return 0; - } - - spc->width = pw; - spc->height = ph; - spc->pixels = pixels; - spc->pack_info = context; - spc->nodes = nodes; - spc->padding = padding; - spc->stride_in_bytes = (stride_in_bytes != 0) ? stride_in_bytes : pw; - spc->h_oversample = 1; - spc->v_oversample = 1; - - nk_rp_init_target(context, pw-padding, ph-padding, nodes, num_nodes); - if (pixels) - NK_MEMSET(pixels, 0, (nk_size)(pw*ph)); /* background of 0 around pixels */ - return 1; -} - -NK_INTERN void -nk_tt_PackEnd(struct nk_tt_pack_context *spc, struct nk_allocator *alloc) -{ - alloc->free(alloc->userdata, spc->nodes); - alloc->free(alloc->userdata, spc->pack_info); -} - -NK_INTERN void -nk_tt_PackSetOversampling(struct nk_tt_pack_context *spc, - unsigned int h_oversample, unsigned int v_oversample) -{ - NK_ASSERT(h_oversample <= NK_TT_MAX_OVERSAMPLE); - NK_ASSERT(v_oversample <= NK_TT_MAX_OVERSAMPLE); - if (h_oversample <= NK_TT_MAX_OVERSAMPLE) - spc->h_oversample = h_oversample; - if (v_oversample <= NK_TT_MAX_OVERSAMPLE) - spc->v_oversample = v_oversample; -} - -NK_INTERN void -nk_tt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, - int kernel_width) -{ - unsigned char buffer[NK_TT_MAX_OVERSAMPLE]; - int safe_w = w - kernel_width; - int j; - - for (j=0; j < h; ++j) - { - int i; - unsigned int total; - NK_MEMSET(buffer, 0, (nk_size)kernel_width); - - total = 0; - - /* make kernel_width a constant in common cases so compiler can optimize out the divide */ - switch (kernel_width) { - case 2: - for (i=0; i <= safe_w; ++i) { - total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]); - buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char) (total / 2); - } - break; - case 3: - for (i=0; i <= safe_w; ++i) { - total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]); - buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char) (total / 3); - } - break; - case 4: - for (i=0; i <= safe_w; ++i) { - total += (unsigned int)pixels[i] - buffer[i & NK_TT__OVER_MASK]; - buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char) (total / 4); - } - break; - case 5: - for (i=0; i <= safe_w; ++i) { - total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]); - buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char) (total / 5); - } - break; - default: - for (i=0; i <= safe_w; ++i) { - total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]); - buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char) (total / (unsigned int)kernel_width); - } - break; - } - - for (; i < w; ++i) { - NK_ASSERT(pixels[i] == 0); - total -= (unsigned int)(buffer[i & NK_TT__OVER_MASK]); - pixels[i] = (unsigned char) (total / (unsigned int)kernel_width); - } - pixels += stride_in_bytes; - } -} - -NK_INTERN void -nk_tt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, - int kernel_width) -{ - unsigned char buffer[NK_TT_MAX_OVERSAMPLE]; - int safe_h = h - kernel_width; - int j; - - for (j=0; j < w; ++j) - { - int i; - unsigned int total; - NK_MEMSET(buffer, 0, (nk_size)kernel_width); - - total = 0; - - /* make kernel_width a constant in common cases so compiler can optimize out the divide */ - switch (kernel_width) { - case 2: - for (i=0; i <= safe_h; ++i) { - total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]); - buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes]; - pixels[i*stride_in_bytes] = (unsigned char) (total / 2); - } - break; - case 3: - for (i=0; i <= safe_h; ++i) { - total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]); - buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes]; - pixels[i*stride_in_bytes] = (unsigned char) (total / 3); - } - break; - case 4: - for (i=0; i <= safe_h; ++i) { - total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]); - buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes]; - pixels[i*stride_in_bytes] = (unsigned char) (total / 4); - } - break; - case 5: - for (i=0; i <= safe_h; ++i) { - total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]); - buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes]; - pixels[i*stride_in_bytes] = (unsigned char) (total / 5); - } - break; - default: - for (i=0; i <= safe_h; ++i) { - total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]); - buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes]; - pixels[i*stride_in_bytes] = (unsigned char) (total / (unsigned int)kernel_width); - } - break; - } - - for (; i < h; ++i) { - NK_ASSERT(pixels[i*stride_in_bytes] == 0); - total -= (unsigned int)(buffer[i & NK_TT__OVER_MASK]); - pixels[i*stride_in_bytes] = (unsigned char) (total / (unsigned int)kernel_width); - } - pixels += 1; - } -} - -NK_INTERN float -nk_tt__oversample_shift(int oversample) -{ - if (!oversample) - return 0.0f; - - /* The prefilter is a box filter of width "oversample", */ - /* which shifts phase by (oversample - 1)/2 pixels in */ - /* oversampled space. We want to shift in the opposite */ - /* direction to counter this. */ - return (float)-(oversample - 1) / (2.0f * (float)oversample); -} - -/* rects array must be big enough to accommodate all characters in the given ranges */ -NK_INTERN int -nk_tt_PackFontRangesGatherRects(struct nk_tt_pack_context *spc, - struct nk_tt_fontinfo *info, struct nk_tt_pack_range *ranges, - int num_ranges, struct nk_rp_rect *rects) -{ - int i,j,k; - k = 0; - - for (i=0; i < num_ranges; ++i) { - float fh = ranges[i].font_size; - float scale = (fh > 0) ? nk_tt_ScaleForPixelHeight(info, fh): - nk_tt_ScaleForMappingEmToPixels(info, -fh); - ranges[i].h_oversample = (unsigned char) spc->h_oversample; - ranges[i].v_oversample = (unsigned char) spc->v_oversample; - for (j=0; j < ranges[i].num_chars; ++j) { - int x0,y0,x1,y1; - int codepoint = ranges[i].first_unicode_codepoint_in_range ? - ranges[i].first_unicode_codepoint_in_range + j : - ranges[i].array_of_unicode_codepoints[j]; - - int glyph = nk_tt_FindGlyphIndex(info, codepoint); - nk_tt_GetGlyphBitmapBoxSubpixel(info,glyph, scale * (float)spc->h_oversample, - scale * (float)spc->v_oversample, 0,0, &x0,&y0,&x1,&y1); - rects[k].w = (nk_rp_coord) (x1-x0 + spc->padding + (int)spc->h_oversample-1); - rects[k].h = (nk_rp_coord) (y1-y0 + spc->padding + (int)spc->v_oversample-1); - ++k; - } - } - return k; -} - -NK_INTERN int -nk_tt_PackFontRangesRenderIntoRects(struct nk_tt_pack_context *spc, - struct nk_tt_fontinfo *info, struct nk_tt_pack_range *ranges, - int num_ranges, struct nk_rp_rect *rects, struct nk_allocator *alloc) -{ - int i,j,k, return_value = 1; - /* save current values */ - int old_h_over = (int)spc->h_oversample; - int old_v_over = (int)spc->v_oversample; - /* rects array must be big enough to accommodate all characters in the given ranges */ - - k = 0; - for (i=0; i < num_ranges; ++i) - { - float fh = ranges[i].font_size; - float recip_h,recip_v,sub_x,sub_y; - float scale = fh > 0 ? nk_tt_ScaleForPixelHeight(info, fh): - nk_tt_ScaleForMappingEmToPixels(info, -fh); - - spc->h_oversample = ranges[i].h_oversample; - spc->v_oversample = ranges[i].v_oversample; - - recip_h = 1.0f / (float)spc->h_oversample; - recip_v = 1.0f / (float)spc->v_oversample; - - sub_x = nk_tt__oversample_shift((int)spc->h_oversample); - sub_y = nk_tt__oversample_shift((int)spc->v_oversample); - - for (j=0; j < ranges[i].num_chars; ++j) - { - struct nk_rp_rect *r = &rects[k]; - if (r->was_packed) - { - struct nk_tt_packedchar *bc = &ranges[i].chardata_for_range[j]; - int advance, lsb, x0,y0,x1,y1; - int codepoint = ranges[i].first_unicode_codepoint_in_range ? - ranges[i].first_unicode_codepoint_in_range + j : - ranges[i].array_of_unicode_codepoints[j]; - int glyph = nk_tt_FindGlyphIndex(info, codepoint); - nk_rp_coord pad = (nk_rp_coord) spc->padding; - - /* pad on left and top */ - r->x = (nk_rp_coord)((int)r->x + (int)pad); - r->y = (nk_rp_coord)((int)r->y + (int)pad); - r->w = (nk_rp_coord)((int)r->w - (int)pad); - r->h = (nk_rp_coord)((int)r->h - (int)pad); - - nk_tt_GetGlyphHMetrics(info, glyph, &advance, &lsb); - nk_tt_GetGlyphBitmapBox(info, glyph, scale * (float)spc->h_oversample, - (scale * (float)spc->v_oversample), &x0,&y0,&x1,&y1); - nk_tt_MakeGlyphBitmapSubpixel(info, spc->pixels + r->x + r->y*spc->stride_in_bytes, - (int)(r->w - spc->h_oversample+1), (int)(r->h - spc->v_oversample+1), - spc->stride_in_bytes, scale * (float)spc->h_oversample, - scale * (float)spc->v_oversample, 0,0, glyph, alloc); - - if (spc->h_oversample > 1) - nk_tt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes, - r->w, r->h, spc->stride_in_bytes, (int)spc->h_oversample); - - if (spc->v_oversample > 1) - nk_tt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes, - r->w, r->h, spc->stride_in_bytes, (int)spc->v_oversample); - - bc->x0 = (nk_ushort) r->x; - bc->y0 = (nk_ushort) r->y; - bc->x1 = (nk_ushort) (r->x + r->w); - bc->y1 = (nk_ushort) (r->y + r->h); - bc->xadvance = scale * (float)advance; - bc->xoff = (float) x0 * recip_h + sub_x; - bc->yoff = (float) y0 * recip_v + sub_y; - bc->xoff2 = ((float)x0 + r->w) * recip_h + sub_x; - bc->yoff2 = ((float)y0 + r->h) * recip_v + sub_y; - } else { - return_value = 0; /* if any fail, report failure */ - } - ++k; - } - } - /* restore original values */ - spc->h_oversample = (unsigned int)old_h_over; - spc->v_oversample = (unsigned int)old_v_over; - return return_value; -} - -NK_INTERN void -nk_tt_GetPackedQuad(struct nk_tt_packedchar *chardata, int pw, int ph, - int char_index, float *xpos, float *ypos, struct nk_tt_aligned_quad *q, - int align_to_integer) -{ - float ipw = 1.0f / (float)pw, iph = 1.0f / (float)ph; - struct nk_tt_packedchar *b = (struct nk_tt_packedchar*)(chardata + char_index); - if (align_to_integer) { - int tx = nk_ifloorf((*xpos + b->xoff) + 0.5f); - int ty = nk_ifloorf((*ypos + b->yoff) + 0.5f); - - float x = (float)tx; - float y = (float)ty; - - q->x0 = x; - q->y0 = y; - q->x1 = x + b->xoff2 - b->xoff; - q->y1 = y + b->yoff2 - b->yoff; - } else { - q->x0 = *xpos + b->xoff; - q->y0 = *ypos + b->yoff; - q->x1 = *xpos + b->xoff2; - q->y1 = *ypos + b->yoff2; - } - q->s0 = b->x0 * ipw; - q->t0 = b->y0 * iph; - q->s1 = b->x1 * ipw; - q->t1 = b->y1 * iph; - *xpos += b->xadvance; -} - -/* ------------------------------------------------------------- - * - * FONT BAKING - * - * --------------------------------------------------------------*/ -struct nk_font_bake_data { - struct nk_tt_fontinfo info; - struct nk_rp_rect *rects; - struct nk_tt_pack_range *ranges; - nk_rune range_count; -}; - -struct nk_font_baker { - struct nk_allocator alloc; - struct nk_tt_pack_context spc; - struct nk_font_bake_data *build; - struct nk_tt_packedchar *packed_chars; - struct nk_rp_rect *rects; - struct nk_tt_pack_range *ranges; -}; - -NK_GLOBAL const nk_size nk_rect_align = NK_ALIGNOF(struct nk_rp_rect); -NK_GLOBAL const nk_size nk_range_align = NK_ALIGNOF(struct nk_tt_pack_range); -NK_GLOBAL const nk_size nk_char_align = NK_ALIGNOF(struct nk_tt_packedchar); -NK_GLOBAL const nk_size nk_build_align = NK_ALIGNOF(struct nk_font_bake_data); -NK_GLOBAL const nk_size nk_baker_align = NK_ALIGNOF(struct nk_font_baker); - -NK_INTERN int -nk_range_count(const nk_rune *range) -{ - const nk_rune *iter = range; - NK_ASSERT(range); - if (!range) return 0; - while (*(iter++) != 0); - return (iter == range) ? 0 : (int)((iter - range)/2); -} - -NK_INTERN int -nk_range_glyph_count(const nk_rune *range, int count) -{ - int i = 0; - int total_glyphs = 0; - for (i = 0; i < count; ++i) { - int diff; - nk_rune f = range[(i*2)+0]; - nk_rune t = range[(i*2)+1]; - NK_ASSERT(t >= f); - diff = (int)((t - f) + 1); - total_glyphs += diff; - } - return total_glyphs; -} - -NK_API const nk_rune* -nk_font_default_glyph_ranges(void) -{ - NK_STORAGE const nk_rune ranges[] = {0x0020, 0x00FF, 0}; - return ranges; -} - -NK_API const nk_rune* -nk_font_chinese_glyph_ranges(void) -{ - NK_STORAGE const nk_rune ranges[] = { - 0x0020, 0x00FF, - 0x3000, 0x30FF, - 0x31F0, 0x31FF, - 0xFF00, 0xFFEF, - 0x4e00, 0x9FAF, - 0 - }; - return ranges; -} - -NK_API const nk_rune* -nk_font_cyrillic_glyph_ranges(void) -{ - NK_STORAGE const nk_rune ranges[] = { - 0x0020, 0x00FF, - 0x0400, 0x052F, - 0x2DE0, 0x2DFF, - 0xA640, 0xA69F, - 0 - }; - return ranges; -} - -NK_API const nk_rune* -nk_font_korean_glyph_ranges(void) -{ - NK_STORAGE const nk_rune ranges[] = { - 0x0020, 0x00FF, - 0x3131, 0x3163, - 0xAC00, 0xD79D, - 0 - }; - return ranges; -} - -NK_INTERN void -nk_font_baker_memory(nk_size *temp, int *glyph_count, - struct nk_font_config *config_list, int count) -{ - int range_count = 0; - int total_range_count = 0; - struct nk_font_config *iter; - - NK_ASSERT(config_list); - NK_ASSERT(glyph_count); - if (!config_list) { - *temp = 0; - *glyph_count = 0; - return; - } - - *glyph_count = 0; - if (!config_list->range) - config_list->range = nk_font_default_glyph_ranges(); - for (iter = config_list; iter; iter = iter->next) { - range_count = nk_range_count(iter->range); - total_range_count += range_count; - *glyph_count += nk_range_glyph_count(iter->range, range_count); - } - - *temp = (nk_size)*glyph_count * sizeof(struct nk_rp_rect); - *temp += (nk_size)total_range_count * sizeof(struct nk_tt_pack_range); - *temp += (nk_size)*glyph_count * sizeof(struct nk_tt_packedchar); - *temp += (nk_size)count * sizeof(struct nk_font_bake_data); - *temp += sizeof(struct nk_font_baker); - *temp += nk_rect_align + nk_range_align + nk_char_align; - *temp += nk_build_align + nk_baker_align; -} - -NK_INTERN struct nk_font_baker* -nk_font_baker(void *memory, int glyph_count, int count, struct nk_allocator *alloc) -{ - struct nk_font_baker *baker; - if (!memory) return 0; - /* setup baker inside a memory block */ - baker = (struct nk_font_baker*)NK_ALIGN_PTR(memory, nk_baker_align); - baker->build = (struct nk_font_bake_data*)NK_ALIGN_PTR((baker + 1), nk_build_align); - baker->packed_chars = (struct nk_tt_packedchar*)NK_ALIGN_PTR((baker->build + count), nk_char_align); - baker->rects = (struct nk_rp_rect*)NK_ALIGN_PTR((baker->packed_chars + glyph_count), nk_rect_align); - baker->ranges = (struct nk_tt_pack_range*)NK_ALIGN_PTR((baker->rects + glyph_count), nk_range_align); - baker->alloc = *alloc; - return baker; -} - -NK_INTERN int -nk_font_bake_pack(struct nk_font_baker *baker, - nk_size *image_memory, int *width, int *height, struct nk_recti *custom, - const struct nk_font_config *config_list, int count, - struct nk_allocator *alloc) -{ - NK_STORAGE const nk_size max_height = 1024 * 32; - const struct nk_font_config *config_iter; - int total_glyph_count = 0; - int total_range_count = 0; - int range_count = 0; - int i = 0; - - NK_ASSERT(image_memory); - NK_ASSERT(width); - NK_ASSERT(height); - NK_ASSERT(config_list); - NK_ASSERT(count); - NK_ASSERT(alloc); - - if (!image_memory || !width || !height || !config_list || !count) return nk_false; - for (config_iter = config_list; config_iter; config_iter = config_iter->next) { - range_count = nk_range_count(config_iter->range); - total_range_count += range_count; - total_glyph_count += nk_range_glyph_count(config_iter->range, range_count); - } - - /* setup font baker from temporary memory */ - for (config_iter = config_list; config_iter; config_iter = config_iter->next) { - const struct nk_font_config *cfg = config_iter; - if (!nk_tt_InitFont(&baker->build[i++].info, (const unsigned char*)cfg->ttf_blob, 0)) - return nk_false; - } - - *height = 0; - *width = (total_glyph_count > 1000) ? 1024 : 512; - nk_tt_PackBegin(&baker->spc, 0, (int)*width, (int)max_height, 0, 1, alloc); - { - int input_i = 0; - int range_n = 0; - int rect_n = 0; - int char_n = 0; - - /* pack custom user data first so it will be in the upper left corner*/ - if (custom) { - struct nk_rp_rect custom_space; - nk_zero(&custom_space, sizeof(custom_space)); - custom_space.w = (nk_rp_coord)((custom->w * 2) + 1); - custom_space.h = (nk_rp_coord)(custom->h + 1); - - nk_tt_PackSetOversampling(&baker->spc, 1, 1); - nk_rp_pack_rects((struct nk_rp_context*)baker->spc.pack_info, &custom_space, 1); - *height = NK_MAX(*height, (int)(custom_space.y + custom_space.h)); - - custom->x = (short)custom_space.x; - custom->y = (short)custom_space.y; - custom->w = (short)custom_space.w; - custom->h = (short)custom_space.h; - } - - /* first font pass: pack all glyphs */ - for (input_i = 0, config_iter = config_list; input_i < count && config_iter; - input_i++, config_iter = config_iter->next) - { - int n = 0; - int glyph_count; - const nk_rune *in_range; - const struct nk_font_config *cfg = config_iter; - struct nk_font_bake_data *tmp = &baker->build[input_i]; - - /* count glyphs + ranges in current font */ - glyph_count = 0; range_count = 0; - for (in_range = cfg->range; in_range[0] && in_range[1]; in_range += 2) { - glyph_count += (int)(in_range[1] - in_range[0]) + 1; - range_count++; - } - - /* setup ranges */ - tmp->ranges = baker->ranges + range_n; - tmp->range_count = (nk_rune)range_count; - range_n += range_count; - for (i = 0; i < range_count; ++i) { - in_range = &cfg->range[i * 2]; - tmp->ranges[i].font_size = cfg->size; - tmp->ranges[i].first_unicode_codepoint_in_range = (int)in_range[0]; - tmp->ranges[i].num_chars = (int)(in_range[1]- in_range[0]) + 1; - tmp->ranges[i].chardata_for_range = baker->packed_chars + char_n; - char_n += tmp->ranges[i].num_chars; - } - - /* pack */ - tmp->rects = baker->rects + rect_n; - rect_n += glyph_count; - nk_tt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v); - n = nk_tt_PackFontRangesGatherRects(&baker->spc, &tmp->info, - tmp->ranges, (int)tmp->range_count, tmp->rects); - nk_rp_pack_rects((struct nk_rp_context*)baker->spc.pack_info, tmp->rects, (int)n); - - /* texture height */ - for (i = 0; i < n; ++i) { - if (tmp->rects[i].was_packed) - *height = NK_MAX(*height, tmp->rects[i].y + tmp->rects[i].h); - } - } - NK_ASSERT(rect_n == total_glyph_count); - NK_ASSERT(char_n == total_glyph_count); - NK_ASSERT(range_n == total_range_count); - } - *height = (int)nk_round_up_pow2((nk_uint)*height); - *image_memory = (nk_size)(*width) * (nk_size)(*height); - return nk_true; -} - -NK_INTERN void -nk_font_bake(struct nk_font_baker *baker, void *image_memory, int width, int height, - struct nk_font_glyph *glyphs, int glyphs_count, - const struct nk_font_config *config_list, int font_count) -{ - int input_i = 0; - nk_rune glyph_n = 0; - const struct nk_font_config *config_iter; - - NK_ASSERT(image_memory); - NK_ASSERT(width); - NK_ASSERT(height); - NK_ASSERT(config_list); - NK_ASSERT(baker); - NK_ASSERT(font_count); - NK_ASSERT(glyphs_count); - if (!image_memory || !width || !height || !config_list || - !font_count || !glyphs || !glyphs_count) - return; - - /* second font pass: render glyphs */ - nk_zero(image_memory, (nk_size)((nk_size)width * (nk_size)height)); - baker->spc.pixels = (unsigned char*)image_memory; - baker->spc.height = (int)height; - for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter; - ++input_i, config_iter = config_iter->next) - { - const struct nk_font_config *cfg = config_iter; - struct nk_font_bake_data *tmp = &baker->build[input_i]; - nk_tt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v); - nk_tt_PackFontRangesRenderIntoRects(&baker->spc, &tmp->info, tmp->ranges, - (int)tmp->range_count, tmp->rects, &baker->alloc); - } - nk_tt_PackEnd(&baker->spc, &baker->alloc); - - /* third pass: setup font and glyphs */ - for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter; - ++input_i, config_iter = config_iter->next) - { - nk_size i = 0; - int char_idx = 0; - nk_rune glyph_count = 0; - const struct nk_font_config *cfg = config_iter; - struct nk_font_bake_data *tmp = &baker->build[input_i]; - struct nk_baked_font *dst_font = cfg->font; - - float font_scale = nk_tt_ScaleForPixelHeight(&tmp->info, cfg->size); - int unscaled_ascent, unscaled_descent, unscaled_line_gap; - nk_tt_GetFontVMetrics(&tmp->info, &unscaled_ascent, &unscaled_descent, - &unscaled_line_gap); - - /* fill baked font */ - if (!cfg->merge_mode) { - dst_font->ranges = cfg->range; - dst_font->height = cfg->size; - dst_font->ascent = ((float)unscaled_ascent * font_scale); - dst_font->descent = ((float)unscaled_descent * font_scale); - dst_font->glyph_offset = glyph_n; - } - - /* fill own baked font glyph array */ - for (i = 0; i < tmp->range_count; ++i) - { - struct nk_tt_pack_range *range = &tmp->ranges[i]; - for (char_idx = 0; char_idx < range->num_chars; char_idx++) - { - nk_rune codepoint = 0; - float dummy_x = 0, dummy_y = 0; - struct nk_tt_aligned_quad q; - struct nk_font_glyph *glyph; - - /* query glyph bounds from stb_truetype */ - const struct nk_tt_packedchar *pc = &range->chardata_for_range[char_idx]; - if (!pc->x0 && !pc->x1 && !pc->y0 && !pc->y1) continue; - codepoint = (nk_rune)(range->first_unicode_codepoint_in_range + char_idx); - nk_tt_GetPackedQuad(range->chardata_for_range, (int)width, - (int)height, char_idx, &dummy_x, &dummy_y, &q, 0); - - /* fill own glyph type with data */ - glyph = &glyphs[dst_font->glyph_offset + (unsigned int)glyph_count]; - glyph->codepoint = codepoint; - glyph->x0 = q.x0; glyph->y0 = q.y0; - glyph->x1 = q.x1; glyph->y1 = q.y1; - glyph->y0 += (dst_font->ascent + 0.5f); - glyph->y1 += (dst_font->ascent + 0.5f); - glyph->w = glyph->x1 - glyph->x0 + 0.5f; - glyph->h = glyph->y1 - glyph->y0; - - if (cfg->coord_type == NK_COORD_PIXEL) { - glyph->u0 = q.s0 * (float)width; - glyph->v0 = q.t0 * (float)height; - glyph->u1 = q.s1 * (float)width; - glyph->v1 = q.t1 * (float)height; - } else { - glyph->u0 = q.s0; - glyph->v0 = q.t0; - glyph->u1 = q.s1; - glyph->v1 = q.t1; - } - glyph->xadvance = (pc->xadvance + cfg->spacing.x); - if (cfg->pixel_snap) - glyph->xadvance = (float)(int)(glyph->xadvance + 0.5f); - glyph_count++; - } - } - dst_font->glyph_count = glyph_count; - glyph_n += dst_font->glyph_count; - } -} - -NK_INTERN void -nk_font_bake_custom_data(void *img_memory, int img_width, int img_height, - struct nk_recti img_dst, const char *texture_data_mask, int tex_width, - int tex_height, char white, char black) -{ - nk_byte *pixels; - int y = 0; - int x = 0; - int n = 0; - - NK_ASSERT(img_memory); - NK_ASSERT(img_width); - NK_ASSERT(img_height); - NK_ASSERT(texture_data_mask); - NK_UNUSED(tex_height); - if (!img_memory || !img_width || !img_height || !texture_data_mask) - return; - - pixels = (nk_byte*)img_memory; - for (y = 0, n = 0; y < tex_height; ++y) { - for (x = 0; x < tex_width; ++x, ++n) { - const int off0 = ((img_dst.x + x) + (img_dst.y + y) * img_width); - const int off1 = off0 + 1 + tex_width; - pixels[off0] = (texture_data_mask[n] == white) ? 0xFF : 0x00; - pixels[off1] = (texture_data_mask[n] == black) ? 0xFF : 0x00; - } - } -} - -NK_INTERN void -nk_font_bake_convert(void *out_memory, int img_width, int img_height, - const void *in_memory) -{ - int n = 0; - nk_rune *dst; - const nk_byte *src; - - NK_ASSERT(out_memory); - NK_ASSERT(in_memory); - NK_ASSERT(img_width); - NK_ASSERT(img_height); - if (!out_memory || !in_memory || !img_height || !img_width) return; - - dst = (nk_rune*)out_memory; - src = (const nk_byte*)in_memory; - for (n = (int)(img_width * img_height); n > 0; n--) - *dst++ = ((nk_rune)(*src++) << 24) | 0x00FFFFFF; -} - -/* ------------------------------------------------------------- - * - * FONT - * - * --------------------------------------------------------------*/ -NK_INTERN float -nk_font_text_width(nk_handle handle, float height, const char *text, int len) -{ - nk_rune unicode; - int text_len = 0; - float text_width = 0; - int glyph_len = 0; - float scale = 0; - - struct nk_font *font = (struct nk_font*)handle.ptr; - NK_ASSERT(font); - NK_ASSERT(font->glyphs); - if (!font || !text || !len) - return 0; - - scale = height/font->info.height; - glyph_len = text_len = nk_utf_decode(text, &unicode, (int)len); - if (!glyph_len) return 0; - while (text_len <= (int)len && glyph_len) { - const struct nk_font_glyph *g; - if (unicode == NK_UTF_INVALID) break; - - /* query currently drawn glyph information */ - g = nk_font_find_glyph(font, unicode); - text_width += g->xadvance * scale; - - /* offset next glyph */ - glyph_len = nk_utf_decode(text + text_len, &unicode, (int)len - text_len); - text_len += glyph_len; - } - return text_width; -} - -#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT -NK_INTERN void -nk_font_query_font_glyph(nk_handle handle, float height, - struct nk_user_font_glyph *glyph, nk_rune codepoint, nk_rune next_codepoint) -{ - float scale; - const struct nk_font_glyph *g; - struct nk_font *font; - - NK_ASSERT(glyph); - NK_UNUSED(next_codepoint); - - font = (struct nk_font*)handle.ptr; - NK_ASSERT(font); - NK_ASSERT(font->glyphs); - if (!font || !glyph) - return; - - scale = height/font->info.height; - g = nk_font_find_glyph(font, codepoint); - glyph->width = (g->x1 - g->x0) * scale; - glyph->height = (g->y1 - g->y0) * scale; - glyph->offset = nk_vec2(g->x0 * scale, g->y0 * scale); - glyph->xadvance = (g->xadvance * scale); - glyph->uv[0] = nk_vec2(g->u0, g->v0); - glyph->uv[1] = nk_vec2(g->u1, g->v1); -} -#endif - -NK_API const struct nk_font_glyph* -nk_font_find_glyph(struct nk_font *font, nk_rune unicode) -{ - int i = 0; - int count; - int total_glyphs = 0; - const struct nk_font_glyph *glyph = 0; - - NK_ASSERT(font); - NK_ASSERT(font->glyphs); - NK_ASSERT(font->info.ranges); - if (!font || !font->glyphs) return 0; - - glyph = font->fallback; - count = nk_range_count(font->info.ranges); - for (i = 0; i < count; ++i) { - int diff; - nk_rune f = font->info.ranges[(i*2)+0]; - nk_rune t = font->info.ranges[(i*2)+1]; - diff = (int)((t - f) + 1); - if (unicode >= f && unicode <= t) - return &font->glyphs[((nk_rune)total_glyphs + (unicode - f))]; - total_glyphs += diff; - } - return glyph; -} - -NK_INTERN void -nk_font_init(struct nk_font *font, float pixel_height, - nk_rune fallback_codepoint, struct nk_font_glyph *glyphs, - const struct nk_baked_font *baked_font, nk_handle atlas) -{ - struct nk_baked_font baked; - NK_ASSERT(font); - NK_ASSERT(glyphs); - NK_ASSERT(baked_font); - if (!font || !glyphs || !baked_font) - return; - - baked = *baked_font; - font->info = baked; - font->scale = (float)pixel_height / (float)font->info.height; - font->glyphs = &glyphs[baked_font->glyph_offset]; - font->texture = atlas; - font->fallback_codepoint = fallback_codepoint; - font->fallback = nk_font_find_glyph(font, fallback_codepoint); - - font->handle.height = font->info.height * font->scale; - font->handle.width = nk_font_text_width; - font->handle.userdata.ptr = font; -#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT - font->handle.query = nk_font_query_font_glyph; - font->handle.texture = font->texture; -#endif -} - -/* --------------------------------------------------------------------------- - * - * DEFAULT FONT - * - * ProggyClean.ttf - * Copyright (c) 2004, 2005 Tristan Grimmer - * MIT license (see License.txt in http://www.upperbounds.net/download/ProggyClean.ttf.zip) - * Download and more information at http://upperbounds.net - *-----------------------------------------------------------------------------*/ -#ifdef NK_INCLUDE_DEFAULT_FONT - - #ifdef __clang__ -#pragma clang diagnostic push - -#pragma clang diagnostic ignored "-Woverlength-strings" -#elif defined(__GNUC__) || defined(__GNUG__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Woverlength-strings" -#endif - -NK_GLOBAL const char nk_proggy_clean_ttf_compressed_data_base85[11980+1] = - "7])#######hV0qs'/###[),##/l:$#Q6>##5[n42>c-TH`->>#/e>11NNV=Bv(*:.F?uu#(gRU.o0XGH`$vhLG1hxt9?W`#,5LsCp#-i>.r$<$6pD>Lb';9Crc6tgXmKVeU2cD4Eo3R/" - "2*>]b(MC;$jPfY.;h^`IWM9Qo#t'X#(v#Y9w0#1D$CIf;W'#pWUPXOuxXuU(H9M(1=Ke$$'5F%)]0^#0X@U.a$FBjVQTSDgEKnIS7EM9>ZY9w0#L;>>#Mx&4Mvt//L[MkA#W@lK.N'[0#7RL_&#w+F%HtG9M#XL`N&.,GM4Pg;--VsM.M0rJfLH2eTM`*oJMHRC`N" - "kfimM2J,W-jXS:)r0wK#@Fge$U>`w'N7G#$#fB#$E^$#:9:hk+eOe--6x)F7*E%?76%^GMHePW-Z5l'&GiF#$956:rS?dA#fiK:)Yr+`�j@'DbG&#^$PG.Ll+DNa&VZ>1i%h1S9u5o@YaaW$e+bROPOpxTO7Stwi1::iB1q)C_=dV26J;2,]7op$]uQr@_V7$q^%lQwtuHY]=DX,n3L#0PHDO4f9>dC@O>HBuKPpP*E,N+b3L#lpR/MrTEH.IAQk.a>D[.e;mc." - "x]Ip.PH^'/aqUO/$1WxLoW0[iLAw=4h(9.`G" - "CRUxHPeR`5Mjol(dUWxZa(>STrPkrJiWx`5U7F#.g*jrohGg`cg:lSTvEY/EV_7H4Q9[Z%cnv;JQYZ5q.l7Zeas:HOIZOB?Ggv:[7MI2k).'2($5FNP&EQ(,)" - "U]W]+fh18.vsai00);D3@4ku5P?DP8aJt+;qUM]=+b'8@;mViBKx0DE[-auGl8:PJ&Dj+M6OC]O^((##]`0i)drT;-7X`=-H3[igUnPG-NZlo.#k@h#=Ork$m>a>$-?Tm$UV(?#P6YY#" - "'/###xe7q.73rI3*pP/$1>s9)W,JrM7SN]'/4C#v$U`0#V.[0>xQsH$fEmPMgY2u7Kh(G%siIfLSoS+MK2eTM$=5,M8p`A.;_R%#u[K#$x4AG8.kK/HSB==-'Ie/QTtG?-.*^N-4B/ZM" - "_3YlQC7(p7q)&](`6_c)$/*JL(L-^(]$wIM`dPtOdGA,U3:w2M-0+WomX2u7lqM2iEumMTcsF?-aT=Z-97UEnXglEn1K-bnEO`gu" - "Ft(c%=;Am_Qs@jLooI&NX;]0#j4#F14;gl8-GQpgwhrq8'=l_f-b49'UOqkLu7-##oDY2L(te+Mch&gLYtJ,MEtJfLh'x'M=$CS-ZZ%P]8bZ>#S?YY#%Q&q'3^Fw&?D)UDNrocM3A76/" - "/oL?#h7gl85[qW/NDOk%16ij;+:1a'iNIdb-ou8.P*w,v5#EI$TWS>Pot-R*H'-SEpA:g)f+O$%%`kA#G=8RMmG1&O`>to8bC]T&$,n.LoO>29sp3dt-52U%VM#q7'DHpg+#Z9%H[Ket`e;)f#Km8&+DC$I46>#Kr]]u-[=99tts1.qb#q72g1WJO81q+eN'03'eM>&1XxY-caEnO" - "j%2n8)),?ILR5^.Ibn<-X-Mq7[a82Lq:F&#ce+S9wsCK*x`569E8ew'He]h:sI[2LM$[guka3ZRd6:t%IG:;$%YiJ:Nq=?eAw;/:nnDq0(CYcMpG)qLN4$##&J-XTt,%OVU4)S1+R-#dg0/Nn?Ku1^0f$B*P:Rowwm-`0PKjYDDM'3]d39VZHEl4,.j']Pk-M.h^&:0FACm$maq-&sgw0t7/6(^xtk%" - "LuH88Fj-ekm>GA#_>568x6(OFRl-IZp`&b,_P'$MhLbxfc$mj`,O;&%W2m`Zh:/)Uetw:aJ%]K9h:TcF]u_-Sj9,VK3M.*'&0D[Ca]J9gp8,kAW]" - "%(?A%R$f<->Zts'^kn=-^@c4%-pY6qI%J%1IGxfLU9CP8cbPlXv);C=b),<2mOvP8up,UVf3839acAWAW-W?#ao/^#%KYo8fRULNd2.>%m]UK:n%r$'sw]J;5pAoO_#2mO3n,'=H5(et" - "Hg*`+RLgv>=4U8guD$I%D:W>-r5V*%j*W:Kvej.Lp$'?;++O'>()jLR-^u68PHm8ZFWe+ej8h:9r6L*0//c&iH&R8pRbA#Kjm%upV1g:" - "a_#Ur7FuA#(tRh#.Y5K+@?3<-8m0$PEn;J:rh6?I6uG<-`wMU'ircp0LaE_OtlMb&1#6T.#FDKu#1Lw%u%+GM+X'e?YLfjM[VO0MbuFp7;>Q&#WIo)0@F%q7c#4XAXN-U&VBpqB>0ie&jhZ[?iLR@@_AvA-iQC(=ksRZRVp7`.=+NpBC%rh&3]R:8XDmE5^V8O(x<-+k?'(^](H.aREZSi,#1:[IXaZFOm<-ui#qUq2$##Ri;u75OK#(RtaW-K-F`S+cF]uN`-KMQ%rP/Xri.LRcB##=YL3BgM/3M" - "D?@f&1'BW-)Ju#bmmWCMkk&#TR`C,5d>g)F;t,4:@_l8G/5h4vUd%&%950:VXD'QdWoY-F$BtUwmfe$YqL'8(PWX(" - "P?^@Po3$##`MSs?DWBZ/S>+4%>fX,VWv/w'KD`LP5IbH;rTV>n3cEK8U#bX]l-/V+^lj3;vlMb&[5YQ8#pekX9JP3XUC72L,,?+Ni&co7ApnO*5NK,((W-i:$,kp'UDAO(G0Sq7MVjJs" - "bIu)'Z,*[>br5fX^:FPAWr-m2KgLQ_nN6'8uTGT5g)uLv:873UpTLgH+#FgpH'_o1780Ph8KmxQJ8#H72L4@768@Tm&Q" - "h4CB/5OvmA&,Q&QbUoi$a_%3M01H)4x7I^&KQVgtFnV+;[Pc>[m4k//,]1?#`VY[Jr*3&&slRfLiVZJ:]?=K3Sw=[$=uRB?3xk48@aege0jT6'N#(q%.O=?2S]u*(m<-" - "V8J'(1)G][68hW$5'q[GC&5j`TE?m'esFGNRM)j,ffZ?-qx8;->g4t*:CIP/[Qap7/9'#(1sao7w-.qNUdkJ)tCF&#B^;xGvn2r9FEPFFFcL@.iFNkTve$m%#QvQS8U@)2Z+3K:AKM5i" - "sZ88+dKQ)W6>J%CL`.d*(B`-n8D9oK-XV1q['-5k'cAZ69e;D_?$ZPP&s^+7])$*$#@QYi9,5P r+$%CE=68>K8r0=dSC%%(@p7" - ".m7jilQ02'0-VWAgTlGW'b)Tq7VT9q^*^$$.:&N@@" - "$&)WHtPm*5_rO0&e%K&#-30j(E4#'Zb.o/(Tpm$>K'f@[PvFl,hfINTNU6u'0pao7%XUp9]5.>%h`8_=VYbxuel.NTSsJfLacFu3B'lQSu/m6-Oqem8T+oE--$0a/k]uj9EwsG>%veR*" - "hv^BFpQj:K'#SJ,sB-'#](j.Lg92rTw-*n%@/;39rrJF,l#qV%OrtBeC6/,;qB3ebNW[?,Hqj2L.1NP&GjUR=1D8QaS3Up&@*9wP?+lo7b?@%'k4`p0Z$22%K3+iCZj?XJN4Nm&+YF]u" - "@-W$U%VEQ/,,>>#)D#%8cY#YZ?=,`Wdxu/ae&#" - "w6)R89tI#6@s'(6Bf7a&?S=^ZI_kS&ai`&=tE72L_D,;^R)7[$so8lKN%5/$(vdfq7+ebA#" - "u1p]ovUKW&Y%q]'>$1@-[xfn$7ZTp7mM,G,Ko7a&Gu%G[RMxJs[0MM%wci.LFDK)(%:_i2B5CsR8&9Z&#=mPEnm0f`<&c)QL5uJ#%u%lJj+D-r;BoFDoS97h5g)E#o:&S4weDF,9^Hoe`h*L+_a*NrLW-1pG_&2UdB8" - "6e%B/:=>)N4xeW.*wft-;$'58-ESqr#U`'6AQ]m&6/`Z>#S?YY#Vc;r7U2&326d=w&H####?TZ`*4?&.MK?LP8Vxg>$[QXc%QJv92.(Db*B)gb*BM9dM*hJMAo*c&#" - "b0v=Pjer]$gG&JXDf->'StvU7505l9$AFvgYRI^&<^b68?j#q9QX4SM'RO#&sL1IM.rJfLUAj221]d##DW=m83u5;'bYx,*Sl0hL(W;;$doB&O/TQ:(Z^xBdLjLV#*8U_72Lh+2Q8Cj0i:6hp&$C/:p(HK>T8Y[gHQ4`4)'$Ab(Nof%V'8hL&#SfD07&6D@M.*J:;$-rv29'M]8qMv-tLp,'886iaC=Hb*YJoKJ,(j%K=H`K.v9HggqBIiZu'QvBT.#=)0ukruV&.)3=(^1`o*Pj4<-#MJ+gLq9-##@HuZPN0]u:h7.T..G:;$/Usj(T7`Q8tT72LnYl<-qx8;-HV7Q-&Xdx%1a,hC=0u+HlsV>nuIQL-5" - "_>@kXQtMacfD.m-VAb8;IReM3$wf0''hra*so568'Ip&vRs849'MRYSp%:t:h5qSgwpEr$B>Q,;s(C#$)`svQuF$##-D,##,g68@2[T;.XSdN9Qe)rpt._K-#5wF)sP'##p#C0c%-Gb%" - "hd+<-j'Ai*x&&HMkT]C'OSl##5RG[JXaHN;d'uA#x._U;.`PU@(Z3dt4r152@:v,'R.Sj'w#0<-;kPI)FfJ&#AYJ&#//)>-k=m=*XnK$>=)72L]0I%>.G690a:$##<,);?;72#?x9+d;" - "^V'9;jY@;)br#q^YQpx:X#Te$Z^'=-=bGhLf:D6&bNwZ9-ZD#n^9HhLMr5G;']d&6'wYmTFmLq9wI>P(9mI[>kC-ekLC/R&CH+s'B;K-M6$EB%is00:" - "+A4[7xks.LrNk0&E)wILYF@2L'0Nb$+pv<(2.768/FrY&h$^3i&@+G%JT'<-,v`3;_)I9M^AE]CN?Cl2AZg+%4iTpT3$U4O]GKx'm9)b@p7YsvK3w^YR-" - "CdQ*:Ir<($u&)#(&?L9Rg3H)4fiEp^iI9O8KnTj,]H?D*r7'M;PwZ9K0E^k&-cpI;.p/6_vwoFMV<->#%Xi.LxVnrU(4&8/P+:hLSKj$#U%]49t'I:rgMi'FL@a:0Y-uA[39',(vbma*" - "hU%<-SRF`Tt:542R_VV$p@[p8DV[A,?1839FWdFTi1O*H&#(AL8[_P%.M>v^-))qOT*F5Cq0`Ye%+$B6i:7@0IXSsDiWP,##P`%/L-" - "S(qw%sf/@%#B6;/U7K]uZbi^Oc^2n%t<)'mEVE''n`WnJra$^TKvX5B>;_aSEK',(hwa0:i4G?.Bci.(X[?b*($,=-n<.Q%`(X=?+@Am*Js0&=3bh8K]mL69=Lb,OcZV/);TTm8VI;?%OtJ<(b4mq7M6:u?KRdFl*:xP?Yb.5)%w_I?7uk5JC+FS(m#i'k.'a0i)9<7b'fs'59hq$*5Uhv##pi^8+hIEBF`nvo`;'l0.^S1<-wUK2/Coh58KKhLj" - "M=SO*rfO`+qC`W-On.=AJ56>>i2@2LH6A:&5q`?9I3@@'04&p2/LVa*T-4<-i3;M9UvZd+N7>b*eIwg:CC)c<>nO&#$(>.Z-I&J(Q0Hd5Q%7Co-b`-cP)hI;*_F]u`Rb[.j8_Q/<&>uu+VsH$sM9TA%?)(vmJ80),P7E>)tjD%2L=-t#fK[%`v=Q8WlA2);Sa" - ">gXm8YB`1d@K#n]76-a$U,mF%Ul:#/'xoFM9QX-$.QN'>" - "[%$Z$uF6pA6Ki2O5:8w*vP1<-1`[G,)-m#>0`P&#eb#.3i)rtB61(o'$?X3B2Qft^ae_5tKL9MUe9b*sLEQ95C&`=G?@Mj=wh*'3E>=-<)Gt*Iw)'QG:`@I" - "wOf7&]1i'S01B+Ev/Nac#9S;=;YQpg_6U`*kVY39xK,[/6Aj7:'1Bm-_1EYfa1+o&o4hp7KN_Q(OlIo@S%;jVdn0'1h19w,WQhLI)3S#f$2(eb,jr*b;3Vw]*7NH%$c4Vs,eD9>XW8?N]o+(*pgC%/72LV-uW%iewS8W6m2rtCpo'RS1R84=@paTKt)>=%&1[)*vp'u+x,VrwN;&]kuO9JDbg=pO$J*.jVe;u'm0dr9l,<*wMK*Oe=g8lV_KEBFkO'oU]^=[-792#ok,)" - "i]lR8qQ2oA8wcRCZ^7w/Njh;?.stX?Q1>S1q4Bn$)K1<-rGdO'$Wr.Lc.CG)$/*JL4tNR/,SVO3,aUw'DJN:)Ss;wGn9A32ijw%FL+Z0Fn.U9;reSq)bmI32U==5ALuG&#Vf1398/pVo" - "1*c-(aY168o<`JsSbk-,1N;$>0:OUas(3:8Z972LSfF8eb=c-;>SPw7.6hn3m`9^Xkn(r.qS[0;T%&Qc=+STRxX'q1BNk3&*eu2;&8q$&x>Q#Q7^Tf+6<(d%ZVmj2bDi%.3L2n+4W'$P" - "iDDG)g,r%+?,$@?uou5tSe2aN_AQU*'IAO" - "URQ##V^Fv-XFbGM7Fl(N<3DhLGF%q.1rC$#:T__&Pi68%0xi_&[qFJ(77j_&JWoF.V735&T,[R*:xFR*K5>>#`bW-?4Ne_&6Ne_&6Ne_&n`kr-#GJcM6X;uM6X;uM(.a..^2TkL%oR(#" - ";u.T%fAr%4tJ8&><1=GHZ_+m9/#H1F^R#SC#*N=BA9(D?v[UiFY>>^8p,KKF.W]L29uLkLlu/+4T" - "w$)F./^n3+rlo+DB;5sIYGNk+i1t-69Jg--0pao7Sm#K)pdHW&;LuDNH@H>#/X-TI(;P>#,Gc>#0Su>#4`1?#8lC?#xL$#B.`$#F:r$#JF.%#NR@%#R_R%#Vke%#Zww%#_-4^Rh%Sflr-k'MS.o?.5/sWel/wpEM0%3'/1)K^f1-d>G21&v(35>V`39V7A4=onx4" - "A1OY5EI0;6Ibgr6M$HS7Q<)58C5w,;WoA*#[%T*#`1g*#d=#+#hI5+#lUG+#pbY+#tnl+#x$),#&1;,#*=M,#.I`,#2Ur,#6b.-#;w[H#iQtA#m^0B#qjBB#uvTB##-hB#'9$C#+E6C#" - "/QHC#3^ZC#7jmC#;v)D#?,)4kMYD4lVu`4m`:&5niUA5@(A5BA1]PBB:xlBCC=2CDLXMCEUtiCf&0g2'tN?PGT4CPGT4CPGT4CPGT4CPGT4CPGT4CPGT4CP" - "GT4CPGT4CPGT4CPGT4CPGT4CPGT4CP-qekC`.9kEg^+F$kwViFJTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5o,^<-28ZI'O?;xp" - "O?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xp;7q-#lLYI:xvD=#"; -#endif /* NK_INCLUDE_DEFAULT_FONT */ - -#define NK_CURSOR_DATA_W 90 -#define NK_CURSOR_DATA_H 27 -NK_GLOBAL const char nk_custom_cursor_data[NK_CURSOR_DATA_W * NK_CURSOR_DATA_H + 1] = -{ - "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX" - "..- -X.....X- X.X - X.X -X.....X - X.....X" - "--- -XXX.XXX- X...X - X...X -X....X - X....X" - "X - X.X - X.....X - X.....X -X...X - X...X" - "XX - X.X -X.......X- X.......X -X..X.X - X.X..X" - "X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X" - "X..X - X.X - X.X - X.X -XX X.X - X.X XX" - "X...X - X.X - X.X - XX X.X XX - X.X - X.X " - "X....X - X.X - X.X - X.X X.X X.X - X.X - X.X " - "X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X " - "X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X " - "X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X " - "X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X " - "X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X " - "X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X " - "X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X " - "X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX " - "X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------" - "X.X X..X - -X.......X- X.......X - XX XX - " - "XX X..X - - X.....X - X.....X - X.X X.X - " - " X..X - X...X - X...X - X..X X..X - " - " XX - X.X - X.X - X...XXXXXXXXXXXXX...X - " - "------------ - X - X -X.....................X- " - " ----------------------------------- X...XXXXXXXXXXXXX...X - " - " - X..X X..X - " - " - X.X X.X - " - " - XX XX - " -}; - -#ifdef __clang__ -#pragma clang diagnostic pop -#elif defined(__GNUC__) || defined(__GNUG__) -#pragma GCC diagnostic pop -#endif - -NK_INTERN unsigned int -nk_decompress_length(unsigned char *input) -{ - return (unsigned int)((input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11]); -} - -NK_GLOBAL unsigned char *nk__barrier; -NK_GLOBAL unsigned char *nk__barrier2; -NK_GLOBAL unsigned char *nk__barrier3; -NK_GLOBAL unsigned char *nk__barrier4; -NK_GLOBAL unsigned char *nk__dout; - -NK_INTERN void -nk__match(unsigned char *data, unsigned int length) -{ - /* INVERSE of memmove... write each byte before copying the next...*/ - NK_ASSERT (nk__dout + length <= nk__barrier); - if (nk__dout + length > nk__barrier) { nk__dout += length; return; } - if (data < nk__barrier4) { nk__dout = nk__barrier+1; return; } - while (length--) *nk__dout++ = *data++; -} - -NK_INTERN void -nk__lit(unsigned char *data, unsigned int length) -{ - NK_ASSERT (nk__dout + length <= nk__barrier); - if (nk__dout + length > nk__barrier) { nk__dout += length; return; } - if (data < nk__barrier2) { nk__dout = nk__barrier+1; return; } - NK_MEMCPY(nk__dout, data, length); - nk__dout += length; -} - -#define nk__in2(x) ((i[x] << 8) + i[(x)+1]) -#define nk__in3(x) ((i[x] << 16) + nk__in2((x)+1)) -#define nk__in4(x) ((i[x] << 24) + nk__in3((x)+1)) - -NK_INTERN unsigned char* -nk_decompress_token(unsigned char *i) -{ - if (*i >= 0x20) { /* use fewer if's for cases that expand small */ - if (*i >= 0x80) nk__match(nk__dout-i[1]-1, (unsigned int)i[0] - 0x80 + 1), i += 2; - else if (*i >= 0x40) nk__match(nk__dout-(nk__in2(0) - 0x4000 + 1), (unsigned int)i[2]+1), i += 3; - else /* *i >= 0x20 */ nk__lit(i+1, (unsigned int)i[0] - 0x20 + 1), i += 1 + (i[0] - 0x20 + 1); - } else { /* more ifs for cases that expand large, since overhead is amortized */ - if (*i >= 0x18) nk__match(nk__dout-(unsigned int)(nk__in3(0) - 0x180000 + 1), (unsigned int)i[3]+1), i += 4; - else if (*i >= 0x10) nk__match(nk__dout-(unsigned int)(nk__in3(0) - 0x100000 + 1), (unsigned int)nk__in2(3)+1), i += 5; - else if (*i >= 0x08) nk__lit(i+2, (unsigned int)nk__in2(0) - 0x0800 + 1), i += 2 + (nk__in2(0) - 0x0800 + 1); - else if (*i == 0x07) nk__lit(i+3, (unsigned int)nk__in2(1) + 1), i += 3 + (nk__in2(1) + 1); - else if (*i == 0x06) nk__match(nk__dout-(unsigned int)(nk__in3(1)+1), i[4]+1u), i += 5; - else if (*i == 0x04) nk__match(nk__dout-(unsigned int)(nk__in3(1)+1), (unsigned int)nk__in2(4)+1u), i += 6; - } - return i; -} - -NK_INTERN unsigned int -nk_adler32(unsigned int adler32, unsigned char *buffer, unsigned int buflen) -{ - const unsigned long ADLER_MOD = 65521; - unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16; - unsigned long blocklen, i; - - blocklen = buflen % 5552; - while (buflen) { - for (i=0; i + 7 < blocklen; i += 8) { - s1 += buffer[0]; s2 += s1; - s1 += buffer[1]; s2 += s1; - s1 += buffer[2]; s2 += s1; - s1 += buffer[3]; s2 += s1; - s1 += buffer[4]; s2 += s1; - s1 += buffer[5]; s2 += s1; - s1 += buffer[6]; s2 += s1; - s1 += buffer[7]; s2 += s1; - buffer += 8; - } - for (; i < blocklen; ++i) { - s1 += *buffer++; s2 += s1; - } - - s1 %= ADLER_MOD; s2 %= ADLER_MOD; - buflen -= (unsigned int)blocklen; - blocklen = 5552; - } - return (unsigned int)(s2 << 16) + (unsigned int)s1; -} - -NK_INTERN unsigned int -nk_decompress(unsigned char *output, unsigned char *i, unsigned int length) -{ - unsigned int olen; - if (nk__in4(0) != 0x57bC0000) return 0; - if (nk__in4(4) != 0) return 0; /* error! stream is > 4GB */ - olen = nk_decompress_length(i); - nk__barrier2 = i; - nk__barrier3 = i+length; - nk__barrier = output + olen; - nk__barrier4 = output; - i += 16; - - nk__dout = output; - for (;;) { - unsigned char *old_i = i; - i = nk_decompress_token(i); - if (i == old_i) { - if (*i == 0x05 && i[1] == 0xfa) { - NK_ASSERT(nk__dout == output + olen); - if (nk__dout != output + olen) return 0; - if (nk_adler32(1, output, olen) != (unsigned int) nk__in4(2)) - return 0; - return olen; - } else { - NK_ASSERT(0); /* NOTREACHED */ - return 0; - } - } - NK_ASSERT(nk__dout <= output + olen); - if (nk__dout > output + olen) - return 0; - } -} - -NK_INTERN unsigned int -nk_decode_85_byte(char c) -{ return (unsigned int)((c >= '\\') ? c-36 : c-35); } - -NK_INTERN void -nk_decode_85(unsigned char* dst, const unsigned char* src) -{ - while (*src) - { - unsigned int tmp = - nk_decode_85_byte((char)src[0]) + - 85 * (nk_decode_85_byte((char)src[1]) + - 85 * (nk_decode_85_byte((char)src[2]) + - 85 * (nk_decode_85_byte((char)src[3]) + - 85 * nk_decode_85_byte((char)src[4])))); - - /* we can't assume little-endianess. */ - dst[0] = (unsigned char)((tmp >> 0) & 0xFF); - dst[1] = (unsigned char)((tmp >> 8) & 0xFF); - dst[2] = (unsigned char)((tmp >> 16) & 0xFF); - dst[3] = (unsigned char)((tmp >> 24) & 0xFF); - - src += 5; - dst += 4; - } -} - -/* ------------------------------------------------------------- - * - * FONT ATLAS - * - * --------------------------------------------------------------*/ -NK_API struct nk_font_config -nk_font_config(float pixel_height) -{ - struct nk_font_config cfg; - nk_zero_struct(cfg); - cfg.ttf_blob = 0; - cfg.ttf_size = 0; - cfg.ttf_data_owned_by_atlas = 0; - cfg.size = pixel_height; - cfg.oversample_h = 3; - cfg.oversample_v = 1; - cfg.pixel_snap = 0; - cfg.coord_type = NK_COORD_UV; - cfg.spacing = nk_vec2(0,0); - cfg.range = nk_font_default_glyph_ranges(); - cfg.merge_mode = 0; - cfg.fallback_glyph = '?'; - cfg.font = 0; - return cfg; -} - -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_API void -nk_font_atlas_init_default(struct nk_font_atlas *atlas) -{ - NK_ASSERT(atlas); - if (!atlas) return; - nk_zero_struct(*atlas); - atlas->temporary.userdata.ptr = 0; - atlas->temporary.alloc = nk_malloc; - atlas->temporary.free = nk_mfree; - atlas->permanent.userdata.ptr = 0; - atlas->permanent.alloc = nk_malloc; - atlas->permanent.free = nk_mfree; -} -#endif - -NK_API void -nk_font_atlas_init(struct nk_font_atlas *atlas, struct nk_allocator *alloc) -{ - NK_ASSERT(atlas); - NK_ASSERT(alloc); - if (!atlas || !alloc) return; - nk_zero_struct(*atlas); - atlas->permanent = *alloc; - atlas->temporary = *alloc; -} - -NK_API void -nk_font_atlas_init_custom(struct nk_font_atlas *atlas, - struct nk_allocator *permanent, struct nk_allocator *temporary) -{ - NK_ASSERT(atlas); - NK_ASSERT(permanent); - NK_ASSERT(temporary); - if (!atlas || !permanent || !temporary) return; - nk_zero_struct(*atlas); - atlas->permanent = *permanent; - atlas->temporary = *temporary; -} - -NK_API void -nk_font_atlas_begin(struct nk_font_atlas *atlas) -{ - NK_ASSERT(atlas); - NK_ASSERT(atlas->temporary.alloc && atlas->temporary.free); - NK_ASSERT(atlas->permanent.alloc && atlas->permanent.free); - if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free || - !atlas->temporary.alloc || !atlas->temporary.free) return; - if (atlas->glyphs) { - atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs); - atlas->glyphs = 0; - } - if (atlas->pixel) { - atlas->permanent.free(atlas->permanent.userdata, atlas->pixel); - atlas->pixel = 0; - } -} - -NK_API struct nk_font* -nk_font_atlas_add(struct nk_font_atlas *atlas, const struct nk_font_config *config) -{ - struct nk_font *font = 0; - struct nk_font_config *cfg; - - NK_ASSERT(atlas); - NK_ASSERT(atlas->permanent.alloc); - NK_ASSERT(atlas->permanent.free); - NK_ASSERT(atlas->temporary.alloc); - NK_ASSERT(atlas->temporary.free); - - NK_ASSERT(config); - NK_ASSERT(config->ttf_blob); - NK_ASSERT(config->ttf_size); - NK_ASSERT(config->size > 0.0f); - - if (!atlas || !config || !config->ttf_blob || !config->ttf_size || config->size <= 0.0f|| - !atlas->permanent.alloc || !atlas->permanent.free || - !atlas->temporary.alloc || !atlas->temporary.free) - return 0; - - /* allocate and insert font config into list */ - cfg = (struct nk_font_config*) - atlas->permanent.alloc(atlas->permanent.userdata,0, sizeof(struct nk_font_config)); - NK_MEMCPY(cfg, config, sizeof(*config)); - if (!atlas->config) { - atlas->config = cfg; - cfg->next = 0; - } else { - cfg->next = atlas->config; - atlas->config = cfg; - } - - /* allocate new font */ - if (!config->merge_mode) { - font = (struct nk_font*) - atlas->permanent.alloc(atlas->permanent.userdata,0, sizeof(struct nk_font)); - NK_ASSERT(font); - if (!font) return 0; - font->config = cfg; - } else { - NK_ASSERT(atlas->font_num); - font = atlas->fonts; - font->config = cfg; - } - - /* insert font into list */ - if (!config->merge_mode) { - if (!atlas->fonts) { - atlas->fonts = font; - font->next = 0; - } else { - font->next = atlas->fonts; - atlas->fonts = font; - } - cfg->font = &font->info; - } - - /* create own copy of .TTF font blob */ - if (!config->ttf_data_owned_by_atlas) { - cfg->ttf_blob = atlas->permanent.alloc(atlas->permanent.userdata,0, cfg->ttf_size); - NK_ASSERT(cfg->ttf_blob); - if (!cfg->ttf_blob) { - atlas->font_num++; - return 0; - } - NK_MEMCPY(cfg->ttf_blob, config->ttf_blob, cfg->ttf_size); - cfg->ttf_data_owned_by_atlas = 1; - } - atlas->font_num++; - return font; -} - -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) -{ - struct nk_font_config cfg; - NK_ASSERT(memory); - NK_ASSERT(size); - - NK_ASSERT(atlas); - NK_ASSERT(atlas->temporary.alloc); - NK_ASSERT(atlas->temporary.free); - NK_ASSERT(atlas->permanent.alloc); - NK_ASSERT(atlas->permanent.free); - if (!atlas || !atlas->temporary.alloc || !atlas->temporary.free || !memory || !size || - !atlas->permanent.alloc || !atlas->permanent.free) - return 0; - - cfg = (config) ? *config: nk_font_config(height); - cfg.ttf_blob = memory; - cfg.ttf_size = size; - cfg.size = height; - cfg.ttf_data_owned_by_atlas = 0; - return nk_font_atlas_add(atlas, &cfg); -} - -#ifdef NK_INCLUDE_STANDARD_IO -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 *config) -{ - nk_size size; - char *memory; - struct nk_font_config cfg; - - NK_ASSERT(atlas); - NK_ASSERT(atlas->temporary.alloc); - NK_ASSERT(atlas->temporary.free); - NK_ASSERT(atlas->permanent.alloc); - NK_ASSERT(atlas->permanent.free); - - if (!atlas || !file_path) return 0; - memory = nk_file_load(file_path, &size, &atlas->permanent); - if (!memory) return 0; - - cfg = (config) ? *config: nk_font_config(height); - cfg.ttf_blob = memory; - cfg.ttf_size = size; - cfg.size = height; - cfg.ttf_data_owned_by_atlas = 1; - return nk_font_atlas_add(atlas, &cfg); -} -#endif - -NK_API struct nk_font* -nk_font_atlas_add_compressed(struct nk_font_atlas *atlas, - void *compressed_data, nk_size compressed_size, float height, - const struct nk_font_config *config) -{ - unsigned int decompressed_size; - void *decompressed_data; - struct nk_font_config cfg; - - NK_ASSERT(atlas); - NK_ASSERT(atlas->temporary.alloc); - NK_ASSERT(atlas->temporary.free); - NK_ASSERT(atlas->permanent.alloc); - NK_ASSERT(atlas->permanent.free); - - NK_ASSERT(compressed_data); - NK_ASSERT(compressed_size); - if (!atlas || !compressed_data || !atlas->temporary.alloc || !atlas->temporary.free || - !atlas->permanent.alloc || !atlas->permanent.free) - return 0; - - decompressed_size = nk_decompress_length((unsigned char*)compressed_data); - decompressed_data = atlas->permanent.alloc(atlas->permanent.userdata,0,decompressed_size); - NK_ASSERT(decompressed_data); - if (!decompressed_data) return 0; - nk_decompress((unsigned char*)decompressed_data, (unsigned char*)compressed_data, - (unsigned int)compressed_size); - - cfg = (config) ? *config: nk_font_config(height); - cfg.ttf_blob = decompressed_data; - cfg.ttf_size = decompressed_size; - cfg.size = height; - cfg.ttf_data_owned_by_atlas = 1; - return nk_font_atlas_add(atlas, &cfg); -} - -NK_API struct nk_font* -nk_font_atlas_add_compressed_base85(struct nk_font_atlas *atlas, - const char *data_base85, float height, const struct nk_font_config *config) -{ - int compressed_size; - void *compressed_data; - struct nk_font *font; - - NK_ASSERT(atlas); - NK_ASSERT(atlas->temporary.alloc); - NK_ASSERT(atlas->temporary.free); - NK_ASSERT(atlas->permanent.alloc); - NK_ASSERT(atlas->permanent.free); - - NK_ASSERT(data_base85); - if (!atlas || !data_base85 || !atlas->temporary.alloc || !atlas->temporary.free || - !atlas->permanent.alloc || !atlas->permanent.free) - return 0; - - compressed_size = (((int)nk_strlen(data_base85) + 4) / 5) * 4; - compressed_data = atlas->temporary.alloc(atlas->temporary.userdata,0, (nk_size)compressed_size); - NK_ASSERT(compressed_data); - if (!compressed_data) return 0; - nk_decode_85((unsigned char*)compressed_data, (const unsigned char*)data_base85); - font = nk_font_atlas_add_compressed(atlas, compressed_data, - (nk_size)compressed_size, height, config); - atlas->temporary.free(atlas->temporary.userdata, compressed_data); - return font; -} - -#ifdef NK_INCLUDE_DEFAULT_FONT -NK_API struct nk_font* -nk_font_atlas_add_default(struct nk_font_atlas *atlas, - float pixel_height, const struct nk_font_config *config) -{ - NK_ASSERT(atlas); - NK_ASSERT(atlas->temporary.alloc); - NK_ASSERT(atlas->temporary.free); - NK_ASSERT(atlas->permanent.alloc); - NK_ASSERT(atlas->permanent.free); - return nk_font_atlas_add_compressed_base85(atlas, - nk_proggy_clean_ttf_compressed_data_base85, pixel_height, config); -} -#endif - -NK_API const void* -nk_font_atlas_bake(struct nk_font_atlas *atlas, int *width, int *height, - enum nk_font_atlas_format fmt) -{ - int i = 0; - void *tmp = 0; - nk_size tmp_size, img_size; - struct nk_font *font_iter; - struct nk_font_baker *baker; - - NK_ASSERT(atlas); - NK_ASSERT(atlas->temporary.alloc); - NK_ASSERT(atlas->temporary.free); - NK_ASSERT(atlas->permanent.alloc); - NK_ASSERT(atlas->permanent.free); - - NK_ASSERT(width); - NK_ASSERT(height); - if (!atlas || !width || !height || - !atlas->temporary.alloc || !atlas->temporary.free || - !atlas->permanent.alloc || !atlas->permanent.free) - return 0; - -#ifdef NK_INCLUDE_DEFAULT_FONT - /* no font added so just use default font */ - if (!atlas->font_num) - atlas->default_font = nk_font_atlas_add_default(atlas, 13.0f, 0); -#endif - NK_ASSERT(atlas->font_num); - if (!atlas->font_num) return 0; - - /* allocate temporary baker memory required for the baking process */ - nk_font_baker_memory(&tmp_size, &atlas->glyph_count, atlas->config, atlas->font_num); - tmp = atlas->temporary.alloc(atlas->temporary.userdata,0, tmp_size); - NK_ASSERT(tmp); - if (!tmp) goto failed; - - /* allocate glyph memory for all fonts */ - baker = nk_font_baker(tmp, atlas->glyph_count, atlas->font_num, &atlas->temporary); - atlas->glyphs = (struct nk_font_glyph*)atlas->permanent.alloc( - atlas->permanent.userdata,0, sizeof(struct nk_font_glyph)*(nk_size)atlas->glyph_count); - NK_ASSERT(atlas->glyphs); - if (!atlas->glyphs) - goto failed; - - /* pack all glyphs into a tight fit space */ - atlas->custom.w = (NK_CURSOR_DATA_W*2)+1; - atlas->custom.h = NK_CURSOR_DATA_H + 1; - if (!nk_font_bake_pack(baker, &img_size, width, height, &atlas->custom, - atlas->config, atlas->font_num, &atlas->temporary)) - goto failed; - - /* allocate memory for the baked image font atlas */ - atlas->pixel = atlas->temporary.alloc(atlas->temporary.userdata,0, img_size); - NK_ASSERT(atlas->pixel); - if (!atlas->pixel) - goto failed; - - /* bake glyphs and custom white pixel into image */ - nk_font_bake(baker, atlas->pixel, *width, *height, - atlas->glyphs, atlas->glyph_count, atlas->config, atlas->font_num); - nk_font_bake_custom_data(atlas->pixel, *width, *height, atlas->custom, - nk_custom_cursor_data, NK_CURSOR_DATA_W, NK_CURSOR_DATA_H, '.', 'X'); - - if (fmt == NK_FONT_ATLAS_RGBA32) { - /* convert alpha8 image into rgba32 image */ - void *img_rgba = atlas->temporary.alloc(atlas->temporary.userdata,0, - (nk_size)(*width * *height * 4)); - NK_ASSERT(img_rgba); - if (!img_rgba) goto failed; - nk_font_bake_convert(img_rgba, *width, *height, atlas->pixel); - atlas->temporary.free(atlas->temporary.userdata, atlas->pixel); - atlas->pixel = img_rgba; - } - atlas->tex_width = *width; - atlas->tex_height = *height; - - /* initialize each font */ - for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) { - struct nk_font *font = font_iter; - struct nk_font_config *config = font->config; - nk_font_init(font, config->size, config->fallback_glyph, atlas->glyphs, - config->font, nk_handle_ptr(0)); - } - - /* initialize each cursor */ - {NK_STORAGE const struct nk_vec2 nk_cursor_data[NK_CURSOR_COUNT][3] = { - /* Pos ----- Size ------- Offset --*/ - {{ 0, 3}, {12,19}, { 0, 0}}, - {{13, 0}, { 7,16}, { 4, 8}}, - {{31, 0}, {23,23}, {11,11}}, - {{21, 0}, { 9, 23}, { 5,11}}, - {{55,18}, {23, 9}, {11, 5}}, - {{73, 0}, {17,17}, { 9, 9}}, - {{55, 0}, {17,17}, { 9, 9}} - }; - for (i = 0; i < NK_CURSOR_COUNT; ++i) { - struct nk_cursor *cursor = &atlas->cursors[i]; - cursor->img.w = (unsigned short)*width; - cursor->img.h = (unsigned short)*height; - cursor->img.region[0] = (unsigned short)(atlas->custom.x + nk_cursor_data[i][0].x); - cursor->img.region[1] = (unsigned short)(atlas->custom.y + nk_cursor_data[i][0].y); - cursor->img.region[2] = (unsigned short)nk_cursor_data[i][1].x; - cursor->img.region[3] = (unsigned short)nk_cursor_data[i][1].y; - cursor->size = nk_cursor_data[i][1]; - cursor->offset = nk_cursor_data[i][2]; - }} - /* free temporary memory */ - atlas->temporary.free(atlas->temporary.userdata, tmp); - return atlas->pixel; - -failed: - /* error so cleanup all memory */ - if (tmp) atlas->temporary.free(atlas->temporary.userdata, tmp); - if (atlas->glyphs) { - atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs); - atlas->glyphs = 0; - } - if (atlas->pixel) { - atlas->temporary.free(atlas->temporary.userdata, atlas->pixel); - atlas->pixel = 0; - } - return 0; -} - -NK_API void -nk_font_atlas_end(struct nk_font_atlas *atlas, nk_handle texture, - struct nk_draw_null_texture *null) -{ - int i = 0; - struct nk_font *font_iter; - NK_ASSERT(atlas); - if (!atlas) { - if (!null) return; - null->texture = texture; - null->uv = nk_vec2(0.5f,0.5f); - } - if (null) { - null->texture = texture; - null->uv.x = (atlas->custom.x + 0.5f)/(float)atlas->tex_width; - null->uv.y = (atlas->custom.y + 0.5f)/(float)atlas->tex_height; - } - for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) { - font_iter->texture = texture; -#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT - font_iter->handle.texture = texture; -#endif - } - for (i = 0; i < NK_CURSOR_COUNT; ++i) - atlas->cursors[i].img.handle = texture; - - atlas->temporary.free(atlas->temporary.userdata, atlas->pixel); - atlas->pixel = 0; - atlas->tex_width = 0; - atlas->tex_height = 0; - atlas->custom.x = 0; - atlas->custom.y = 0; - atlas->custom.w = 0; - atlas->custom.h = 0; -} - -NK_API void -nk_font_atlas_cleanup(struct nk_font_atlas *atlas) -{ - NK_ASSERT(atlas); - NK_ASSERT(atlas->temporary.alloc); - NK_ASSERT(atlas->temporary.free); - NK_ASSERT(atlas->permanent.alloc); - NK_ASSERT(atlas->permanent.free); - - if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free) return; - if (atlas->config) { - struct nk_font_config *iter, *next; - for (iter = atlas->config; iter; iter = next) { - next = iter->next; - atlas->permanent.free(atlas->permanent.userdata, iter->ttf_blob); - atlas->permanent.free(atlas->permanent.userdata, iter); - } - } -} - -NK_API void -nk_font_atlas_clear(struct nk_font_atlas *atlas) -{ - NK_ASSERT(atlas); - NK_ASSERT(atlas->temporary.alloc); - NK_ASSERT(atlas->temporary.free); - NK_ASSERT(atlas->permanent.alloc); - NK_ASSERT(atlas->permanent.free); - if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free) return; - - nk_font_atlas_cleanup(atlas); - if (atlas->fonts) { - struct nk_font *iter, *next; - for (iter = atlas->fonts; iter; iter = next) { - next = iter->next; - atlas->permanent.free(atlas->permanent.userdata, iter); - } - atlas->fonts = 0; - } - if (atlas->glyphs) - atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs); - nk_zero_struct(*atlas); -} -#endif -/* ============================================================== - * - * INPUT - * - * ===============================================================*/ -NK_API void -nk_input_begin(struct nk_context *ctx) -{ - int i; - struct nk_input *in; - NK_ASSERT(ctx); - if (!ctx) return; - in = &ctx->input; - for (i = 0; i < NK_BUTTON_MAX; ++i) - in->mouse.buttons[i].clicked = 0; - - in->keyboard.text_len = 0; - in->mouse.scroll_delta = 0; - in->mouse.prev.x = in->mouse.pos.x; - in->mouse.prev.y = in->mouse.pos.y; - in->mouse.delta.x = 0; - in->mouse.delta.y = 0; - for (i = 0; i < NK_KEY_MAX; i++) - in->keyboard.keys[i].clicked = 0; -} - -NK_API void -nk_input_end(struct nk_context *ctx) -{ - struct nk_input *in; - NK_ASSERT(ctx); - if (!ctx) return; - in = &ctx->input; - if (in->mouse.grab) - in->mouse.grab = 0; - if (in->mouse.ungrab) { - in->mouse.grabbed = 0; - in->mouse.ungrab = 0; - in->mouse.grab = 0; - } -} - -NK_API void -nk_input_motion(struct nk_context *ctx, int x, int y) -{ - struct nk_input *in; - NK_ASSERT(ctx); - if (!ctx) return; - in = &ctx->input; - in->mouse.pos.x = (float)x; - in->mouse.pos.y = (float)y; - in->mouse.delta.x = in->mouse.pos.x - in->mouse.prev.x; - in->mouse.delta.y = in->mouse.pos.y - in->mouse.prev.y; -} - -NK_API void -nk_input_key(struct nk_context *ctx, enum nk_keys key, int down) -{ - struct nk_input *in; - NK_ASSERT(ctx); - if (!ctx) return; - in = &ctx->input; - in->keyboard.keys[key].down = down; - in->keyboard.keys[key].clicked++; -} - -NK_API void -nk_input_button(struct nk_context *ctx, enum nk_buttons id, int x, int y, int down) -{ - struct nk_mouse_button *btn; - struct nk_input *in; - NK_ASSERT(ctx); - if (!ctx) return; - in = &ctx->input; - if (in->mouse.buttons[id].down == down) return; - - btn = &in->mouse.buttons[id]; - btn->clicked_pos.x = (float)x; - btn->clicked_pos.y = (float)y; - btn->down = down; - btn->clicked++; -} - -NK_API void -nk_input_scroll(struct nk_context *ctx, float y) -{ - NK_ASSERT(ctx); - if (!ctx) return; - ctx->input.mouse.scroll_delta += y; -} - -NK_API void -nk_input_glyph(struct nk_context *ctx, const nk_glyph glyph) -{ - int len = 0; - nk_rune unicode; - struct nk_input *in; - - NK_ASSERT(ctx); - if (!ctx) return; - in = &ctx->input; - - len = nk_utf_decode(glyph, &unicode, NK_UTF_SIZE); - if (len && ((in->keyboard.text_len + len) < NK_INPUT_MAX)) { - nk_utf_encode(unicode, &in->keyboard.text[in->keyboard.text_len], - NK_INPUT_MAX - in->keyboard.text_len); - in->keyboard.text_len += len; - } -} - -NK_API void -nk_input_char(struct nk_context *ctx, char c) -{ - nk_glyph glyph; - NK_ASSERT(ctx); - if (!ctx) return; - glyph[0] = c; - nk_input_glyph(ctx, glyph); -} - -NK_API void -nk_input_unicode(struct nk_context *ctx, nk_rune unicode) -{ - nk_glyph rune; - NK_ASSERT(ctx); - if (!ctx) return; - nk_utf_encode(unicode, rune, NK_UTF_SIZE); - nk_input_glyph(ctx, rune); -} - -NK_API int -nk_input_has_mouse_click(const struct nk_input *i, enum nk_buttons id) -{ - const struct nk_mouse_button *btn; - if (!i) return nk_false; - btn = &i->mouse.buttons[id]; - return (btn->clicked && btn->down == nk_false) ? nk_true : nk_false; -} - -NK_API int -nk_input_has_mouse_click_in_rect(const struct nk_input *i, enum nk_buttons id, - struct nk_rect b) -{ - const struct nk_mouse_button *btn; - if (!i) return nk_false; - btn = &i->mouse.buttons[id]; - if (!NK_INBOX(btn->clicked_pos.x,btn->clicked_pos.y,b.x,b.y,b.w,b.h)) - return nk_false; - return nk_true; -} - -NK_API int -nk_input_has_mouse_click_down_in_rect(const struct nk_input *i, enum nk_buttons id, - struct nk_rect b, int down) -{ - const struct nk_mouse_button *btn; - if (!i) return nk_false; - btn = &i->mouse.buttons[id]; - return nk_input_has_mouse_click_in_rect(i, id, b) && (btn->down == down); -} - -NK_API int -nk_input_is_mouse_click_in_rect(const struct nk_input *i, enum nk_buttons id, - struct nk_rect b) -{ - const struct nk_mouse_button *btn; - if (!i) return nk_false; - btn = &i->mouse.buttons[id]; - return (nk_input_has_mouse_click_down_in_rect(i, id, b, nk_false) && - btn->clicked) ? nk_true : nk_false; -} - -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) -{ - const struct nk_mouse_button *btn; - if (!i) return nk_false; - btn = &i->mouse.buttons[id]; - return (nk_input_has_mouse_click_down_in_rect(i, id, b, down) && - btn->clicked) ? nk_true : nk_false; -} - -NK_API int -nk_input_any_mouse_click_in_rect(const struct nk_input *in, struct nk_rect b) -{ - int i, down = 0; - for (i = 0; i < NK_BUTTON_MAX; ++i) - down = down || nk_input_is_mouse_click_in_rect(in, (enum nk_buttons)i, b); - return down; -} - -NK_API int -nk_input_is_mouse_hovering_rect(const struct nk_input *i, struct nk_rect rect) -{ - if (!i) return nk_false; - return NK_INBOX(i->mouse.pos.x, i->mouse.pos.y, rect.x, rect.y, rect.w, rect.h); -} - -NK_API int -nk_input_is_mouse_prev_hovering_rect(const struct nk_input *i, struct nk_rect rect) -{ - if (!i) return nk_false; - return NK_INBOX(i->mouse.prev.x, i->mouse.prev.y, rect.x, rect.y, rect.w, rect.h); -} - -NK_API int -nk_input_mouse_clicked(const struct nk_input *i, enum nk_buttons id, struct nk_rect rect) -{ - if (!i) return nk_false; - if (!nk_input_is_mouse_hovering_rect(i, rect)) return nk_false; - return nk_input_is_mouse_click_in_rect(i, id, rect); -} - -NK_API int -nk_input_is_mouse_down(const struct nk_input *i, enum nk_buttons id) -{ - if (!i) return nk_false; - return i->mouse.buttons[id].down; -} - -NK_API int -nk_input_is_mouse_pressed(const struct nk_input *i, enum nk_buttons id) -{ - const struct nk_mouse_button *b; - if (!i) return nk_false; - b = &i->mouse.buttons[id]; - if (b->down && b->clicked) - return nk_true; - return nk_false; -} - -NK_API int -nk_input_is_mouse_released(const struct nk_input *i, enum nk_buttons id) -{ - if (!i) return nk_false; - return (!i->mouse.buttons[id].down && i->mouse.buttons[id].clicked); -} - -NK_API int -nk_input_is_key_pressed(const struct nk_input *i, enum nk_keys key) -{ - const struct nk_key *k; - if (!i) return nk_false; - k = &i->keyboard.keys[key]; - if ((k->down && k->clicked) || (!k->down && k->clicked >= 2)) - return nk_true; - return nk_false; -} - -NK_API int -nk_input_is_key_released(const struct nk_input *i, enum nk_keys key) -{ - const struct nk_key *k; - if (!i) return nk_false; - k = &i->keyboard.keys[key]; - if ((!k->down && k->clicked) || (k->down && k->clicked >= 2)) - return nk_true; - return nk_false; -} - -NK_API int -nk_input_is_key_down(const struct nk_input *i, enum nk_keys key) -{ - const struct nk_key *k; - if (!i) return nk_false; - k = &i->keyboard.keys[key]; - if (k->down) return nk_true; - return nk_false; -} - -/* - * ============================================================== - * - * TEXT EDITOR - * - * =============================================================== - */ -/* stb_textedit.h - v1.8 - public domain - Sean Barrett */ -struct nk_text_find { - float x,y; /* position of n'th character */ - float height; /* height of line */ - int first_char, length; /* first char of row, and length */ - int prev_first; /*_ first char of previous row */ -}; - -struct nk_text_edit_row { - float x0,x1; - /* starting x location, end x location (allows for align=right, etc) */ - float baseline_y_delta; - /* position of baseline relative to previous row's baseline*/ - float ymin,ymax; - /* height of row above and below baseline */ - int num_chars; -}; - -/* forward declarations */ -NK_INTERN void nk_textedit_makeundo_delete(struct nk_text_edit*, int, int); -NK_INTERN void nk_textedit_makeundo_insert(struct nk_text_edit*, int, int); -NK_INTERN void nk_textedit_makeundo_replace(struct nk_text_edit*, int, int, int); -#define NK_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end) - -NK_INTERN float -nk_textedit_get_width(const struct nk_text_edit *edit, int line_start, int char_id, - const struct nk_user_font *font) -{ - int len = 0; - nk_rune unicode = 0; - const char *str = nk_str_at_const(&edit->string, line_start + char_id, &unicode, &len); - return font->width(font->userdata, font->height, str, len); -} - -NK_INTERN void -nk_textedit_layout_row(struct nk_text_edit_row *r, struct nk_text_edit *edit, - int line_start_id, float row_height, const struct nk_user_font *font) -{ - int l; - int glyphs = 0; - nk_rune unicode; - const char *remaining; - int len = nk_str_len_char(&edit->string); - const char *end = nk_str_get_const(&edit->string) + len; - const char *text = nk_str_at_const(&edit->string, line_start_id, &unicode, &l); - const struct nk_vec2 size = nk_text_calculate_text_bounds(font, - text, (int)(end - text), row_height, &remaining, 0, &glyphs, NK_STOP_ON_NEW_LINE); - - r->x0 = 0.0f; - r->x1 = size.x; - r->baseline_y_delta = size.y; - r->ymin = 0.0f; - r->ymax = size.y; - r->num_chars = glyphs; -} - -NK_INTERN int -nk_textedit_locate_coord(struct nk_text_edit *edit, float x, float y, - const struct nk_user_font *font, float row_height) -{ - struct nk_text_edit_row r; - int n = edit->string.len; - float base_y = 0, prev_x; - int i=0, k; - - r.x0 = r.x1 = 0; - r.ymin = r.ymax = 0; - r.num_chars = 0; - - /* search rows to find one that straddles 'y' */ - while (i < n) { - nk_textedit_layout_row(&r, edit, i, row_height, font); - if (r.num_chars <= 0) - return n; - - if (i==0 && y < base_y + r.ymin) - return 0; - - if (y < base_y + r.ymax) - break; - - i += r.num_chars; - base_y += r.baseline_y_delta; - } - - /* below all text, return 'after' last character */ - if (i >= n) - return n; - - /* check if it's before the beginning of the line */ - if (x < r.x0) - return i; - - /* check if it's before the end of the line */ - if (x < r.x1) { - /* search characters in row for one that straddles 'x' */ - k = i; - prev_x = r.x0; - for (i=0; i < r.num_chars; ++i) { - float w = nk_textedit_get_width(edit, k, i, font); - if (x < prev_x+w) { - if (x < prev_x+w/2) - return k+i; - else return k+i+1; - } - prev_x += w; - } - /* shouldn't happen, but if it does, fall through to end-of-line case */ - } - - /* if the last character is a newline, return that. - * otherwise return 'after' the last character */ - if (nk_str_rune_at(&edit->string, i+r.num_chars-1) == '\n') - return i+r.num_chars-1; - else return i+r.num_chars; -} - -NK_INTERN void -nk_textedit_click(struct nk_text_edit *state, float x, float y, - const struct nk_user_font *font, float row_height) -{ - /* API click: on mouse down, move the cursor to the clicked location, - * and reset the selection */ - state->cursor = nk_textedit_locate_coord(state, x, y, font, row_height); - state->select_start = state->cursor; - state->select_end = state->cursor; - state->has_preferred_x = 0; -} - -NK_INTERN void -nk_textedit_drag(struct nk_text_edit *state, float x, float y, - const struct nk_user_font *font, float row_height) -{ - /* API drag: on mouse drag, move the cursor and selection endpoint - * to the clicked location */ - int p = nk_textedit_locate_coord(state, x, y, font, row_height); - if (state->select_start == state->select_end) - state->select_start = state->cursor; - state->cursor = state->select_end = p; -} - -NK_INTERN void -nk_textedit_find_charpos(struct nk_text_find *find, struct nk_text_edit *state, - int n, int single_line, const struct nk_user_font *font, float row_height) -{ - /* find the x/y location of a character, and remember info about the previous - * row in case we get a move-up event (for page up, we'll have to rescan) */ - struct nk_text_edit_row r; - int prev_start = 0; - int z = state->string.len; - int i=0, first; - - nk_zero_struct(r); - if (n == z) { - /* if it's at the end, then find the last line -- simpler than trying to - explicitly handle this case in the regular code */ - nk_textedit_layout_row(&r, state, 0, row_height, font); - if (single_line) { - find->first_char = 0; - find->length = z; - } else { - while (i < z) { - prev_start = i; - i += r.num_chars; - nk_textedit_layout_row(&r, state, i, row_height, font); - } - - find->first_char = i; - find->length = r.num_chars; - } - find->x = r.x1; - find->y = r.ymin; - find->height = r.ymax - r.ymin; - find->prev_first = prev_start; - return; - } - - /* search rows to find the one that straddles character n */ - find->y = 0; - - for(;;) { - nk_textedit_layout_row(&r, state, i, row_height, font); - if (n < i + r.num_chars) break; - prev_start = i; - i += r.num_chars; - find->y += r.baseline_y_delta; - } - - find->first_char = first = i; - find->length = r.num_chars; - find->height = r.ymax - r.ymin; - find->prev_first = prev_start; - - /* now scan to find xpos */ - find->x = r.x0; - for (i=0; first+i < n; ++i) - find->x += nk_textedit_get_width(state, first, i, font); -} - -NK_INTERN void -nk_textedit_clamp(struct nk_text_edit *state) -{ - /* make the selection/cursor state valid if client altered the string */ - int n = state->string.len; - if (NK_TEXT_HAS_SELECTION(state)) { - if (state->select_start > n) state->select_start = n; - if (state->select_end > n) state->select_end = n; - /* if clamping forced them to be equal, move the cursor to match */ - if (state->select_start == state->select_end) - state->cursor = state->select_start; - } - if (state->cursor > n) state->cursor = n; -} - -NK_API void -nk_textedit_delete(struct nk_text_edit *state, int where, int len) -{ - /* delete characters while updating undo */ - nk_textedit_makeundo_delete(state, where, len); - nk_str_delete_runes(&state->string, where, len); - state->has_preferred_x = 0; -} - -NK_API void -nk_textedit_delete_selection(struct nk_text_edit *state) -{ - /* delete the section */ - nk_textedit_clamp(state); - if (NK_TEXT_HAS_SELECTION(state)) { - if (state->select_start < state->select_end) { - nk_textedit_delete(state, state->select_start, - state->select_end - state->select_start); - state->select_end = state->cursor = state->select_start; - } else { - nk_textedit_delete(state, state->select_end, - state->select_start - state->select_end); - state->select_start = state->cursor = state->select_end; - } - state->has_preferred_x = 0; - } -} - -NK_INTERN void -nk_textedit_sortselection(struct nk_text_edit *state) -{ - /* canonicalize the selection so start <= end */ - if (state->select_end < state->select_start) { - int temp = state->select_end; - state->select_end = state->select_start; - state->select_start = temp; - } -} - -NK_INTERN void -nk_textedit_move_to_first(struct nk_text_edit *state) -{ - /* move cursor to first character of selection */ - if (NK_TEXT_HAS_SELECTION(state)) { - nk_textedit_sortselection(state); - state->cursor = state->select_start; - state->select_end = state->select_start; - state->has_preferred_x = 0; - } -} - -NK_INTERN void -nk_textedit_move_to_last(struct nk_text_edit *state) -{ - /* move cursor to last character of selection */ - if (NK_TEXT_HAS_SELECTION(state)) { - nk_textedit_sortselection(state); - nk_textedit_clamp(state); - state->cursor = state->select_end; - state->select_start = state->select_end; - state->has_preferred_x = 0; - } -} - -NK_INTERN int -nk_is_word_boundary( struct nk_text_edit *state, int idx) -{ - int len; - nk_rune c; - if (idx <= 0) return 1; - if (!nk_str_at_rune(&state->string, idx, &c, &len)) return 1; - return (c == ' ' || c == '\t' ||c == 0x3000 || c == ',' || c == ';' || - c == '(' || c == ')' || c == '{' || c == '}' || c == '[' || c == ']' || - c == '|'); -} - -NK_INTERN int -nk_textedit_move_to_word_previous(struct nk_text_edit *state) -{ - int c = state->cursor - 1; - while( c >= 0 && !nk_is_word_boundary(state, c)) - --c; - - if( c < 0 ) - c = 0; - - return c; -} - -NK_INTERN int -nk_textedit_move_to_word_next(struct nk_text_edit *state) -{ - const int len = state->string.len; - int c = state->cursor+1; - while( c < len && !nk_is_word_boundary(state, c)) - ++c; - - if( c > len ) - c = len; - - return c; -} - -NK_INTERN void -nk_textedit_prep_selection_at_cursor(struct nk_text_edit *state) -{ - /* update selection and cursor to match each other */ - if (!NK_TEXT_HAS_SELECTION(state)) - state->select_start = state->select_end = state->cursor; - else state->cursor = state->select_end; -} - -NK_API int -nk_textedit_cut(struct nk_text_edit *state) -{ - /* API cut: delete selection */ - if (state->mode == NK_TEXT_EDIT_MODE_VIEW) - return 0; - if (NK_TEXT_HAS_SELECTION(state)) { - nk_textedit_delete_selection(state); /* implicitly clamps */ - state->has_preferred_x = 0; - return 1; - } - return 0; -} - -NK_API int -nk_textedit_paste(struct nk_text_edit *state, char const *ctext, int len) -{ - /* API paste: replace existing selection with passed-in text */ - int glyphs; - const char *text = (const char *) ctext; - if (state->mode == NK_TEXT_EDIT_MODE_VIEW) return 0; - - /* if there's a selection, the paste should delete it */ - nk_textedit_clamp(state); - nk_textedit_delete_selection(state); - - /* try to insert the characters */ - glyphs = nk_utf_len(ctext, len); - if (nk_str_insert_text_char(&state->string, state->cursor, text, len)) { - nk_textedit_makeundo_insert(state, state->cursor, glyphs); - state->cursor += len; - state->has_preferred_x = 0; - return 1; - } - /* remove the undo since we didn't actually insert the characters */ - if (state->undo.undo_point) - --state->undo.undo_point; - return 0; -} - -NK_API void -nk_textedit_text(struct nk_text_edit *state, const char *text, int total_len) -{ - nk_rune unicode; - int glyph_len; - int text_len = 0; - - NK_ASSERT(state); - NK_ASSERT(text); - if (!text || !total_len || state->mode == NK_TEXT_EDIT_MODE_VIEW) return; - - glyph_len = nk_utf_decode(text, &unicode, total_len); - if (!glyph_len) return; - while ((text_len < total_len) && glyph_len) - { - /* don't insert a backward delete, just process the event */ - if (unicode == 127) - break; - - /* can't add newline in single-line mode */ - if (unicode == '\n' && state->single_line) - break; - - /* filter incoming text */ - if (state->filter && !state->filter(state, unicode)) { - glyph_len = nk_utf_decode(text + text_len, &unicode, total_len-text_len); - text_len += glyph_len; - continue; - } - - if (!NK_TEXT_HAS_SELECTION(state) && - state->cursor < state->string.len) - { - if (state->mode == NK_TEXT_EDIT_MODE_REPLACE) { - nk_textedit_makeundo_replace(state, state->cursor, 1, 1); - nk_str_delete_runes(&state->string, state->cursor, 1); - } - if (nk_str_insert_text_utf8(&state->string, state->cursor, - text+text_len, 1)) - { - ++state->cursor; - state->has_preferred_x = 0; - } - } else { - nk_textedit_delete_selection(state); /* implicitly clamps */ - if (nk_str_insert_text_utf8(&state->string, state->cursor, - text+text_len, 1)) - { - nk_textedit_makeundo_insert(state, state->cursor, 1); - ++state->cursor; - state->has_preferred_x = 0; - } - } - glyph_len = nk_utf_decode(text + text_len, &unicode, total_len-text_len); - text_len += glyph_len; - } -} - -NK_INTERN 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) -{ -retry: - switch (key) - { - case NK_KEY_NONE: - case NK_KEY_CTRL: - case NK_KEY_ENTER: - case NK_KEY_SHIFT: - case NK_KEY_TAB: - case NK_KEY_COPY: - case NK_KEY_CUT: - case NK_KEY_PASTE: - case NK_KEY_MAX: - default: break; - case NK_KEY_TEXT_UNDO: - nk_textedit_undo(state); - state->has_preferred_x = 0; - break; - - case NK_KEY_TEXT_REDO: - nk_textedit_redo(state); - state->has_preferred_x = 0; - break; - - case NK_KEY_TEXT_INSERT_MODE: - if (state->mode == NK_TEXT_EDIT_MODE_VIEW) - state->mode = NK_TEXT_EDIT_MODE_INSERT; - break; - case NK_KEY_TEXT_REPLACE_MODE: - if (state->mode == NK_TEXT_EDIT_MODE_VIEW) - state->mode = NK_TEXT_EDIT_MODE_REPLACE; - break; - case NK_KEY_TEXT_RESET_MODE: - if (state->mode == NK_TEXT_EDIT_MODE_INSERT || - state->mode == NK_TEXT_EDIT_MODE_REPLACE) - state->mode = NK_TEXT_EDIT_MODE_VIEW; - break; - - case NK_KEY_LEFT: - if (shift_mod) { - nk_textedit_clamp(state); - nk_textedit_prep_selection_at_cursor(state); - /* move selection left */ - if (state->select_end > 0) - --state->select_end; - state->cursor = state->select_end; - state->has_preferred_x = 0; - } else { - /* if currently there's a selection, - * move cursor to start of selection */ - if (NK_TEXT_HAS_SELECTION(state)) - nk_textedit_move_to_first(state); - else if (state->cursor > 0) - --state->cursor; - state->has_preferred_x = 0; - } break; - - case NK_KEY_RIGHT: - if (shift_mod) { - nk_textedit_prep_selection_at_cursor(state); - /* move selection right */ - ++state->select_end; - nk_textedit_clamp(state); - state->cursor = state->select_end; - state->has_preferred_x = 0; - } else { - /* if currently there's a selection, - * move cursor to end of selection */ - if (NK_TEXT_HAS_SELECTION(state)) - nk_textedit_move_to_last(state); - else ++state->cursor; - nk_textedit_clamp(state); - state->has_preferred_x = 0; - } break; - - case NK_KEY_TEXT_WORD_LEFT: - if (shift_mod) { - if( !NK_TEXT_HAS_SELECTION( state ) ) - nk_textedit_prep_selection_at_cursor(state); - state->cursor = nk_textedit_move_to_word_previous(state); - state->select_end = state->cursor; - nk_textedit_clamp(state ); - } else { - if (NK_TEXT_HAS_SELECTION(state)) - nk_textedit_move_to_first(state); - else { - state->cursor = nk_textedit_move_to_word_previous(state); - nk_textedit_clamp(state ); - } - } break; - - case NK_KEY_TEXT_WORD_RIGHT: - if (shift_mod) { - if( !NK_TEXT_HAS_SELECTION( state ) ) - nk_textedit_prep_selection_at_cursor(state); - state->cursor = nk_textedit_move_to_word_next(state); - state->select_end = state->cursor; - nk_textedit_clamp(state); - } else { - if (NK_TEXT_HAS_SELECTION(state)) - nk_textedit_move_to_last(state); - else { - state->cursor = nk_textedit_move_to_word_next(state); - nk_textedit_clamp(state ); - } - } break; - - case NK_KEY_DOWN: { - struct nk_text_find find; - struct nk_text_edit_row row; - int i, sel = shift_mod; - - if (state->single_line) { - /* on windows, up&down in single-line behave like left&right */ - key = NK_KEY_RIGHT; - goto retry; - } - - if (sel) - nk_textedit_prep_selection_at_cursor(state); - else if (NK_TEXT_HAS_SELECTION(state)) - nk_textedit_move_to_last(state); - - /* compute current position of cursor point */ - nk_textedit_clamp(state); - nk_textedit_find_charpos(&find, state, state->cursor, state->single_line, - font, row_height); - - /* now find character position down a row */ - if (find.length) - { - float x; - float goal_x = state->has_preferred_x ? state->preferred_x : find.x; - int start = find.first_char + find.length; - - state->cursor = start; - nk_textedit_layout_row(&row, state, state->cursor, row_height, font); - x = row.x0; - - for (i=0; i < row.num_chars && x < row.x1; ++i) { - float dx = nk_textedit_get_width(state, start, i, font); - x += dx; - if (x > goal_x) - break; - ++state->cursor; - } - nk_textedit_clamp(state); - - state->has_preferred_x = 1; - state->preferred_x = goal_x; - if (sel) - state->select_end = state->cursor; - } - } break; - - case NK_KEY_UP: { - struct nk_text_find find; - struct nk_text_edit_row row; - int i, sel = shift_mod; - - if (state->single_line) { - /* on windows, up&down become left&right */ - key = NK_KEY_LEFT; - goto retry; - } - - if (sel) - nk_textedit_prep_selection_at_cursor(state); - else if (NK_TEXT_HAS_SELECTION(state)) - nk_textedit_move_to_first(state); - - /* compute current position of cursor point */ - nk_textedit_clamp(state); - nk_textedit_find_charpos(&find, state, state->cursor, state->single_line, - font, row_height); - - /* can only go up if there's a previous row */ - if (find.prev_first != find.first_char) { - /* now find character position up a row */ - float x; - float goal_x = state->has_preferred_x ? state->preferred_x : find.x; - - state->cursor = find.prev_first; - nk_textedit_layout_row(&row, state, state->cursor, row_height, font); - x = row.x0; - - for (i=0; i < row.num_chars && x < row.x1; ++i) { - float dx = nk_textedit_get_width(state, find.prev_first, i, font); - x += dx; - if (x > goal_x) - break; - ++state->cursor; - } - nk_textedit_clamp(state); - - state->has_preferred_x = 1; - state->preferred_x = goal_x; - if (sel) state->select_end = state->cursor; - } - } break; - - case NK_KEY_DEL: - if (state->mode == NK_TEXT_EDIT_MODE_VIEW) - break; - if (NK_TEXT_HAS_SELECTION(state)) - nk_textedit_delete_selection(state); - else { - int n = state->string.len; - if (state->cursor < n) - nk_textedit_delete(state, state->cursor, 1); - } - state->has_preferred_x = 0; - break; - - case NK_KEY_BACKSPACE: - if (state->mode == NK_TEXT_EDIT_MODE_VIEW) - break; - if (NK_TEXT_HAS_SELECTION(state)) - nk_textedit_delete_selection(state); - else { - nk_textedit_clamp(state); - if (state->cursor > 0) { - nk_textedit_delete(state, state->cursor-1, 1); - --state->cursor; - } - } - state->has_preferred_x = 0; - break; - - case NK_KEY_TEXT_START: - if (shift_mod) { - nk_textedit_prep_selection_at_cursor(state); - state->cursor = state->select_end = 0; - state->has_preferred_x = 0; - } else { - state->cursor = state->select_start = state->select_end = 0; - state->has_preferred_x = 0; - } - break; - - case NK_KEY_TEXT_END: - if (shift_mod) { - nk_textedit_prep_selection_at_cursor(state); - state->cursor = state->select_end = state->string.len; - state->has_preferred_x = 0; - } else { - state->cursor = state->string.len; - state->select_start = state->select_end = 0; - state->has_preferred_x = 0; - } - break; - - case NK_KEY_TEXT_LINE_START: { - if (shift_mod) { - struct nk_text_find find; - nk_textedit_clamp(state); - nk_textedit_prep_selection_at_cursor(state); - if (state->string.len && state->cursor == state->string.len) - --state->cursor; - nk_textedit_find_charpos(&find, state,state->cursor, state->single_line, - font, row_height); - state->cursor = state->select_end = find.first_char; - state->has_preferred_x = 0; - } else { - struct nk_text_find find; - if (state->string.len && state->cursor == state->string.len) - --state->cursor; - nk_textedit_clamp(state); - nk_textedit_move_to_first(state); - nk_textedit_find_charpos(&find, state, state->cursor, state->single_line, - font, row_height); - state->cursor = find.first_char; - state->has_preferred_x = 0; - } - } break; - - case NK_KEY_TEXT_LINE_END: { - if (shift_mod) { - struct nk_text_find find; - nk_textedit_clamp(state); - nk_textedit_prep_selection_at_cursor(state); - nk_textedit_find_charpos(&find, state, state->cursor, state->single_line, - font, row_height); - state->has_preferred_x = 0; - state->cursor = find.first_char + find.length; - if (find.length > 0 && nk_str_rune_at(&state->string, state->cursor-1) == '\n') - --state->cursor; - state->select_end = state->cursor; - } else { - struct nk_text_find find; - nk_textedit_clamp(state); - nk_textedit_move_to_first(state); - nk_textedit_find_charpos(&find, state, state->cursor, state->single_line, - font, row_height); - - state->has_preferred_x = 0; - state->cursor = find.first_char + find.length; - if (find.length > 0 && nk_str_rune_at(&state->string, state->cursor-1) == '\n') - --state->cursor; - }} break; - } -} - -NK_INTERN void -nk_textedit_flush_redo(struct nk_text_undo_state *state) -{ - state->redo_point = NK_TEXTEDIT_UNDOSTATECOUNT; - state->redo_char_point = NK_TEXTEDIT_UNDOCHARCOUNT; -} - -NK_INTERN void -nk_textedit_discard_undo(struct nk_text_undo_state *state) -{ - /* discard the oldest entry in the undo list */ - if (state->undo_point > 0) { - /* if the 0th undo state has characters, clean those up */ - if (state->undo_rec[0].char_storage >= 0) { - int n = state->undo_rec[0].insert_length, i; - /* delete n characters from all other records */ - state->undo_char_point = (short)(state->undo_char_point - n); - NK_MEMCPY(state->undo_char, state->undo_char + n, - (nk_size)state->undo_char_point*sizeof(nk_rune)); - for (i=0; i < state->undo_point; ++i) { - if (state->undo_rec[i].char_storage >= 0) - state->undo_rec[i].char_storage = (short) - (state->undo_rec[i].char_storage - n); - } - } - --state->undo_point; - NK_MEMCPY(state->undo_rec, state->undo_rec+1, - (nk_size)((nk_size)state->undo_point * sizeof(state->undo_rec[0]))); - } -} - -NK_INTERN void -nk_textedit_discard_redo(struct nk_text_undo_state *state) -{ -/* discard the oldest entry in the redo list--it's bad if this - ever happens, but because undo & redo have to store the actual - characters in different cases, the redo character buffer can - fill up even though the undo buffer didn't */ - nk_size num; - int k = NK_TEXTEDIT_UNDOSTATECOUNT-1; - if (state->redo_point <= k) { - /* if the k'th undo state has characters, clean those up */ - if (state->undo_rec[k].char_storage >= 0) { - int n = state->undo_rec[k].insert_length, i; - /* delete n characters from all other records */ - state->redo_char_point = (short)(state->redo_char_point + n); - num = (nk_size)(NK_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point); - NK_MEMCPY(state->undo_char + state->redo_char_point, - state->undo_char + state->redo_char_point-n, num * sizeof(char)); - for (i = state->redo_point; i < k; ++i) { - if (state->undo_rec[i].char_storage >= 0) { - state->undo_rec[i].char_storage = (short) - (state->undo_rec[i].char_storage + n); - } - } - } - ++state->redo_point; - num = (nk_size)(NK_TEXTEDIT_UNDOSTATECOUNT - state->redo_point); - if (num) NK_MEMCPY(state->undo_rec + state->redo_point-1, - state->undo_rec + state->redo_point, num * sizeof(state->undo_rec[0])); - } -} - -NK_INTERN struct nk_text_undo_record* -nk_textedit_create_undo_record(struct nk_text_undo_state *state, int numchars) -{ - /* any time we create a new undo record, we discard redo*/ - nk_textedit_flush_redo(state); - - /* if we have no free records, we have to make room, - * by sliding the existing records down */ - if (state->undo_point == NK_TEXTEDIT_UNDOSTATECOUNT) - nk_textedit_discard_undo(state); - - /* if the characters to store won't possibly fit in the buffer, - * we can't undo */ - if (numchars > NK_TEXTEDIT_UNDOCHARCOUNT) { - state->undo_point = 0; - state->undo_char_point = 0; - return 0; - } - - /* if we don't have enough free characters in the buffer, - * we have to make room */ - while (state->undo_char_point + numchars > NK_TEXTEDIT_UNDOCHARCOUNT) - nk_textedit_discard_undo(state); - return &state->undo_rec[state->undo_point++]; -} - -NK_INTERN nk_rune* -nk_textedit_createundo(struct nk_text_undo_state *state, int pos, - int insert_len, int delete_len) -{ - struct nk_text_undo_record *r = nk_textedit_create_undo_record(state, insert_len); - if (r == 0) - return 0; - - r->where = pos; - r->insert_length = (short) insert_len; - r->delete_length = (short) delete_len; - - if (insert_len == 0) { - r->char_storage = -1; - return 0; - } else { - r->char_storage = state->undo_char_point; - state->undo_char_point = (short)(state->undo_char_point + insert_len); - return &state->undo_char[r->char_storage]; - } -} - -NK_API void -nk_textedit_undo(struct nk_text_edit *state) -{ - struct nk_text_undo_state *s = &state->undo; - struct nk_text_undo_record u, *r; - if (s->undo_point == 0) - return; - - /* we need to do two things: apply the undo record, and create a redo record */ - u = s->undo_rec[s->undo_point-1]; - r = &s->undo_rec[s->redo_point-1]; - r->char_storage = -1; - - r->insert_length = u.delete_length; - r->delete_length = u.insert_length; - r->where = u.where; - - if (u.delete_length) - { - /* if the undo record says to delete characters, then the redo record will - need to re-insert the characters that get deleted, so we need to store - them. - there are three cases: - - there's enough room to store the characters - - characters stored for *redoing* don't leave room for redo - - characters stored for *undoing* don't leave room for redo - if the last is true, we have to bail */ - if (s->undo_char_point + u.delete_length >= NK_TEXTEDIT_UNDOCHARCOUNT) { - /* the undo records take up too much character space; there's no space - * to store the redo characters */ - r->insert_length = 0; - } else { - int i; - /* there's definitely room to store the characters eventually */ - while (s->undo_char_point + u.delete_length > s->redo_char_point) { - /* there's currently not enough room, so discard a redo record */ - nk_textedit_discard_redo(s); - /* should never happen: */ - if (s->redo_point == NK_TEXTEDIT_UNDOSTATECOUNT) - return; - } - - r = &s->undo_rec[s->redo_point-1]; - r->char_storage = (short)(s->redo_char_point - u.delete_length); - s->redo_char_point = (short)(s->redo_char_point - u.delete_length); - - /* now save the characters */ - for (i=0; i < u.delete_length; ++i) - s->undo_char[r->char_storage + i] = - nk_str_rune_at(&state->string, u.where + i); - } - /* now we can carry out the deletion */ - nk_str_delete_runes(&state->string, u.where, u.delete_length); - } - - /* check type of recorded action: */ - if (u.insert_length) { - /* easy case: was a deletion, so we need to insert n characters */ - nk_str_insert_text_runes(&state->string, u.where, - &s->undo_char[u.char_storage], u.insert_length); - s->undo_char_point = (short)(s->undo_char_point - u.insert_length); - } - state->cursor = (short)(u.where + u.insert_length); - - s->undo_point--; - s->redo_point--; -} - -NK_API void -nk_textedit_redo(struct nk_text_edit *state) -{ - struct nk_text_undo_state *s = &state->undo; - struct nk_text_undo_record *u, r; - if (s->redo_point == NK_TEXTEDIT_UNDOSTATECOUNT) - return; - - /* we need to do two things: apply the redo record, and create an undo record */ - u = &s->undo_rec[s->undo_point]; - r = s->undo_rec[s->redo_point]; - - /* we KNOW there must be room for the undo record, because the redo record - was derived from an undo record */ - u->delete_length = r.insert_length; - u->insert_length = r.delete_length; - u->where = r.where; - u->char_storage = -1; - - if (r.delete_length) { - /* the redo record requires us to delete characters, so the undo record - needs to store the characters */ - if (s->undo_char_point + u->insert_length > s->redo_char_point) { - u->insert_length = 0; - u->delete_length = 0; - } else { - int i; - u->char_storage = s->undo_char_point; - s->undo_char_point = (short)(s->undo_char_point + u->insert_length); - - /* now save the characters */ - for (i=0; i < u->insert_length; ++i) { - s->undo_char[u->char_storage + i] = - nk_str_rune_at(&state->string, u->where + i); - } - } - nk_str_delete_runes(&state->string, r.where, r.delete_length); - } - - if (r.insert_length) { - /* easy case: need to insert n characters */ - nk_str_insert_text_runes(&state->string, r.where, - &s->undo_char[r.char_storage], r.insert_length); - } - state->cursor = r.where + r.insert_length; - - s->undo_point++; - s->redo_point++; -} - -NK_INTERN void -nk_textedit_makeundo_insert(struct nk_text_edit *state, int where, int length) -{ - nk_textedit_createundo(&state->undo, where, 0, length); -} - -NK_INTERN void -nk_textedit_makeundo_delete(struct nk_text_edit *state, int where, int length) -{ - int i; - nk_rune *p = nk_textedit_createundo(&state->undo, where, length, 0); - if (p) { - for (i=0; i < length; ++i) - p[i] = nk_str_rune_at(&state->string, where+i); - } -} - -NK_INTERN void -nk_textedit_makeundo_replace(struct nk_text_edit *state, int where, - int old_length, int new_length) -{ - int i; - nk_rune *p = nk_textedit_createundo(&state->undo, where, old_length, new_length); - if (p) { - for (i=0; i < old_length; ++i) - p[i] = nk_str_rune_at(&state->string, where+i); - } -} - -NK_INTERN void -nk_textedit_clear_state(struct nk_text_edit *state, enum nk_text_edit_type type, - nk_plugin_filter filter) -{ - /* reset the state to default */ - state->undo.undo_point = 0; - state->undo.undo_char_point = 0; - state->undo.redo_point = NK_TEXTEDIT_UNDOSTATECOUNT; - state->undo.redo_char_point = NK_TEXTEDIT_UNDOCHARCOUNT; - state->select_end = state->select_start = 0; - state->cursor = 0; - state->has_preferred_x = 0; - state->preferred_x = 0; - state->cursor_at_end_of_line = 0; - state->initialized = 1; - state->single_line = (unsigned char)(type == NK_TEXT_EDIT_SINGLE_LINE); - state->mode = NK_TEXT_EDIT_MODE_VIEW; - state->filter = filter; - state->scrollbar = nk_vec2(0,0); -} - -NK_API void -nk_textedit_init_fixed(struct nk_text_edit *state, void *memory, nk_size size) -{ - NK_ASSERT(state); - NK_ASSERT(memory); - if (!state || !memory || !size) return; - nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0); - nk_str_init_fixed(&state->string, memory, size); -} - -NK_API void -nk_textedit_init(struct nk_text_edit *state, struct nk_allocator *alloc, nk_size size) -{ - NK_ASSERT(state); - NK_ASSERT(alloc); - if (!state || !alloc) return; - nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0); - nk_str_init(&state->string, alloc, size); -} - -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_API void -nk_textedit_init_default(struct nk_text_edit *state) -{ - NK_ASSERT(state); - if (!state) return; - nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0); - nk_str_init_default(&state->string); -} -#endif - -NK_API void -nk_textedit_select_all(struct nk_text_edit *state) -{ - NK_ASSERT(state); - state->select_start = 0; - state->select_end = state->string.len; -} - -NK_API void -nk_textedit_free(struct nk_text_edit *state) -{ - NK_ASSERT(state); - if (!state) return; - nk_str_free(&state->string); -} - -/* =============================================================== - * - * TEXT WIDGET - * - * ===============================================================*/ -#define nk_widget_state_reset(s)\ - if ((*(s)) & NK_WIDGET_STATE_MODIFIED)\ - (*(s)) = NK_WIDGET_STATE_INACTIVE|NK_WIDGET_STATE_MODIFIED;\ - else (*(s)) = NK_WIDGET_STATE_INACTIVE; - -struct nk_text { - struct nk_vec2 padding; - struct nk_color background; - struct nk_color text; -}; - -NK_INTERN 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) -{ - struct nk_rect label; - float text_width; - - NK_ASSERT(o); - NK_ASSERT(t); - if (!o || !t) return; - - b.h = NK_MAX(b.h, 2 * t->padding.y); - label.x = 0; label.w = 0; - label.y = b.y + t->padding.y; - label.h = NK_MIN(f->height, b.h - 2 * t->padding.y); - - text_width = f->width(f->userdata, f->height, (const char*)string, len); - text_width += (2.0f * t->padding.x); - - /* align in x-axis */ - if (a & NK_TEXT_ALIGN_LEFT) { - label.x = b.x + t->padding.x; - label.w = NK_MAX(0, b.w - 2 * t->padding.x); - } else if (a & NK_TEXT_ALIGN_CENTERED) { - label.w = NK_MAX(1, 2 * t->padding.x + (float)text_width); - label.x = (b.x + t->padding.x + ((b.w - 2 * t->padding.x) - label.w) / 2); - label.x = NK_MAX(b.x + t->padding.x, label.x); - label.w = NK_MIN(b.x + b.w, label.x + label.w); - if (label.w >= label.x) label.w -= label.x; - } else if (a & NK_TEXT_ALIGN_RIGHT) { - label.x = NK_MAX(b.x + t->padding.x, (b.x + b.w) - (2 * t->padding.x + (float)text_width)); - label.w = (float)text_width + 2 * t->padding.x; - } else return; - - /* align in y-axis */ - if (a & NK_TEXT_ALIGN_MIDDLE) { - label.y = b.y + b.h/2.0f - (float)f->height/2.0f; - label.h = NK_MAX(b.h/2.0f, b.h - (b.h/2.0f + f->height/2.0f)); - } else if (a & NK_TEXT_ALIGN_BOTTOM) { - label.y = b.y + b.h - f->height; - label.h = f->height; - } - nk_draw_text(o, label, (const char*)string, - len, f, t->background, t->text); -} - -NK_INTERN 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) -{ - float width; - int glyphs = 0; - int fitting = 0; - int done = 0; - struct nk_rect line; - struct nk_text text; - NK_INTERN nk_rune seperator[] = {' '}; - - NK_ASSERT(o); - NK_ASSERT(t); - if (!o || !t) return; - - text.padding = nk_vec2(0,0); - text.background = t->background; - text.text = t->text; - - b.w = NK_MAX(b.w, 2 * t->padding.x); - b.h = NK_MAX(b.h, 2 * t->padding.y); - b.h = b.h - 2 * t->padding.y; - - line.x = b.x + t->padding.x; - line.y = b.y + t->padding.y; - line.w = b.w - 2 * t->padding.x; - line.h = 2 * t->padding.y + f->height; - - fitting = nk_text_clamp(f, string, len, line.w, &glyphs, &width, seperator,NK_LEN(seperator)); - while (done < len) { - if (!fitting || line.y + line.h >= (b.y + b.h)) break; - nk_widget_text(o, line, &string[done], fitting, &text, NK_TEXT_LEFT, f); - done += fitting; - line.y += f->height + 2 * t->padding.y; - fitting = nk_text_clamp(f, &string[done], len - done, line.w, &glyphs, &width, seperator,NK_LEN(seperator)); - } -} - -/* =============================================================== - * - * BUTTON - * - * ===============================================================*/ -NK_INTERN 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) -{ - switch (type) { - case NK_SYMBOL_X: - case NK_SYMBOL_UNDERSCORE: - case NK_SYMBOL_PLUS: - case NK_SYMBOL_MINUS: { - /* single character text symbol */ - const char *X = (type == NK_SYMBOL_X) ? "x": - (type == NK_SYMBOL_UNDERSCORE) ? "_": - (type == NK_SYMBOL_PLUS) ? "+": "-"; - struct nk_text text; - text.padding = nk_vec2(0,0); - text.background = background; - text.text = foreground; - nk_widget_text(out, content, X, 1, &text, NK_TEXT_CENTERED, font); - } break; - case NK_SYMBOL_CIRCLE_SOLID: - case NK_SYMBOL_CIRCLE_OUTLINE: - case NK_SYMBOL_RECT_SOLID: - case NK_SYMBOL_RECT_OUTLINE: { - /* simple empty/filled shapes */ - if (type == NK_SYMBOL_RECT_SOLID || type == NK_SYMBOL_RECT_OUTLINE) { - nk_fill_rect(out, content, 0, foreground); - if (type == NK_SYMBOL_RECT_OUTLINE) - nk_fill_rect(out, nk_shrink_rect(content, border_width), 0, background); - } else { - nk_fill_circle(out, content, foreground); - if (type == NK_SYMBOL_CIRCLE_OUTLINE) - nk_fill_circle(out, nk_shrink_rect(content, 1), background); - } - } break; - case NK_SYMBOL_TRIANGLE_UP: - case NK_SYMBOL_TRIANGLE_DOWN: - case NK_SYMBOL_TRIANGLE_LEFT: - case NK_SYMBOL_TRIANGLE_RIGHT: { - enum nk_heading heading; - struct nk_vec2 points[3]; - heading = (type == NK_SYMBOL_TRIANGLE_RIGHT) ? NK_RIGHT : - (type == NK_SYMBOL_TRIANGLE_LEFT) ? NK_LEFT: - (type == NK_SYMBOL_TRIANGLE_UP) ? NK_UP: NK_DOWN; - nk_triangle_from_direction(points, content, 0, 0, heading); - nk_fill_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y, - points[2].x, points[2].y, foreground); - } break; - default: - case NK_SYMBOL_NONE: - case NK_SYMBOL_MAX: break; - } -} - -NK_INTERN int -nk_button_behavior(nk_flags *state, struct nk_rect r, - const struct nk_input *i, enum nk_button_behavior behavior) -{ - int ret = 0; - nk_widget_state_reset(state); - if (!i) return 0; - if (nk_input_is_mouse_hovering_rect(i, r)) { - *state = NK_WIDGET_STATE_HOVERED; - if (nk_input_is_mouse_down(i, NK_BUTTON_LEFT)) - *state = NK_WIDGET_STATE_ACTIVE; - if (nk_input_has_mouse_click_in_rect(i, NK_BUTTON_LEFT, r)) { - ret = (behavior != NK_BUTTON_DEFAULT) ? - nk_input_is_mouse_down(i, NK_BUTTON_LEFT): -#ifdef NK_BUTTON_TRIGGER_ON_RELEASE - nk_input_is_mouse_released(i, NK_BUTTON_LEFT); -#else - nk_input_is_mouse_pressed(i, NK_BUTTON_LEFT); -#endif - } - } - if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(i, r)) - *state |= NK_WIDGET_STATE_ENTERED; - else if (nk_input_is_mouse_prev_hovering_rect(i, r)) - *state |= NK_WIDGET_STATE_LEFT; - return ret; -} - -NK_INTERN 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) -{ - const struct nk_style_item *background; - if (state & NK_WIDGET_STATE_HOVER) - background = &style->hover; - else if (state & NK_WIDGET_STATE_ACTIVED) - background = &style->active; - else background = &style->normal; - - if (background->type == NK_STYLE_ITEM_IMAGE) { - nk_draw_image(out, *bounds, &background->data.image, nk_white); - } else { - nk_fill_rect(out, *bounds, style->rounding, background->data.color); - nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color); - } - return background; -} - -NK_INTERN 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) -{ - struct nk_rect bounds; - NK_ASSERT(style); - NK_ASSERT(state); - NK_ASSERT(out); - if (!out || !style) - return nk_false; - - /* calculate button content space */ - content->x = r.x + style->padding.x + style->border + style->rounding; - content->y = r.y + style->padding.y + style->border + style->rounding; - content->w = r.w - (2 * style->padding.x + style->border + style->rounding*2); - content->h = r.h - (2 * style->padding.y + style->border + style->rounding*2); - - /* execute button behavior */ - bounds.x = r.x - style->touch_padding.x; - bounds.y = r.y - style->touch_padding.y; - bounds.w = r.w + 2 * style->touch_padding.x; - bounds.h = r.h + 2 * style->touch_padding.y; - return nk_button_behavior(state, bounds, in, behavior); -} - -NK_INTERN 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) -{ - struct nk_text text; - const struct nk_style_item *background; - background = nk_draw_button(out, bounds, state, style); - - /* select correct colors/images */ - if (background->type == NK_STYLE_ITEM_COLOR) - text.background = background->data.color; - else text.background = style->text_background; - if (state & NK_WIDGET_STATE_HOVER) - text.text = style->text_hover; - else if (state & NK_WIDGET_STATE_ACTIVED) - text.text = style->text_active; - else text.text = style->text_normal; - - text.padding = nk_vec2(0,0); - nk_widget_text(out, *content, txt, len, &text, text_alignment, font); -} - -NK_INTERN 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) -{ - struct nk_rect content; - int ret = nk_false; - - NK_ASSERT(state); - NK_ASSERT(style); - NK_ASSERT(out); - NK_ASSERT(string); - NK_ASSERT(font); - if (!out || !style || !font || !string) - return nk_false; - - ret = nk_do_button(state, out, bounds, style, in, behavior, &content); - if (style->draw_begin) style->draw_begin(out, style->userdata); - nk_draw_button_text(out, &bounds, &content, *state, style, string, len, align, font); - if (style->draw_end) style->draw_end(out, style->userdata); - return ret; -} - -NK_INTERN 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) -{ - struct nk_color sym, bg; - const struct nk_style_item *background; - - /* select correct colors/images */ - background = nk_draw_button(out, bounds, state, style); - if (background->type == NK_STYLE_ITEM_COLOR) - bg = background->data.color; - else bg = style->text_background; - - if (state & NK_WIDGET_STATE_HOVER) - sym = style->text_hover; - else if (state & NK_WIDGET_STATE_ACTIVED) - sym = style->text_active; - else sym = style->text_normal; - nk_draw_symbol(out, type, *content, bg, sym, 1, font); -} - -NK_INTERN 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) -{ - int ret; - struct nk_rect content; - - NK_ASSERT(state); - NK_ASSERT(style); - NK_ASSERT(font); - NK_ASSERT(out); - if (!out || !style || !font || !state) - return nk_false; - - ret = nk_do_button(state, out, bounds, style, in, behavior, &content); - if (style->draw_begin) style->draw_begin(out, style->userdata); - nk_draw_button_symbol(out, &bounds, &content, *state, style, symbol, font); - if (style->draw_end) style->draw_end(out, style->userdata); - return ret; -} - -NK_INTERN 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) -{ - nk_draw_button(out, bounds, state, style); - nk_draw_image(out, *content, img, nk_white); -} - -NK_INTERN 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) -{ - int ret; - struct nk_rect content; - - NK_ASSERT(state); - NK_ASSERT(style); - NK_ASSERT(out); - if (!out || !style || !state) - return nk_false; - - ret = nk_do_button(state, out, bounds, style, in, b, &content); - content.x += style->image_padding.x; - content.y += style->image_padding.y; - content.w -= 2 * style->image_padding.x; - content.h -= 2 * style->image_padding.y; - - if (style->draw_begin) style->draw_begin(out, style->userdata); - nk_draw_button_image(out, &bounds, &content, *state, style, &img); - if (style->draw_end) style->draw_end(out, style->userdata); - return ret; -} - -NK_INTERN 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) -{ - struct nk_color sym; - struct nk_text text; - const struct nk_style_item *background; - - /* select correct background colors/images */ - background = nk_draw_button(out, bounds, state, style); - if (background->type == NK_STYLE_ITEM_COLOR) - text.background = background->data.color; - else text.background = style->text_background; - - /* select correct text colors */ - if (state & NK_WIDGET_STATE_HOVER) { - sym = style->text_hover; - text.text = style->text_hover; - } else if (state & NK_WIDGET_STATE_ACTIVED) { - sym = style->text_active; - text.text = style->text_active; - } else { - sym = style->text_normal; - text.text = style->text_normal; - } - - text.padding = nk_vec2(0,0); - nk_draw_symbol(out, type, *symbol, style->text_background, sym, 0, font); - nk_widget_text(out, *label, str, len, &text, NK_TEXT_CENTERED, font); -} - -NK_INTERN 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) -{ - int ret; - struct nk_rect tri = {0,0,0,0}; - struct nk_rect content; - - NK_ASSERT(style); - NK_ASSERT(out); - NK_ASSERT(font); - if (!out || !style || !font) - return nk_false; - - ret = nk_do_button(state, out, bounds, style, in, behavior, &content); - tri.y = content.y + (content.h/2) - font->height/2; - tri.w = font->height; tri.h = font->height; - if (align & NK_TEXT_ALIGN_LEFT) { - tri.x = (content.x + content.w) - (2 * style->padding.x + tri.w); - tri.x = NK_MAX(tri.x, 0); - } else tri.x = content.x + 2 * style->padding.x; - - /* draw button */ - if (style->draw_begin) style->draw_begin(out, style->userdata); - nk_draw_button_text_symbol(out, &bounds, &content, &tri, - *state, style, str, len, symbol, font); - if (style->draw_end) style->draw_end(out, style->userdata); - return ret; -} - -NK_INTERN 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) -{ - struct nk_text text; - const struct nk_style_item *background; - background = nk_draw_button(out, bounds, state, style); - - /* select correct colors */ - if (background->type == NK_STYLE_ITEM_COLOR) - text.background = background->data.color; - else text.background = style->text_background; - if (state & NK_WIDGET_STATE_HOVER) - text.text = style->text_hover; - else if (state & NK_WIDGET_STATE_ACTIVED) - text.text = style->text_active; - else text.text = style->text_normal; - - text.padding = nk_vec2(0,0); - nk_widget_text(out, *label, str, len, &text, NK_TEXT_CENTERED, font); - nk_draw_image(out, *image, img, nk_white); -} - -NK_INTERN 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) -{ - int ret; - struct nk_rect icon; - struct nk_rect content; - - NK_ASSERT(style); - NK_ASSERT(state); - NK_ASSERT(font); - NK_ASSERT(out); - if (!out || !font || !style || !str) - return nk_false; - - ret = nk_do_button(state, out, bounds, style, in, behavior, &content); - icon.y = bounds.y + style->padding.y; - icon.w = icon.h = bounds.h - 2 * style->padding.y; - if (align & NK_TEXT_ALIGN_LEFT) { - icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w); - icon.x = NK_MAX(icon.x, 0); - } else icon.x = bounds.x + 2 * style->padding.x; - - icon.x += style->image_padding.x; - icon.y += style->image_padding.y; - icon.w -= 2 * style->image_padding.x; - icon.h -= 2 * style->image_padding.y; - - if (style->draw_begin) style->draw_begin(out, style->userdata); - nk_draw_button_text_image(out, &bounds, &content, &icon, *state, style, str, len, font, &img); - if (style->draw_end) style->draw_end(out, style->userdata); - return ret; -} - -/* =============================================================== - * - * TOGGLE - * - * ===============================================================*/ -enum nk_toggle_type { - NK_TOGGLE_CHECK, - NK_TOGGLE_OPTION -}; - -NK_INTERN int -nk_toggle_behavior(const struct nk_input *in, struct nk_rect select, - nk_flags *state, int active) -{ - nk_widget_state_reset(state); - if (nk_button_behavior(state, select, in, NK_BUTTON_DEFAULT)) { - *state = NK_WIDGET_STATE_ACTIVE; - active = !active; - } - if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, select)) - *state |= NK_WIDGET_STATE_ENTERED; - else if (nk_input_is_mouse_prev_hovering_rect(in, select)) - *state |= NK_WIDGET_STATE_LEFT; - return active; -} - -NK_INTERN 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) -{ - const struct nk_style_item *background; - const struct nk_style_item *cursor; - struct nk_text text; - - /* select correct colors/images */ - if (state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - cursor = &style->cursor_hover; - text.text = style->text_hover; - } else if (state & NK_WIDGET_STATE_ACTIVED) { - background = &style->hover; - cursor = &style->cursor_hover; - text.text = style->text_active; - } else { - background = &style->normal; - cursor = &style->cursor_normal; - text.text = style->text_normal; - } - - /* draw background and cursor */ - if (background->type == NK_STYLE_ITEM_COLOR) { - nk_fill_rect(out, *selector, 0, style->border_color); - nk_fill_rect(out, nk_shrink_rect(*selector, style->border), 0, background->data.color); - } else nk_draw_image(out, *selector, &background->data.image, nk_white); - if (active) { - if (cursor->type == NK_STYLE_ITEM_IMAGE) - nk_draw_image(out, *cursors, &cursor->data.image, nk_white); - else nk_fill_rect(out, *cursors, 0, cursor->data.color); - } - - text.padding.x = 0; - text.padding.y = 0; - text.background = style->text_background; - nk_widget_text(out, *label, string, len, &text, NK_TEXT_LEFT, font); -} - -NK_INTERN 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) -{ - const struct nk_style_item *background; - const struct nk_style_item *cursor; - struct nk_text text; - - /* select correct colors/images */ - if (state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - cursor = &style->cursor_hover; - text.text = style->text_hover; - } else if (state & NK_WIDGET_STATE_ACTIVED) { - background = &style->hover; - cursor = &style->cursor_hover; - text.text = style->text_active; - } else { - background = &style->normal; - cursor = &style->cursor_normal; - text.text = style->text_normal; - } - - /* draw background and cursor */ - if (background->type == NK_STYLE_ITEM_COLOR) { - nk_fill_circle(out, *selector, style->border_color); - nk_fill_circle(out, nk_shrink_rect(*selector, style->border), background->data.color); - } else nk_draw_image(out, *selector, &background->data.image, nk_white); - if (active) { - if (cursor->type == NK_STYLE_ITEM_IMAGE) - nk_draw_image(out, *cursors, &cursor->data.image, nk_white); - else nk_fill_circle(out, *cursors, cursor->data.color); - } - - text.padding.x = 0; - text.padding.y = 0; - text.background = style->text_background; - nk_widget_text(out, *label, string, len, &text, NK_TEXT_LEFT, font); -} - -NK_INTERN 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) -{ - int was_active; - struct nk_rect bounds; - struct nk_rect select; - struct nk_rect cursor; - struct nk_rect label; - - NK_ASSERT(style); - NK_ASSERT(out); - NK_ASSERT(font); - if (!out || !style || !font || !active) - return 0; - - r.w = NK_MAX(r.w, font->height + 2 * style->padding.x); - r.h = NK_MAX(r.h, font->height + 2 * style->padding.y); - - /* add additional touch padding for touch screen devices */ - bounds.x = r.x - style->touch_padding.x; - bounds.y = r.y - style->touch_padding.y; - bounds.w = r.w + 2 * style->touch_padding.x; - bounds.h = r.h + 2 * style->touch_padding.y; - - /* calculate the selector space */ - select.w = font->height; - select.h = select.w; - select.y = r.y + r.h/2.0f - select.h/2.0f; - select.x = r.x; - - /* calculate the bounds of the cursor inside the selector */ - cursor.x = select.x + style->padding.x + style->border; - cursor.y = select.y + style->padding.y + style->border; - cursor.w = select.w - (2 * style->padding.x + 2 * style->border); - cursor.h = select.h - (2 * style->padding.y + 2 * style->border); - - /* label behind the selector */ - label.x = select.x + select.w + style->spacing; - label.y = select.y; - label.w = NK_MAX(r.x + r.w, label.x) - label.x; - label.h = select.w; - - /* update selector */ - was_active = *active; - *active = nk_toggle_behavior(in, bounds, state, *active); - - /* draw selector */ - if (style->draw_begin) - style->draw_begin(out, style->userdata); - if (type == NK_TOGGLE_CHECK) { - nk_draw_checkbox(out, *state, style, *active, &label, &select, &cursor, str, len, font); - } else { - nk_draw_option(out, *state, style, *active, &label, &select, &cursor, str, len, font); - } - if (style->draw_end) - style->draw_end(out, style->userdata); - return (was_active != *active); -} - -/* =============================================================== - * - * SELECTABLE - * - * ===============================================================*/ -NK_INTERN 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, - const char *string, int len, nk_flags align, const struct nk_user_font *font) -{ - const struct nk_style_item *background; - struct nk_text text; - text.padding = style->padding; - - /* select correct colors/images */ - if (!active) { - if (state & NK_WIDGET_STATE_ACTIVED) { - background = &style->pressed; - text.text = style->text_pressed; - } else if (state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - text.text = style->text_hover; - } else { - background = &style->normal; - text.text = style->text_normal; - } - } else { - if (state & NK_WIDGET_STATE_ACTIVED) { - background = &style->pressed_active; - text.text = style->text_pressed_active; - } else if (state & NK_WIDGET_STATE_HOVER) { - background = &style->hover_active; - text.text = style->text_hover_active; - } else { - background = &style->normal_active; - text.text = style->text_normal_active; - } - } - - - /* draw selectable background and text */ - if (background->type == NK_STYLE_ITEM_IMAGE) { - nk_draw_image(out, *bounds, &background->data.image, nk_white); - text.background = nk_rgba(0,0,0,0); - } else { - nk_fill_rect(out, *bounds, style->rounding, background->data.color); - text.background = background->data.color; - } - if (img && icon) nk_draw_image(out, *icon, img, nk_white); - nk_widget_text(out, *bounds, string, len, &text, align, font); -} - -NK_INTERN 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) -{ - int old_value; - struct nk_rect touch; - - NK_ASSERT(state); - NK_ASSERT(out); - NK_ASSERT(str); - NK_ASSERT(len); - NK_ASSERT(value); - NK_ASSERT(style); - NK_ASSERT(font); - - if (!state || !out || !str || !len || !value || !style || !font) return 0; - old_value = *value; - - /* remove padding */ - touch.x = bounds.x - style->touch_padding.x; - touch.y = bounds.y - style->touch_padding.y; - touch.w = bounds.w + style->touch_padding.x * 2; - touch.h = bounds.h + style->touch_padding.y * 2; - - /* update button */ - if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT)) - *value = !(*value); - - /* draw selectable */ - if (style->draw_begin) style->draw_begin(out, style->userdata); - nk_draw_selectable(out, *state, style, *value, &bounds, 0,0, str, len, align, font); - if (style->draw_end) style->draw_end(out, style->userdata); - return old_value != *value; -} - -NK_INTERN 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) -{ - int old_value; - struct nk_rect touch; - struct nk_rect icon; - - NK_ASSERT(state); - NK_ASSERT(out); - NK_ASSERT(str); - NK_ASSERT(len); - NK_ASSERT(value); - NK_ASSERT(style); - NK_ASSERT(font); - - if (!state || !out || !str || !len || !value || !style || !font) return 0; - old_value = *value; - - /* toggle behavior */ - touch.x = bounds.x - style->touch_padding.x; - touch.y = bounds.y - style->touch_padding.y; - touch.w = bounds.w + style->touch_padding.x * 2; - touch.h = bounds.h + style->touch_padding.y * 2; - if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT)) - *value = !(*value); - - icon.y = bounds.y + style->padding.y; - icon.w = icon.h = bounds.h - 2 * style->padding.y; - if (align & NK_TEXT_ALIGN_LEFT) { - icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w); - icon.x = NK_MAX(icon.x, 0); - } else icon.x = bounds.x + 2 * style->padding.x; - - icon.x += style->image_padding.x; - icon.y += style->image_padding.y; - icon.w -= 2 * style->image_padding.x; - icon.h -= 2 * style->image_padding.y; - - /* draw selectable */ - if (style->draw_begin) style->draw_begin(out, style->userdata); - nk_draw_selectable(out, *state, style, *value, &bounds, &icon, img, str, len, align, font); - if (style->draw_end) style->draw_end(out, style->userdata); - return old_value != *value; -} - - -/* =============================================================== - * - * SLIDER - * - * ===============================================================*/ -NK_INTERN float -nk_slider_behavior(nk_flags *state, struct nk_rect *logical_cursor, - struct nk_rect *visual_cursor, struct nk_input *in, - const struct nk_style_slider *style, struct nk_rect bounds, - float slider_min, float slider_max, float slider_value, - float slider_step, float slider_steps) -{ - int left_mouse_down; - int left_mouse_click_in_cursor; - - /* check if visual cursor is being dragged */ - nk_widget_state_reset(state); - left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down; - left_mouse_click_in_cursor = in && nk_input_has_mouse_click_down_in_rect(in, - NK_BUTTON_LEFT, *visual_cursor, nk_true); - - if (left_mouse_down && left_mouse_click_in_cursor) - { - float ratio = 0; - const float d = in->mouse.pos.x - (visual_cursor->x + visual_cursor->w / 2.0f); - const float pxstep = (bounds.w - (2 * style->padding.x)) / slider_steps; - - /* only update value if the next slider step is reached */ - *state = NK_WIDGET_STATE_ACTIVE; - if (NK_ABS(d) >= pxstep) { - const float steps = (float)((int)(NK_ABS(d) / pxstep)); - slider_value += (d > 0) ? (slider_step*steps) : -(slider_step*steps); - slider_value = NK_CLAMP(slider_min, slider_value, slider_max); - ratio = (slider_value - slider_min)/slider_step; - logical_cursor->x = bounds.x + (logical_cursor->w * ratio); - in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = logical_cursor->x + logical_cursor->w/2.0f; - } - } - - /* slider widget state */ - if (nk_input_is_mouse_hovering_rect(in, bounds)) - *state = NK_WIDGET_STATE_HOVERED; - if (*state & NK_WIDGET_STATE_HOVER && - !nk_input_is_mouse_prev_hovering_rect(in, bounds)) - *state |= NK_WIDGET_STATE_ENTERED; - else if (nk_input_is_mouse_prev_hovering_rect(in, bounds)) - *state |= NK_WIDGET_STATE_LEFT; - return slider_value; -} - -NK_INTERN 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) -{ - struct nk_rect fill; - struct nk_rect bar; - const struct nk_style_item *background; - - /* select correct slider images/colors */ - struct nk_color bar_color; - const struct nk_style_item *cursor; - - NK_UNUSED(min); - NK_UNUSED(max); - NK_UNUSED(value); - - if (state & NK_WIDGET_STATE_ACTIVED) { - background = &style->active; - bar_color = style->bar_active; - cursor = &style->cursor_active; - } else if (state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - bar_color = style->bar_hover; - cursor = &style->cursor_hover; - } else { - background = &style->normal; - bar_color = style->bar_normal; - cursor = &style->cursor_normal; - } - - /* calculate slider background bar */ - bar.x = bounds->x; - bar.y = (visual_cursor->y + visual_cursor->h/2) - bounds->h/12; - bar.w = bounds->w; - bar.h = bounds->h/6; - - /* filled background bar style */ - fill.w = (visual_cursor->x + (visual_cursor->w/2.0f)) - bar.x; - fill.x = bar.x; - fill.y = bar.y; - fill.h = bar.h; - - /* draw background */ - if (background->type == NK_STYLE_ITEM_IMAGE) { - nk_draw_image(out, *bounds, &background->data.image, nk_white); - } else { - nk_fill_rect(out, *bounds, style->rounding, background->data.color); - nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color); - } - - /* draw slider bar */ - nk_fill_rect(out, bar, style->rounding, bar_color); - nk_fill_rect(out, fill, style->rounding, style->bar_filled); - - /* draw cursor */ - if (cursor->type == NK_STYLE_ITEM_IMAGE) - nk_draw_image(out, *visual_cursor, &cursor->data.image, nk_white); - else nk_fill_circle(out, *visual_cursor, cursor->data.color); -} - -NK_INTERN 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) -{ - float slider_range; - float slider_min; - float slider_max; - float slider_value; - float slider_steps; - float cursor_offset; - - struct nk_rect visual_cursor; - struct nk_rect logical_cursor; - - NK_ASSERT(style); - NK_ASSERT(out); - if (!out || !style) - return 0; - - /* remove padding from slider bounds */ - bounds.x = bounds.x + style->padding.x; - bounds.y = bounds.y + style->padding.y; - bounds.h = NK_MAX(bounds.h, 2*style->padding.y); - bounds.w = NK_MAX(bounds.w, 2*style->padding.x + style->cursor_size.x); - bounds.w -= 2 * style->padding.x; - bounds.h -= 2 * style->padding.y; - - /* optional buttons */ - if (style->show_buttons) { - nk_flags ws; - struct nk_rect button; - button.y = bounds.y; - button.w = bounds.h; - button.h = bounds.h; - - /* decrement button */ - button.x = bounds.x; - if (nk_do_button_symbol(&ws, out, button, style->dec_symbol, NK_BUTTON_DEFAULT, - &style->dec_button, in, font)) - val -= step; - - /* increment button */ - button.x = (bounds.x + bounds.w) - button.w; - if (nk_do_button_symbol(&ws, out, button, style->inc_symbol, NK_BUTTON_DEFAULT, - &style->inc_button, in, font)) - val += step; - - bounds.x = bounds.x + button.w + style->spacing.x; - bounds.w = bounds.w - (2*button.w + 2*style->spacing.x); - } - - /* make sure the provided values are correct */ - slider_max = NK_MAX(min, max); - slider_min = NK_MIN(min, max); - slider_value = NK_CLAMP(slider_min, val, slider_max); - slider_range = slider_max - slider_min; - slider_steps = slider_range / step; - cursor_offset = (slider_value - slider_min) / step; - - /* remove one cursor size to support visual cursor */ - bounds.x += style->cursor_size.x*0.5f; - bounds.w -= style->cursor_size.x; - - /* calculate cursor - Basically you have two cursors. One for visual representation and interaction - and one for updating the actual cursor value. */ - logical_cursor.h = bounds.h; - logical_cursor.w = bounds.w / slider_steps; - logical_cursor.x = bounds.x + (logical_cursor.w * cursor_offset); - logical_cursor.y = bounds.y; - - visual_cursor.h = style->cursor_size.y; - visual_cursor.w = style->cursor_size.x; - visual_cursor.y = (bounds.y + bounds.h*0.5f) - visual_cursor.h*0.5f; - visual_cursor.x = (logical_cursor.x + logical_cursor.w*0.5f) - visual_cursor.w*0.5f; - - slider_value = nk_slider_behavior(state, &logical_cursor, &visual_cursor, - in, style, bounds, slider_min, slider_max, slider_value, step, slider_steps); - visual_cursor.x = logical_cursor.x - visual_cursor.w*0.5f; - - /* draw slider */ - if (style->draw_begin) style->draw_begin(out, style->userdata); - nk_draw_slider(out, *state, style, &bounds, &visual_cursor, slider_min, slider_value, slider_max); - if (style->draw_end) style->draw_end(out, style->userdata); - return slider_value; -} - -/* =============================================================== - * - * PROGRESSBAR - * - * ===============================================================*/ -NK_INTERN nk_size -nk_progress_behavior(nk_flags *state, const struct nk_input *in, - struct nk_rect r, nk_size max, nk_size value, int modifiable) -{ - nk_widget_state_reset(state); - if (in && modifiable && nk_input_is_mouse_hovering_rect(in, r)) { - int left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down; - int left_mouse_click_in_cursor = nk_input_has_mouse_click_down_in_rect(in, - NK_BUTTON_LEFT, r, nk_true); - - if (left_mouse_down && left_mouse_click_in_cursor) { - float ratio = NK_MAX(0, (float)(in->mouse.pos.x - r.x)) / (float)r.w; - value = (nk_size)NK_MAX(0,((float)max * ratio)); - *state = NK_WIDGET_STATE_ACTIVE; - } else *state = NK_WIDGET_STATE_HOVERED; - } - - /* set progressbar widget state */ - if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, r)) - *state |= NK_WIDGET_STATE_ENTERED; - else if (nk_input_is_mouse_prev_hovering_rect(in, r)) - *state |= NK_WIDGET_STATE_LEFT; - - if (!max) return value; - value = NK_MIN(value, max); - return value; -} - -NK_INTERN 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) -{ - const struct nk_style_item *background; - const struct nk_style_item *cursor; - - NK_UNUSED(max); - NK_UNUSED(value); - - /* select correct colors/images to draw */ - if (state & NK_WIDGET_STATE_ACTIVED) { - background = &style->active; - cursor = &style->cursor_active; - } else if (state & NK_WIDGET_STATE_HOVER){ - background = &style->hover; - cursor = &style->cursor_hover; - } else { - background = &style->normal; - cursor = &style->cursor_normal; - } - - /* draw background */ - if (background->type == NK_STYLE_ITEM_COLOR) { - nk_fill_rect(out, *bounds, style->rounding, background->data.color); - nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color); - } else nk_draw_image(out, *bounds, &background->data.image, nk_white); - - /* draw cursor */ - if (background->type == NK_STYLE_ITEM_COLOR) { - nk_fill_rect(out, *scursor, style->rounding, cursor->data.color); - nk_stroke_rect(out, *scursor, style->rounding, style->border, style->border_color); - } else nk_draw_image(out, *scursor, &cursor->data.image, nk_white); -} - -NK_INTERN 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, const struct nk_input *in) -{ - float prog_scale; - nk_size prog_value; - struct nk_rect cursor; - - NK_ASSERT(style); - NK_ASSERT(out); - if (!out || !style) return 0; - - /* calculate progressbar cursor */ - cursor.w = NK_MAX(bounds.w, 2 * style->padding.x + 2 * style->border); - cursor.h = NK_MAX(bounds.h, 2 * style->padding.y + 2 * style->border); - cursor = nk_pad_rect(bounds, nk_vec2(style->padding.x + style->border, style->padding.y + style->border)); - prog_scale = (float)value / (float)max; - cursor.w = (bounds.w - 2) * prog_scale; - - /* update progressbar */ - prog_value = NK_MIN(value, max); - prog_value = nk_progress_behavior(state, in, bounds, max, prog_value, modifiable); - - /* draw progressbar */ - if (style->draw_begin) style->draw_begin(out, style->userdata); - nk_draw_progress(out, *state, style, &bounds, &cursor, value, max); - if (style->draw_end) style->draw_end(out, style->userdata); - return prog_value; -} - -/* =============================================================== - * - * SCROLLBAR - * - * ===============================================================*/ -NK_INTERN 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) -{ - nk_flags ws; - int left_mouse_down; - int left_mouse_click_in_cursor; - - nk_widget_state_reset(state); - if (!in) return scroll_offset; - - left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down; - left_mouse_click_in_cursor = nk_input_has_mouse_click_down_in_rect(in, - NK_BUTTON_LEFT, *cursor, nk_true); - if (nk_input_is_mouse_hovering_rect(in, *scroll)) - *state = NK_WIDGET_STATE_HOVERED; - - if (left_mouse_down && left_mouse_click_in_cursor) { - /* update cursor by mouse dragging */ - float pixel, delta; - *state = NK_WIDGET_STATE_ACTIVE; - if (o == NK_VERTICAL) { - float cursor_y; - pixel = in->mouse.delta.y; - delta = (pixel / scroll->h) * target; - scroll_offset = NK_CLAMP(0, scroll_offset + delta, target - scroll->h); - cursor_y = scroll->y + ((scroll_offset/target) * scroll->h); - in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y = cursor_y + cursor->h/2.0f; - } else { - float cursor_x; - pixel = in->mouse.delta.x; - delta = (pixel / scroll->w) * target; - scroll_offset = NK_CLAMP(0, scroll_offset + delta, target - scroll->w); - cursor_x = scroll->x + ((scroll_offset/target) * scroll->w); - in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = cursor_x + cursor->w/2.0f; - } - } else if ((nk_input_is_key_pressed(in, NK_KEY_SCROLL_UP) && o == NK_VERTICAL && has_scrolling)|| - nk_button_behavior(&ws, *empty0, in, NK_BUTTON_DEFAULT)) { - /* scroll page up by click on empty space or shortcut */ - if (o == NK_VERTICAL) - scroll_offset = NK_MAX(0, scroll_offset - scroll->h); - else scroll_offset = NK_MAX(0, scroll_offset - scroll->w); - } else if ((nk_input_is_key_pressed(in, NK_KEY_SCROLL_DOWN) && o == NK_VERTICAL && has_scrolling) || - nk_button_behavior(&ws, *empty1, in, NK_BUTTON_DEFAULT)) { - /* scroll page down by click on empty space or shortcut */ - if (o == NK_VERTICAL) - scroll_offset = NK_MIN(scroll_offset + scroll->h, target - scroll->h); - else scroll_offset = NK_MIN(scroll_offset + scroll->w, target - scroll->w); - } else if (has_scrolling) { - if ((in->mouse.scroll_delta<0 || (in->mouse.scroll_delta>0))) { - /* update cursor by mouse scrolling */ - scroll_offset = scroll_offset + scroll_step * (-in->mouse.scroll_delta); - if (o == NK_VERTICAL) - scroll_offset = NK_CLAMP(0, scroll_offset, target - scroll->h); - else scroll_offset = NK_CLAMP(0, scroll_offset, target - scroll->w); - } else if (nk_input_is_key_pressed(in, NK_KEY_SCROLL_START)) { - /* update cursor to the beginning */ - if (o == NK_VERTICAL) scroll_offset = 0; - } else if (nk_input_is_key_pressed(in, NK_KEY_SCROLL_END)) { - /* update cursor to the end */ - if (o == NK_VERTICAL) scroll_offset = target - scroll->h; - } - } - if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, *scroll)) - *state |= NK_WIDGET_STATE_ENTERED; - else if (nk_input_is_mouse_prev_hovering_rect(in, *scroll)) - *state |= NK_WIDGET_STATE_LEFT; - return scroll_offset; -} - -NK_INTERN 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) -{ - const struct nk_style_item *background; - const struct nk_style_item *cursor; - - /* select correct colors/images to draw */ - if (state & NK_WIDGET_STATE_ACTIVED) { - background = &style->active; - cursor = &style->cursor_active; - } else if (state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - cursor = &style->cursor_hover; - } else { - background = &style->normal; - cursor = &style->cursor_normal; - } - - /* draw background */ - if (background->type == NK_STYLE_ITEM_COLOR) { - nk_fill_rect(out, *bounds, style->rounding, background->data.color); - nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color); - } else { - nk_draw_image(out, *bounds, &background->data.image, nk_white); - } - - /* draw cursor */ - if (background->type == NK_STYLE_ITEM_COLOR) { - nk_fill_rect(out, *scroll, style->rounding_cursor, cursor->data.color); - nk_stroke_rect(out, *scroll, style->rounding_cursor, style->border_cursor, style->cursor_border_color); - } else nk_draw_image(out, *scroll, &cursor->data.image, nk_white); -} - -NK_INTERN 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) -{ - struct nk_rect empty_north; - struct nk_rect empty_south; - struct nk_rect cursor; - - float scroll_step; - float scroll_offset; - float scroll_off; - float scroll_ratio; - - NK_ASSERT(out); - NK_ASSERT(style); - NK_ASSERT(state); - if (!out || !style) return 0; - - scroll.w = NK_MAX(scroll.w, 1); - scroll.h = NK_MAX(scroll.h, 2 * scroll.w); - if (target <= scroll.h) return 0; - - /* optional scrollbar buttons */ - if (style->show_buttons) { - nk_flags ws; - float scroll_h; - struct nk_rect button; - - button.x = scroll.x; - button.w = scroll.w; - button.h = scroll.w; - - scroll_h = scroll.h - 2 * button.h; - scroll_step = NK_MIN(step, button_pixel_inc); - - /* decrement button */ - button.y = scroll.y; - if (nk_do_button_symbol(&ws, out, button, style->dec_symbol, - NK_BUTTON_REPEATER, &style->dec_button, in, font)) - offset = offset - scroll_step; - - /* increment button */ - button.y = scroll.y + scroll.h - button.h; - if (nk_do_button_symbol(&ws, out, button, style->inc_symbol, - NK_BUTTON_REPEATER, &style->inc_button, in, font)) - offset = offset + scroll_step; - - scroll.y = scroll.y + button.h; - scroll.h = scroll_h; - } - - /* calculate scrollbar constants */ - scroll_step = NK_MIN(step, scroll.h); - scroll_offset = NK_CLAMP(0, offset, target - scroll.h); - scroll_ratio = scroll.h / target; - scroll_off = scroll_offset / target; - - /* calculate scrollbar cursor bounds */ - cursor.h = (scroll_ratio * scroll.h) - (2*style->border + 2*style->padding.y); - cursor.y = scroll.y + (scroll_off * scroll.h) + style->border + style->padding.y; - cursor.w = scroll.w - (2 * style->border + 2 * style->padding.x); - cursor.x = scroll.x + style->border + style->padding.x; - - /* calculate empty space around cursor */ - empty_north.x = scroll.x; - empty_north.y = scroll.y; - empty_north.w = scroll.w; - empty_north.h = cursor.y - scroll.y; - - empty_south.x = scroll.x; - empty_south.y = cursor.y + cursor.h; - empty_south.w = scroll.w; - empty_south.h = (scroll.y + scroll.h) - (cursor.y + cursor.h); - - /* update scrollbar */ - scroll_offset = nk_scrollbar_behavior(state, in, has_scrolling, &scroll, &cursor, - &empty_north, &empty_south, scroll_offset, target, scroll_step, NK_VERTICAL); - scroll_off = scroll_offset / target; - cursor.y = scroll.y + (scroll_off * scroll.h) + style->border_cursor + style->padding.y; - - /* draw scrollbar */ - if (style->draw_begin) style->draw_begin(out, style->userdata); - nk_draw_scrollbar(out, *state, style, &scroll, &cursor); - if (style->draw_end) style->draw_end(out, style->userdata); - return scroll_offset; -} - -NK_INTERN 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) -{ - struct nk_rect cursor; - struct nk_rect empty_west; - struct nk_rect empty_east; - - float scroll_step; - float scroll_offset; - float scroll_off; - float scroll_ratio; - - NK_ASSERT(out); - NK_ASSERT(style); - if (!out || !style) return 0; - - /* scrollbar background */ - scroll.h = NK_MAX(scroll.h, 1); - scroll.w = NK_MAX(scroll.w, 2 * scroll.h); - if (target <= scroll.w) return 0; - - /* optional scrollbar buttons */ - if (style->show_buttons) { - nk_flags ws; - float scroll_w; - struct nk_rect button; - button.y = scroll.y; - button.w = scroll.h; - button.h = scroll.h; - - scroll_w = scroll.w - 2 * button.w; - scroll_step = NK_MIN(step, button_pixel_inc); - - /* decrement button */ - button.x = scroll.x; - if (nk_do_button_symbol(&ws, out, button, style->dec_symbol, - NK_BUTTON_REPEATER, &style->dec_button, in, font)) - offset = offset - scroll_step; - - /* increment button */ - button.x = scroll.x + scroll.w - button.w; - if (nk_do_button_symbol(&ws, out, button, style->inc_symbol, - NK_BUTTON_REPEATER, &style->inc_button, in, font)) - offset = offset + scroll_step; - - scroll.x = scroll.x + button.w; - scroll.w = scroll_w; - } - - /* calculate scrollbar constants */ - scroll_step = NK_MIN(step, scroll.w); - scroll_offset = NK_CLAMP(0, offset, target - scroll.w); - scroll_ratio = scroll.w / target; - scroll_off = scroll_offset / target; - - /* calculate cursor bounds */ - cursor.w = (scroll_ratio * scroll.w) - (2*style->border + 2*style->padding.x); - cursor.x = scroll.x + (scroll_off * scroll.w) + style->border + style->padding.x; - cursor.h = scroll.h - (2 * style->border + 2 * style->padding.y); - cursor.y = scroll.y + style->border + style->padding.y; - - /* calculate empty space around cursor */ - empty_west.x = scroll.x; - empty_west.y = scroll.y; - empty_west.w = cursor.x - scroll.x; - empty_west.h = scroll.h; - - empty_east.x = cursor.x + cursor.w; - empty_east.y = scroll.y; - empty_east.w = (scroll.x + scroll.w) - (cursor.x + cursor.w); - empty_east.h = scroll.h; - - /* update scrollbar */ - scroll_offset = nk_scrollbar_behavior(state, in, has_scrolling, &scroll, &cursor, - &empty_west, &empty_east, scroll_offset, target, scroll_step, NK_HORIZONTAL); - scroll_off = scroll_offset / target; - cursor.x = scroll.x + (scroll_off * scroll.w); - - /* draw scrollbar */ - if (style->draw_begin) style->draw_begin(out, style->userdata); - nk_draw_scrollbar(out, *state, style, &scroll, &cursor); - if (style->draw_end) style->draw_end(out, style->userdata); - return scroll_offset; -} - -/* =============================================================== - * - * FILTER - * - * ===============================================================*/ -NK_API int nk_filter_default(const struct nk_text_edit *box, nk_rune unicode) -{(void)unicode;NK_UNUSED(box);return nk_true;} - -NK_API int -nk_filter_ascii(const struct nk_text_edit *box, nk_rune unicode) -{ - NK_UNUSED(box); - if (unicode > 128) return nk_false; - else return nk_true; -} - -NK_API int -nk_filter_float(const struct nk_text_edit *box, nk_rune unicode) -{ - NK_UNUSED(box); - if ((unicode < '0' || unicode > '9') && unicode != '.' && unicode != '-') - return nk_false; - else return nk_true; -} - -NK_API int -nk_filter_decimal(const struct nk_text_edit *box, nk_rune unicode) -{ - NK_UNUSED(box); - if ((unicode < '0' || unicode > '9') && unicode != '-') - return nk_false; - else return nk_true; -} - -NK_API int -nk_filter_hex(const struct nk_text_edit *box, nk_rune unicode) -{ - NK_UNUSED(box); - if ((unicode < '0' || unicode > '9') && - (unicode < 'a' || unicode > 'f') && - (unicode < 'A' || unicode > 'F')) - return nk_false; - else return nk_true; -} - -NK_API int -nk_filter_oct(const struct nk_text_edit *box, nk_rune unicode) -{ - NK_UNUSED(box); - if (unicode < '0' || unicode > '7') - return nk_false; - else return nk_true; -} - -NK_API int -nk_filter_binary(const struct nk_text_edit *box, nk_rune unicode) -{ - NK_UNUSED(box); - if (unicode != '0' && unicode != '1') - return nk_false; - else return nk_true; -} - -/* =============================================================== - * - * EDIT - * - * ===============================================================*/ -NK_INTERN 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) -{ - NK_ASSERT(out); - NK_ASSERT(font); - NK_ASSERT(style); - if (!text || !byte_len || !out || !style) return; - - {int glyph_len = 0; - nk_rune unicode = 0; - int text_len = 0; - float line_width = 0; - float glyph_width; - const char *line = text; - float line_offset = 0; - int line_count = 0; - - struct nk_text txt; - txt.padding = nk_vec2(0,0); - txt.background = background; - txt.text = foreground; - - glyph_len = nk_utf_decode(text+text_len, &unicode, byte_len-text_len); - if (!glyph_len) return; - while ((text_len < byte_len) && glyph_len) - { - if (unicode == '\n') { - /* new line sepeator so draw previous line */ - struct nk_rect label; - label.y = pos_y + line_offset; - label.h = row_height; - label.w = line_width; - label.x = pos_x; - if (!line_count) - label.x += x_offset; - - if (is_selected) /* selection needs to draw different background color */ - nk_fill_rect(out, label, 0, background); - nk_widget_text(out, label, line, (int)((text + text_len) - line), - &txt, NK_TEXT_CENTERED, font); - - text_len++; - line_count++; - line_width = 0; - line = text + text_len; - line_offset += row_height; - glyph_len = nk_utf_decode(text + text_len, &unicode, (int)(byte_len-text_len)); - continue; - } - if (unicode == '\r') { - text_len++; - glyph_len = nk_utf_decode(text + text_len, &unicode, byte_len-text_len); - continue; - } - glyph_width = font->width(font->userdata, font->height, text+text_len, glyph_len); - line_width += (float)glyph_width; - text_len += glyph_len; - glyph_len = nk_utf_decode(text + text_len, &unicode, byte_len-text_len); - continue; - } - if (line_width > 0) { - /* draw last line */ - struct nk_rect label; - label.y = pos_y + line_offset; - label.h = row_height; - label.w = line_width; - label.x = pos_x; - if (!line_count) - label.x += x_offset; - - if (is_selected) - nk_fill_rect(out, label, 0, background); - nk_widget_text(out, label, line, (int)((text + text_len) - line), - &txt, NK_TEXT_LEFT, font); - }} -} - -NK_INTERN 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) -{ - struct nk_rect area; - nk_flags ret = 0; - float row_height; - char prev_state = 0; - char is_hovered = 0; - char select_all = 0; - char cursor_follow = 0; - struct nk_rect old_clip; - struct nk_rect clip; - - NK_ASSERT(state); - NK_ASSERT(out); - NK_ASSERT(style); - if (!state || !out || !style) - return ret; - - /* visible text area calculation */ - area.x = bounds.x + style->padding.x + style->border; - area.y = bounds.y + style->padding.y + style->border; - area.w = bounds.w - (2.0f * style->padding.x + 2 * style->border); - area.h = bounds.h - (2.0f * style->padding.y + 2 * style->border); - if (flags & NK_EDIT_MULTILINE) - area.w = NK_MAX(0, area.w - style->scrollbar_size.x); - row_height = (flags & NK_EDIT_MULTILINE)? font->height + style->row_padding: area.h; - - /* calculate clipping rectangle */ - old_clip = out->clip; - nk_unify(&clip, &old_clip, area.x, area.y, area.x + area.w, area.y + area.h); - - /* update edit state */ - prev_state = (char)edit->active; - is_hovered = (char)nk_input_is_mouse_hovering_rect(in, bounds); - if (in && in->mouse.buttons[NK_BUTTON_LEFT].clicked && in->mouse.buttons[NK_BUTTON_LEFT].down) { - edit->active = NK_INBOX(in->mouse.pos.x, in->mouse.pos.y, - bounds.x, bounds.y, bounds.w, bounds.h); - } - - /* (de)activate text editor */ - if (!prev_state && edit->active) { - const enum nk_text_edit_type type = (flags & NK_EDIT_MULTILINE) ? - NK_TEXT_EDIT_MULTI_LINE: NK_TEXT_EDIT_SINGLE_LINE; - nk_textedit_clear_state(edit, type, filter); - if (flags & NK_EDIT_ALWAYS_INSERT_MODE) - edit->mode = NK_TEXT_EDIT_MODE_INSERT; - if (flags & NK_EDIT_AUTO_SELECT) - select_all = nk_true; - if (flags & NK_EDIT_GOTO_END_ON_ACTIVATE) { - edit->cursor = edit->string.len; - in = 0; - } - } else if (!edit->active) edit->mode = NK_TEXT_EDIT_MODE_VIEW; - if (flags & NK_EDIT_READ_ONLY) - edit->mode = NK_TEXT_EDIT_MODE_VIEW; - - ret = (edit->active) ? NK_EDIT_ACTIVE: NK_EDIT_INACTIVE; - if (prev_state != edit->active) - ret |= (edit->active) ? NK_EDIT_ACTIVATED: NK_EDIT_DEACTIVATED; - - /* handle user input */ - if (edit->active && in) - { - int shift_mod = in->keyboard.keys[NK_KEY_SHIFT].down; - const float mouse_x = (in->mouse.pos.x - area.x) + edit->scrollbar.x; - const float mouse_y = (in->mouse.pos.y - area.y) + edit->scrollbar.y; - - /* mouse click handler */ - is_hovered = (char)nk_input_is_mouse_hovering_rect(in, area); - if (select_all) { - nk_textedit_select_all(edit); - } else if (is_hovered && in->mouse.buttons[NK_BUTTON_LEFT].down && - in->mouse.buttons[NK_BUTTON_LEFT].clicked) { - nk_textedit_click(edit, mouse_x, mouse_y, font, row_height); - } else if (is_hovered && in->mouse.buttons[NK_BUTTON_LEFT].down && - (in->mouse.delta.x != 0.0f || in->mouse.delta.y != 0.0f)) { - nk_textedit_drag(edit, mouse_x, mouse_y, font, row_height); - cursor_follow = nk_true; - } else if (is_hovered && in->mouse.buttons[NK_BUTTON_RIGHT].clicked && - in->mouse.buttons[NK_BUTTON_RIGHT].down) { - nk_textedit_key(edit, NK_KEY_TEXT_WORD_LEFT, nk_false, font, row_height); - nk_textedit_key(edit, NK_KEY_TEXT_WORD_RIGHT, nk_true, font, row_height); - cursor_follow = nk_true; - } - - {int i; /* keyboard input */ - int old_mode = edit->mode; - for (i = 0; i < NK_KEY_MAX; ++i) { - if (i == NK_KEY_ENTER || i == NK_KEY_TAB) continue; /* special case */ - if (nk_input_is_key_pressed(in, (enum nk_keys)i)) { - nk_textedit_key(edit, (enum nk_keys)i, shift_mod, font, row_height); - cursor_follow = nk_true; - } - } - if (old_mode != edit->mode) { - in->keyboard.text_len = 0; - }} - - /* text input */ - edit->filter = filter; - if (in->keyboard.text_len) { - nk_textedit_text(edit, in->keyboard.text, in->keyboard.text_len); - cursor_follow = nk_true; - in->keyboard.text_len = 0; - } - - /* enter key handler */ - if (nk_input_is_key_pressed(in, NK_KEY_ENTER)) { - cursor_follow = nk_true; - if (flags & NK_EDIT_CTRL_ENTER_NEWLINE && shift_mod) - nk_textedit_text(edit, "\n", 1); - else if (flags & NK_EDIT_SIG_ENTER) - ret |= NK_EDIT_COMMITED; - else nk_textedit_text(edit, "\n", 1); - } - - /* cut & copy handler */ - {int copy= nk_input_is_key_pressed(in, NK_KEY_COPY); - int cut = nk_input_is_key_pressed(in, NK_KEY_CUT); - if ((copy || cut) && (flags & NK_EDIT_CLIPBOARD)) - { - int glyph_len; - nk_rune unicode; - const char *text; - int b = edit->select_start; - int e = edit->select_end; - - int begin = NK_MIN(b, e); - int end = NK_MAX(b, e); - text = nk_str_at_const(&edit->string, begin, &unicode, &glyph_len); - if (edit->clip.copy) - edit->clip.copy(edit->clip.userdata, text, end - begin); - if (cut && !(flags & NK_EDIT_READ_ONLY)){ - nk_textedit_cut(edit); - cursor_follow = nk_true; - } - }} - - /* paste handler */ - {int paste = nk_input_is_key_pressed(in, NK_KEY_PASTE); - if (paste && (flags & NK_EDIT_CLIPBOARD) && edit->clip.paste) { - edit->clip.paste(edit->clip.userdata, edit); - cursor_follow = nk_true; - }} - - /* tab handler */ - {int tab = nk_input_is_key_pressed(in, NK_KEY_TAB); - if (tab && (flags & NK_EDIT_ALLOW_TAB)) { - nk_textedit_text(edit, " ", 4); - cursor_follow = nk_true; - }} - } - - /* set widget state */ - if (edit->active) - *state = NK_WIDGET_STATE_ACTIVE; - else nk_widget_state_reset(state); - - if (is_hovered) - *state |= NK_WIDGET_STATE_HOVERED; - - /* DRAW EDIT */ - {const char *text = nk_str_get_const(&edit->string); - int len = nk_str_len_char(&edit->string); - - {/* select background colors/images */ - const struct nk_style_item *background; - if (*state & NK_WIDGET_STATE_ACTIVED) - background = &style->active; - else if (*state & NK_WIDGET_STATE_HOVER) - background = &style->hover; - else background = &style->normal; - - /* draw background frame */ - if (background->type == NK_STYLE_ITEM_COLOR) { - nk_stroke_rect(out, bounds, style->rounding, style->border, style->border_color); - nk_fill_rect(out, bounds, style->rounding, background->data.color); - } else nk_draw_image(out, bounds, &background->data.image, nk_white);} - - area.w = NK_MAX(0, area.w - style->cursor_size); - if (edit->active) - { - int total_lines = 1; - struct nk_vec2 text_size = nk_vec2(0,0); - - /* text pointer positions */ - const char *cursor_ptr = 0; - const char *select_begin_ptr = 0; - const char *select_end_ptr = 0; - - /* 2D pixel positions */ - struct nk_vec2 cursor_pos = nk_vec2(0,0); - struct nk_vec2 selection_offset_start = nk_vec2(0,0); - struct nk_vec2 selection_offset_end = nk_vec2(0,0); - - int selection_begin = NK_MIN(edit->select_start, edit->select_end); - int selection_end = NK_MAX(edit->select_start, edit->select_end); - - /* calculate total line count + total space + cursor/selection position */ - float line_width = 0.0f; - if (text && len) - { - /* utf8 encoding */ - float glyph_width; - int glyph_len = 0; - nk_rune unicode = 0; - int text_len = 0; - int glyphs = 0; - int row_begin = 0; - - glyph_len = nk_utf_decode(text, &unicode, len); - glyph_width = font->width(font->userdata, font->height, text, glyph_len); - line_width = 0; - - /* iterate all lines */ - while ((text_len < len) && glyph_len) - { - /* set cursor 2D position and line */ - if (!cursor_ptr && glyphs == edit->cursor) - { - int glyph_offset; - struct nk_vec2 out_offset; - struct nk_vec2 row_size; - const char *remaining; - - /* calculate 2d position */ - cursor_pos.y = (float)(total_lines-1) * row_height; - row_size = nk_text_calculate_text_bounds(font, text+row_begin, - text_len-row_begin, row_height, &remaining, - &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE); - cursor_pos.x = row_size.x; - cursor_ptr = text + text_len; - } - - /* set start selection 2D position and line */ - if (!select_begin_ptr && edit->select_start != edit->select_end && - glyphs == selection_begin) - { - int glyph_offset; - struct nk_vec2 out_offset; - struct nk_vec2 row_size; - const char *remaining; - - /* calculate 2d position */ - selection_offset_start.y = (float)(NK_MAX(total_lines-1,0)) * row_height; - row_size = nk_text_calculate_text_bounds(font, text+row_begin, - text_len-row_begin, row_height, &remaining, - &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE); - selection_offset_start.x = row_size.x; - select_begin_ptr = text + text_len; - } - - /* set end selection 2D position and line */ - if (!select_end_ptr && edit->select_start != edit->select_end && - glyphs == selection_end) - { - int glyph_offset; - struct nk_vec2 out_offset; - struct nk_vec2 row_size; - const char *remaining; - - /* calculate 2d position */ - selection_offset_end.y = (float)(total_lines-1) * row_height; - row_size = nk_text_calculate_text_bounds(font, text+row_begin, - text_len-row_begin, row_height, &remaining, - &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE); - selection_offset_end.x = row_size.x; - select_end_ptr = text + text_len; - } - if (unicode == '\n') { - text_size.x = NK_MAX(text_size.x, line_width); - total_lines++; - line_width = 0; - text_len++; - glyphs++; - row_begin = text_len; - glyph_len = nk_utf_decode(text + text_len, &unicode, len-text_len); - glyph_width = font->width(font->userdata, font->height, text+text_len, glyph_len); - continue; - } - - glyphs++; - text_len += glyph_len; - line_width += (float)glyph_width; - - glyph_len = nk_utf_decode(text + text_len, &unicode, len-text_len); - glyph_width = font->width(font->userdata, font->height, - text+text_len, glyph_len); - continue; - } - text_size.y = (float)total_lines * row_height; - - /* handle case when cursor is at end of text buffer */ - if (!cursor_ptr && edit->cursor == edit->string.len) { - cursor_pos.x = line_width; - cursor_pos.y = text_size.y - row_height; - } - } - { - /* scrollbar */ - if (cursor_follow) - { - /* update scrollbar to follow cursor */ - if (!(flags & NK_EDIT_NO_HORIZONTAL_SCROLL)) { - /* horizontal scroll */ - const float scroll_increment = area.w * 0.25f; - if (cursor_pos.x < edit->scrollbar.x) - edit->scrollbar.x = (float)(int)NK_MAX(0.0f, cursor_pos.x - scroll_increment); - if (cursor_pos.x >= edit->scrollbar.x + area.w) - edit->scrollbar.x = (float)(int)NK_MAX(0.0f, cursor_pos.x); - } else edit->scrollbar.x = 0; - - if (flags & NK_EDIT_MULTILINE) { - /* vertical scroll */ - if (cursor_pos.y < edit->scrollbar.y) - edit->scrollbar.y = NK_MAX(0.0f, cursor_pos.y - row_height); - if (cursor_pos.y >= edit->scrollbar.y + area.h) - edit->scrollbar.y = edit->scrollbar.y + row_height; - } else edit->scrollbar.y = 0; - } - - /* scrollbar widget */ - if (flags & NK_EDIT_MULTILINE) - { - nk_flags ws; - struct nk_rect scroll; - float scroll_target; - float scroll_offset; - float scroll_step; - float scroll_inc; - - scroll = area; - scroll.x = (bounds.x + bounds.w - style->border) - style->scrollbar_size.x; - scroll.w = style->scrollbar_size.x; - - scroll_offset = edit->scrollbar.y; - scroll_step = scroll.h * 0.10f; - scroll_inc = scroll.h * 0.01f; - scroll_target = text_size.y; - edit->scrollbar.y = nk_do_scrollbarv(&ws, out, scroll, 0, - scroll_offset, scroll_target, scroll_step, scroll_inc, - &style->scrollbar, in, font); - } - } - - /* draw text */ - {struct nk_color background_color; - struct nk_color text_color; - struct nk_color sel_background_color; - struct nk_color sel_text_color; - struct nk_color cursor_color; - struct nk_color cursor_text_color; - const struct nk_style_item *background; - nk_push_scissor(out, clip); - - /* select correct colors to draw */ - if (*state & NK_WIDGET_STATE_ACTIVED) { - background = &style->active; - text_color = style->text_active; - sel_text_color = style->selected_text_hover; - sel_background_color = style->selected_hover; - cursor_color = style->cursor_hover; - cursor_text_color = style->cursor_text_hover; - } else if (*state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - text_color = style->text_hover; - sel_text_color = style->selected_text_hover; - sel_background_color = style->selected_hover; - cursor_text_color = style->cursor_text_hover; - cursor_color = style->cursor_hover; - } else { - background = &style->normal; - text_color = style->text_normal; - sel_text_color = style->selected_text_normal; - sel_background_color = style->selected_normal; - cursor_color = style->cursor_normal; - cursor_text_color = style->cursor_text_normal; - } - if (background->type == NK_STYLE_ITEM_IMAGE) - background_color = nk_rgba(0,0,0,0); - else background_color = background->data.color; - - - if (edit->select_start == edit->select_end) { - /* no selection so just draw the complete text */ - const char *begin = nk_str_get_const(&edit->string); - int l = nk_str_len_char(&edit->string); - nk_edit_draw_text(out, style, area.x - edit->scrollbar.x, - area.y - edit->scrollbar.y, 0, begin, l, row_height, font, - background_color, text_color, nk_false); - } else { - /* edit has selection so draw 1-3 text chunks */ - if (edit->select_start != edit->select_end && selection_begin > 0){ - /* draw unselected text before selection */ - const char *begin = nk_str_get_const(&edit->string); - NK_ASSERT(select_begin_ptr); - nk_edit_draw_text(out, style, area.x - edit->scrollbar.x, - area.y - edit->scrollbar.y, 0, begin, (int)(select_begin_ptr - begin), - row_height, font, background_color, text_color, nk_false); - } - if (edit->select_start != edit->select_end) { - /* draw selected text */ - NK_ASSERT(select_begin_ptr); - if (!select_end_ptr) { - const char *begin = nk_str_get_const(&edit->string); - select_end_ptr = begin + nk_str_len_char(&edit->string); - } - nk_edit_draw_text(out, style, - area.x - edit->scrollbar.x, - area.y + selection_offset_start.y - edit->scrollbar.y, - selection_offset_start.x, - select_begin_ptr, (int)(select_end_ptr - select_begin_ptr), - row_height, font, sel_background_color, sel_text_color, nk_true); - } - if ((edit->select_start != edit->select_end && - selection_end < edit->string.len)) - { - /* draw unselected text after selected text */ - const char *begin = select_end_ptr; - const char *end = nk_str_get_const(&edit->string) + - nk_str_len_char(&edit->string); - NK_ASSERT(select_end_ptr); - nk_edit_draw_text(out, style, - area.x - edit->scrollbar.x, - area.y + selection_offset_end.y - edit->scrollbar.y, - selection_offset_end.x, - begin, (int)(end - begin), row_height, font, - background_color, text_color, nk_true); - } - } - - /* cursor */ - if (edit->select_start == edit->select_end) - { - if (edit->cursor >= nk_str_len(&edit->string) || - (cursor_ptr && *cursor_ptr == '\n')) { - /* draw cursor at end of line */ - struct nk_rect cursor; - cursor.w = style->cursor_size; - cursor.h = font->height; - cursor.x = area.x + cursor_pos.x - edit->scrollbar.x; - cursor.y = area.y + cursor_pos.y + row_height/2.0f - cursor.h/2.0f; - cursor.y -= edit->scrollbar.y; - nk_fill_rect(out, cursor, 0, cursor_color); - } else { - /* draw cursor inside text */ - int glyph_len; - struct nk_rect label; - struct nk_text txt; - - nk_rune unicode; - NK_ASSERT(cursor_ptr); - glyph_len = nk_utf_decode(cursor_ptr, &unicode, 4); - - label.x = area.x + cursor_pos.x - edit->scrollbar.x; - label.y = area.y + cursor_pos.y - edit->scrollbar.y; - label.w = font->width(font->userdata, font->height, cursor_ptr, glyph_len); - label.h = row_height; - - txt.padding = nk_vec2(0,0); - txt.background = cursor_color;; - txt.text = cursor_text_color; - nk_fill_rect(out, label, 0, cursor_color); - nk_widget_text(out, label, cursor_ptr, glyph_len, &txt, NK_TEXT_LEFT, font); - } - }} - } else { - /* not active so just draw text */ - int l = nk_str_len_char(&edit->string); - const char *begin = nk_str_get_const(&edit->string); - - const struct nk_style_item *background; - struct nk_color background_color; - struct nk_color text_color; - nk_push_scissor(out, clip); - if (*state & NK_WIDGET_STATE_ACTIVED) { - background = &style->active; - text_color = style->text_active; - } else if (*state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - text_color = style->text_hover; - } else { - background = &style->normal; - text_color = style->text_normal; - } - if (background->type == NK_STYLE_ITEM_IMAGE) - background_color = nk_rgba(0,0,0,0); - else background_color = background->data.color; - nk_edit_draw_text(out, style, area.x - edit->scrollbar.x, - area.y - edit->scrollbar.y, 0, begin, l, row_height, font, - background_color, text_color, nk_false); - } - nk_push_scissor(out, old_clip);} - return ret; -} - -/* =============================================================== - * - * PROPERTY - * - * ===============================================================*/ -enum nk_property_status { - NK_PROPERTY_DEFAULT, - NK_PROPERTY_EDIT, - NK_PROPERTY_DRAG -}; -enum nk_property_filter { - NK_FILTER_INT, - NK_FILTER_FLOAT -}; -enum nk_property_kind { - NK_PROPERTY_INT, - NK_PROPERTY_FLOAT, - NK_PROPERTY_DOUBLE -}; -union nk_property { - int i; - float f; - double d; -}; -struct nk_property_variant { - enum nk_property_kind kind; - union nk_property value; - union nk_property min_value; - union nk_property max_value; - union nk_property step; -}; - -NK_INTERN 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) -{ - int left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down; - int left_mouse_click_in_cursor = in && - nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, drag, nk_true); - - nk_widget_state_reset(state); - if (nk_input_is_mouse_hovering_rect(in, drag)) - *state = NK_WIDGET_STATE_HOVERED; - - if (left_mouse_down && left_mouse_click_in_cursor) { - float delta, pixels; - pixels = in->mouse.delta.x; - delta = pixels * inc_per_pixel; - switch (variant->kind) { - default: break; - case NK_PROPERTY_INT: - variant->value.i = variant->value.i + (int)delta; - variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i); - break; - case NK_PROPERTY_FLOAT: - variant->value.f = variant->value.f + (float)delta; - variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f); - break; - case NK_PROPERTY_DOUBLE: - variant->value.d = variant->value.d + (double)delta; - variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d); - break; - } - *state = NK_WIDGET_STATE_ACTIVE; - } - if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, drag)) - *state |= NK_WIDGET_STATE_ENTERED; - else if (nk_input_is_mouse_prev_hovering_rect(in, drag)) - *state |= NK_WIDGET_STATE_LEFT; -} - -NK_INTERN 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) -{ - if (in && *state == NK_PROPERTY_DEFAULT) { - if (nk_button_behavior(ws, edit, in, NK_BUTTON_DEFAULT)) - *state = NK_PROPERTY_EDIT; - else if (nk_input_is_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, label, nk_true)) - *state = NK_PROPERTY_DRAG; - else if (nk_input_is_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, empty, nk_true)) - *state = NK_PROPERTY_DRAG; - } - if (*state == NK_PROPERTY_DRAG) { - nk_drag_behavior(ws, in, property, variant, inc_per_pixel); - if (!(*ws & NK_WIDGET_STATE_ACTIVED)) *state = NK_PROPERTY_DEFAULT; - } -} - -NK_INTERN 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) -{ - struct nk_text text; - const struct nk_style_item *background; - - /* select correct background and text color */ - if (state & NK_WIDGET_STATE_ACTIVED) { - background = &style->active; - text.text = style->label_active; - } else if (state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - text.text = style->label_hover; - } else { - background = &style->normal; - text.text = style->label_normal; - } - - /* draw background */ - if (background->type == NK_STYLE_ITEM_IMAGE) { - nk_draw_image(out, *bounds, &background->data.image, nk_white); - text.background = nk_rgba(0,0,0,0); - } else { - text.background = background->data.color; - nk_fill_rect(out, *bounds, style->rounding, background->data.color); - nk_stroke_rect(out, *bounds, style->rounding, style->border, background->data.color); - } - - /* draw label */ - text.padding = nk_vec2(0,0); - nk_widget_text(out, *label, name, len, &text, NK_TEXT_CENTERED, font); -} - -NK_INTERN 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, 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) -{ - const nk_plugin_filter filters[] = { - nk_filter_decimal, - nk_filter_float - }; - int active, old; - int num_len, name_len; - char string[NK_MAX_NUMBER_BUFFER]; - float size; - - char *dst = 0; - int *length; - - struct nk_rect left; - struct nk_rect right; - struct nk_rect label; - struct nk_rect edit; - struct nk_rect empty; - - /* left decrement button */ - left.h = font->height/2; - left.w = left.h; - left.x = property.x + style->border + style->padding.x; - left.y = property.y + style->border + property.h/2.0f - left.h/2; - - /* text label */ - name_len = nk_strlen(name); - size = font->width(font->userdata, font->height, name, name_len); - label.x = left.x + left.w + style->padding.x; - label.w = (float)size + 2 * style->padding.x; - label.y = property.y + style->border + style->padding.y; - label.h = property.h - (2 * style->border + 2 * style->padding.y); - - /* right increment button */ - right.y = left.y; - right.w = left.w; - right.h = left.h; - right.x = property.x + property.w - (right.w + style->padding.x); - - /* edit */ - if (*state == NK_PROPERTY_EDIT) { - size = font->width(font->userdata, font->height, buffer, *len); - size += style->edit.cursor_size; - length = len; - dst = buffer; - } else { - switch (variant->kind) { - default: break; - case NK_PROPERTY_INT: - nk_itoa(string, variant->value.i); - num_len = nk_strlen(string); - break; - case NK_PROPERTY_FLOAT: - nk_dtoa(string, (double)variant->value.f); - num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION); - break; - case NK_PROPERTY_DOUBLE: - nk_dtoa(string, variant->value.d); - num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION); - break; - } - size = font->width(font->userdata, font->height, string, num_len); - dst = string; - length = &num_len; - } - - edit.w = (float)size + 2 * style->padding.x; - edit.w = NK_MIN(edit.w, right.x - (label.x + label.w)); - edit.x = right.x - (edit.w + style->padding.x); - edit.y = property.y + style->border; - edit.h = property.h - (2 * style->border); - - /* empty left space activator */ - empty.w = edit.x - (label.x + label.w); - empty.x = label.x + label.w; - empty.y = property.y; - empty.h = property.h; - - /* update property */ - old = (*state == NK_PROPERTY_EDIT); - nk_property_behavior(ws, in, property, label, edit, empty, state, variant, inc_per_pixel); - - /* draw property */ - if (style->draw_begin) style->draw_begin(out, style->userdata); - nk_draw_property(out, style, &property, &label, *ws, name, name_len, font); - if (style->draw_end) style->draw_end(out, style->userdata); - - /* execute right button */ - if (nk_do_button_symbol(ws, out, left, style->sym_left, NK_BUTTON_DEFAULT, &style->dec_button, in, font)) { - switch (variant->kind) { - default: break; - case NK_PROPERTY_INT: - variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i - variant->step.i, variant->max_value.i); break; - case NK_PROPERTY_FLOAT: - variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f - variant->step.f, variant->max_value.f); break; - case NK_PROPERTY_DOUBLE: - variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d - variant->step.d, variant->max_value.d); break; - } - } - - /* execute left button */ - if (nk_do_button_symbol(ws, out, right, style->sym_right, NK_BUTTON_DEFAULT, &style->inc_button, in, font)) { - switch (variant->kind) { - default: break; - case NK_PROPERTY_INT: - variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i + variant->step.i, variant->max_value.i); break; - case NK_PROPERTY_FLOAT: - variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f + variant->step.f, variant->max_value.f); break; - case NK_PROPERTY_DOUBLE: - variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d + variant->step.d, variant->max_value.d); break; - } - } - - active = (*state == NK_PROPERTY_EDIT); - if (old != NK_PROPERTY_EDIT && active) { - /* property has been activated so setup buffer */ - NK_MEMCPY(buffer, dst, (nk_size)*length); - *cursor = nk_utf_len(buffer, *length); - *len = *length; - length = len; - dst = buffer; - } - - /* execute and run text edit field */ - nk_textedit_clear_state(text_edit, NK_TEXT_EDIT_SINGLE_LINE, filters[filter]); - text_edit->active = (unsigned char)active; - text_edit->string.len = *length; - text_edit->cursor = NK_CLAMP(0, *cursor, *length); - text_edit->string.buffer.allocated = (nk_size)*length; - text_edit->string.buffer.memory.size = NK_MAX_NUMBER_BUFFER; - text_edit->string.buffer.memory.ptr = dst; - text_edit->string.buffer.size = NK_MAX_NUMBER_BUFFER; - text_edit->mode = NK_TEXT_EDIT_MODE_INSERT; - nk_do_edit(ws, out, edit, NK_EDIT_ALWAYS_INSERT_MODE, filters[filter], - text_edit, &style->edit, (*state == NK_PROPERTY_EDIT) ? in: 0, font); - - *length = text_edit->string.len; - active = text_edit->active; - *cursor = text_edit->cursor; - - if (active && nk_input_is_key_pressed(in, NK_KEY_ENTER)) - active = !active; - - if (old && !active) { - /* property is now not active so convert edit text to value*/ - *state = NK_PROPERTY_DEFAULT; - buffer[*len] = '\0'; - switch (variant->kind) { - default: break; - case NK_PROPERTY_INT: - variant->value.i = nk_strtoi(buffer, 0); - variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i); - break; - case NK_PROPERTY_FLOAT: - nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION); - variant->value.f = nk_strtof(buffer, 0); - variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f); - break; - case NK_PROPERTY_DOUBLE: - nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION); - variant->value.d = nk_strtod(buffer, 0); - variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d); - break; - } - } -} -/* =============================================================== - * - * COLOR PICKER - * - * ===============================================================*/ -NK_INTERN 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_color *color, const struct nk_input *in) -{ - float hsva[4]; - int value_changed = 0; - int hsv_changed = 0; - - NK_ASSERT(state); - NK_ASSERT(matrix); - NK_ASSERT(hue_bar); - NK_ASSERT(color); - - /* color matrix */ - nk_color_hsva_fv(hsva, *color); - if (nk_button_behavior(state, *matrix, in, NK_BUTTON_REPEATER)) { - hsva[1] = NK_SATURATE((in->mouse.pos.x - matrix->x) / (matrix->w-1)); - hsva[2] = 1.0f - NK_SATURATE((in->mouse.pos.y - matrix->y) / (matrix->h-1)); - value_changed = hsv_changed = 1; - } - - /* hue bar */ - if (nk_button_behavior(state, *hue_bar, in, NK_BUTTON_REPEATER)) { - hsva[0] = NK_SATURATE((in->mouse.pos.y - hue_bar->y) / (hue_bar->h-1)); - value_changed = hsv_changed = 1; - } - - /* alpha bar */ - if (alpha_bar) { - if (nk_button_behavior(state, *alpha_bar, in, NK_BUTTON_REPEATER)) { - hsva[3] = 1.0f - NK_SATURATE((in->mouse.pos.y - alpha_bar->y) / (alpha_bar->h-1)); - value_changed = 1; - } - } - nk_widget_state_reset(state); - if (hsv_changed) { - *color = nk_hsva_fv(hsva); - *state = NK_WIDGET_STATE_ACTIVE; - } - if (value_changed) { - color->a = (nk_byte)(hsva[3] * 255.0f); - *state = NK_WIDGET_STATE_ACTIVE; - } - - /* set color picker widget state */ - if (nk_input_is_mouse_hovering_rect(in, *bounds)) - *state = NK_WIDGET_STATE_HOVERED; - if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, *bounds)) - *state |= NK_WIDGET_STATE_ENTERED; - else if (nk_input_is_mouse_prev_hovering_rect(in, *bounds)) - *state |= NK_WIDGET_STATE_LEFT; - return value_changed; -} - -NK_INTERN 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_color color) -{ - NK_STORAGE const struct nk_color black = {0,0,0,255}; - NK_STORAGE const struct nk_color white = {255, 255, 255, 255}; - NK_STORAGE const struct nk_color black_trans = {0,0,0,0}; - - const float crosshair_size = 7.0f; - struct nk_color temp; - float hsva[4]; - float line_y; - int i; - - NK_ASSERT(o); - NK_ASSERT(matrix); - NK_ASSERT(hue_bar); - - /* draw hue bar */ - nk_color_hsv_fv(hsva, color); - for (i = 0; i < 6; ++i) { - NK_GLOBAL const struct nk_color hue_colors[] = { - {255, 0, 0, 255}, - {255,255,0,255}, - {0,255,0,255}, - {0, 255,255,255}, - {0,0,255,255}, - {255, 0, 255, 255}, - {255, 0, 0, 255} - }; - nk_fill_rect_multi_color(o, - nk_rect(hue_bar->x, hue_bar->y + (float)i * (hue_bar->h/6.0f) + 0.5f, - hue_bar->w, (hue_bar->h/6.0f) + 0.5f), hue_colors[i], hue_colors[i], - hue_colors[i+1], hue_colors[i+1]); - } - line_y = (float)(int)(hue_bar->y + hsva[0] * matrix->h + 0.5f); - nk_stroke_line(o, hue_bar->x-1, line_y, hue_bar->x + hue_bar->w + 2, - line_y, 1, nk_rgb(255,255,255)); - - /* draw alpha bar */ - if (alpha_bar) { - float alpha = NK_SATURATE((float)color.a/255.0f); - line_y = (float)(int)(alpha_bar->y + (1.0f - alpha) * matrix->h + 0.5f); - - nk_fill_rect_multi_color(o, *alpha_bar, white, white, black, black); - nk_stroke_line(o, alpha_bar->x-1, line_y, alpha_bar->x + alpha_bar->w + 2, - line_y, 1, nk_rgb(255,255,255)); - } - - /* draw color matrix */ - temp = nk_hsv_f(hsva[0], 1.0f, 1.0f); - nk_fill_rect_multi_color(o, *matrix, white, temp, temp, white); - nk_fill_rect_multi_color(o, *matrix, black_trans, black_trans, black, black); - - /* draw cross-hair */ - {struct nk_vec2 p; float S = hsva[1]; float V = hsva[2]; - p.x = (float)(int)(matrix->x + S * matrix->w); - p.y = (float)(int)(matrix->y + (1.0f - V) * matrix->h); - nk_stroke_line(o, p.x - crosshair_size, p.y, p.x-2, p.y, 1.0f, white); - nk_stroke_line(o, p.x + crosshair_size + 1, p.y, p.x+3, p.y, 1.0f, white); - nk_stroke_line(o, p.x, p.y + crosshair_size + 1, p.x, p.y+3, 1.0f, white); - nk_stroke_line(o, p.x, p.y - crosshair_size, p.x, p.y-2, 1.0f, white);} -} - -NK_INTERN int -nk_do_color_picker(nk_flags *state, - struct nk_command_buffer *out, struct nk_color *color, - enum nk_color_format fmt, struct nk_rect bounds, - struct nk_vec2 padding, const struct nk_input *in, - const struct nk_user_font *font) -{ - int ret = 0; - struct nk_rect matrix; - struct nk_rect hue_bar; - struct nk_rect alpha_bar; - float bar_w; - - NK_ASSERT(out); - NK_ASSERT(color); - NK_ASSERT(state); - NK_ASSERT(font); - if (!out || !color || !state || !font) - return ret; - - bar_w = font->height; - bounds.x += padding.x; - bounds.y += padding.x; - bounds.w -= 2 * padding.x; - bounds.h -= 2 * padding.y; - - matrix.x = bounds.x; - matrix.y = bounds.y; - matrix.h = bounds.h; - matrix.w = bounds.w - (3 * padding.x + 2 * bar_w); - - hue_bar.w = bar_w; - hue_bar.y = bounds.y; - hue_bar.h = matrix.h; - hue_bar.x = matrix.x + matrix.w + padding.x; - - alpha_bar.x = hue_bar.x + hue_bar.w + padding.x; - alpha_bar.y = bounds.y; - alpha_bar.w = bar_w; - alpha_bar.h = matrix.h; - - ret = nk_color_picker_behavior(state, &bounds, &matrix, &hue_bar, - (fmt == NK_RGBA) ? &alpha_bar:0, color, in); - nk_draw_color_picker(out, &matrix, &hue_bar, (fmt == NK_RGBA) ? &alpha_bar:0, *color); - return ret; -} - -/* ============================================================== - * - * STYLE - * - * ===============================================================*/ -NK_API void nk_style_default(struct nk_context *ctx){nk_style_from_table(ctx, 0);} -#define NK_COLOR_MAP(NK_COLOR)\ - NK_COLOR(NK_COLOR_TEXT, 175,175,175,255) \ - NK_COLOR(NK_COLOR_WINDOW, 45, 45, 45, 255) \ - NK_COLOR(NK_COLOR_HEADER, 40, 40, 40, 255) \ - NK_COLOR(NK_COLOR_BORDER, 65, 65, 65, 255) \ - NK_COLOR(NK_COLOR_BUTTON, 50, 50, 50, 255) \ - NK_COLOR(NK_COLOR_BUTTON_HOVER, 40, 40, 40, 255) \ - NK_COLOR(NK_COLOR_BUTTON_ACTIVE, 35, 35, 35, 255) \ - NK_COLOR(NK_COLOR_TOGGLE, 100,100,100,255) \ - NK_COLOR(NK_COLOR_TOGGLE_HOVER, 120,120,120,255) \ - NK_COLOR(NK_COLOR_TOGGLE_CURSOR, 45, 45, 45, 255) \ - NK_COLOR(NK_COLOR_SELECT, 45, 45, 45, 255) \ - NK_COLOR(NK_COLOR_SELECT_ACTIVE, 35, 35, 35,255) \ - NK_COLOR(NK_COLOR_SLIDER, 38, 38, 38, 255) \ - NK_COLOR(NK_COLOR_SLIDER_CURSOR, 100,100,100,255) \ - NK_COLOR(NK_COLOR_SLIDER_CURSOR_HOVER, 120,120,120,255) \ - NK_COLOR(NK_COLOR_SLIDER_CURSOR_ACTIVE, 150,150,150,255) \ - NK_COLOR(NK_COLOR_PROPERTY, 38, 38, 38, 255) \ - NK_COLOR(NK_COLOR_EDIT, 38, 38, 38, 255) \ - NK_COLOR(NK_COLOR_EDIT_CURSOR, 175,175,175,255) \ - NK_COLOR(NK_COLOR_COMBO, 45, 45, 45, 255) \ - NK_COLOR(NK_COLOR_CHART, 120,120,120,255) \ - NK_COLOR(NK_COLOR_CHART_COLOR, 45, 45, 45, 255) \ - NK_COLOR(NK_COLOR_CHART_COLOR_HIGHLIGHT,255, 0, 0, 255) \ - NK_COLOR(NK_COLOR_SCROLLBAR, 40, 40, 40, 255) \ - NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR, 100,100,100,255) \ - NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR_HOVER,120,120,120,255) \ - NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR_ACTIVE,150,150,150,255) \ - NK_COLOR(NK_COLOR_TAB_HEADER, 40, 40, 40,255) - -NK_GLOBAL const struct nk_color -nk_default_color_style[NK_COLOR_COUNT] = { -#define NK_COLOR(a,b,c,d,e) {b,c,d,e}, - NK_COLOR_MAP(NK_COLOR) -#undef NK_COLOR -}; - -NK_GLOBAL const char *nk_color_names[NK_COLOR_COUNT] = { -#define NK_COLOR(a,b,c,d,e) #a, - NK_COLOR_MAP(NK_COLOR) -#undef NK_COLOR -}; - -NK_API const char *nk_style_get_color_by_name(enum nk_style_colors c) -{return nk_color_names[c];} - -NK_API struct nk_style_item nk_style_item_image(struct nk_image img) -{struct nk_style_item i; i.type = NK_STYLE_ITEM_IMAGE; i.data.image = img; return i;} - -NK_API struct nk_style_item nk_style_item_color(struct nk_color col) -{struct nk_style_item i; i.type = NK_STYLE_ITEM_COLOR; i.data.color = col; return i;} - -NK_API struct nk_style_item nk_style_item_hide(void) -{struct nk_style_item i; i.type = NK_STYLE_ITEM_COLOR; i.data.color = nk_rgba(0,0,0,0); return i;} - -NK_API void -nk_style_from_table(struct nk_context *ctx, const struct nk_color *table) -{ - struct nk_style *style; - struct nk_style_text *text; - struct nk_style_button *button; - struct nk_style_toggle *toggle; - struct nk_style_selectable *select; - struct nk_style_slider *slider; - struct nk_style_progress *prog; - struct nk_style_scrollbar *scroll; - struct nk_style_edit *edit; - struct nk_style_property *property; - struct nk_style_combo *combo; - struct nk_style_chart *chart; - struct nk_style_tab *tab; - struct nk_style_window *win; - - NK_ASSERT(ctx); - if (!ctx) return; - style = &ctx->style; - table = (!table) ? nk_default_color_style: table; - - /* default text */ - text = &style->text; - text->color = table[NK_COLOR_TEXT]; - text->padding = nk_vec2(0,0); - - /* default button */ - button = &style->button; - nk_zero_struct(*button); - button->normal = nk_style_item_color(table[NK_COLOR_BUTTON]); - button->hover = nk_style_item_color(table[NK_COLOR_BUTTON_HOVER]); - button->active = nk_style_item_color(table[NK_COLOR_BUTTON_ACTIVE]); - button->border_color = table[NK_COLOR_BORDER]; - button->text_background = table[NK_COLOR_BUTTON]; - button->text_normal = table[NK_COLOR_TEXT]; - button->text_hover = table[NK_COLOR_TEXT]; - button->text_active = table[NK_COLOR_TEXT]; - button->padding = nk_vec2(2.0f,2.0f); - button->image_padding = nk_vec2(0.0f,0.0f); - button->touch_padding = nk_vec2(0.0f, 0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 1.0f; - button->rounding = 4.0f; - button->draw_begin = 0; - button->draw_end = 0; - - /* contextual button */ - button = &style->contextual_button; - nk_zero_struct(*button); - button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]); - button->hover = nk_style_item_color(table[NK_COLOR_BUTTON_HOVER]); - button->active = nk_style_item_color(table[NK_COLOR_BUTTON_ACTIVE]); - button->border_color = table[NK_COLOR_WINDOW]; - button->text_background = table[NK_COLOR_WINDOW]; - button->text_normal = table[NK_COLOR_TEXT]; - button->text_hover = table[NK_COLOR_TEXT]; - button->text_active = table[NK_COLOR_TEXT]; - button->padding = nk_vec2(2.0f,2.0f); - button->touch_padding = nk_vec2(0.0f,0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 0.0f; - button->rounding = 0.0f; - button->draw_begin = 0; - button->draw_end = 0; - - /* menu button */ - button = &style->menu_button; - nk_zero_struct(*button); - button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]); - button->hover = nk_style_item_color(table[NK_COLOR_WINDOW]); - button->active = nk_style_item_color(table[NK_COLOR_WINDOW]); - button->border_color = table[NK_COLOR_WINDOW]; - button->text_background = table[NK_COLOR_WINDOW]; - button->text_normal = table[NK_COLOR_TEXT]; - button->text_hover = table[NK_COLOR_TEXT]; - button->text_active = table[NK_COLOR_TEXT]; - button->padding = nk_vec2(2.0f,2.0f); - button->touch_padding = nk_vec2(0.0f,0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 0.0f; - button->rounding = 1.0f; - button->draw_begin = 0; - button->draw_end = 0; - - /* checkbox toggle */ - toggle = &style->checkbox; - nk_zero_struct(*toggle); - toggle->normal = nk_style_item_color(table[NK_COLOR_TOGGLE]); - toggle->hover = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]); - toggle->active = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]); - toggle->cursor_normal = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]); - toggle->cursor_hover = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]); - toggle->userdata = nk_handle_ptr(0); - toggle->text_background = table[NK_COLOR_WINDOW]; - toggle->text_normal = table[NK_COLOR_TEXT]; - toggle->text_hover = table[NK_COLOR_TEXT]; - toggle->text_active = table[NK_COLOR_TEXT]; - toggle->padding = nk_vec2(2.0f, 2.0f); - toggle->touch_padding = nk_vec2(0,0); - toggle->border_color = nk_rgba(0,0,0,0); - toggle->border = 0.0f; - toggle->spacing = 4; - - /* option toggle */ - toggle = &style->option; - nk_zero_struct(*toggle); - toggle->normal = nk_style_item_color(table[NK_COLOR_TOGGLE]); - toggle->hover = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]); - toggle->active = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]); - toggle->cursor_normal = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]); - toggle->cursor_hover = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]); - toggle->userdata = nk_handle_ptr(0); - toggle->text_background = table[NK_COLOR_WINDOW]; - toggle->text_normal = table[NK_COLOR_TEXT]; - toggle->text_hover = table[NK_COLOR_TEXT]; - toggle->text_active = table[NK_COLOR_TEXT]; - toggle->padding = nk_vec2(3.0f, 3.0f); - toggle->touch_padding = nk_vec2(0,0); - toggle->border_color = nk_rgba(0,0,0,0); - toggle->border = 0.0f; - toggle->spacing = 4; - - /* selectable */ - select = &style->selectable; - nk_zero_struct(*select); - select->normal = nk_style_item_color(table[NK_COLOR_SELECT]); - select->hover = nk_style_item_color(table[NK_COLOR_SELECT]); - select->pressed = nk_style_item_color(table[NK_COLOR_SELECT]); - select->normal_active = nk_style_item_color(table[NK_COLOR_SELECT_ACTIVE]); - select->hover_active = nk_style_item_color(table[NK_COLOR_SELECT_ACTIVE]); - select->pressed_active = nk_style_item_color(table[NK_COLOR_SELECT_ACTIVE]); - select->text_normal = table[NK_COLOR_TEXT]; - select->text_hover = table[NK_COLOR_TEXT]; - select->text_pressed = table[NK_COLOR_TEXT]; - select->text_normal_active = table[NK_COLOR_TEXT]; - select->text_hover_active = table[NK_COLOR_TEXT]; - select->text_pressed_active = table[NK_COLOR_TEXT]; - select->padding = nk_vec2(2.0f,2.0f); - select->touch_padding = nk_vec2(0,0); - select->userdata = nk_handle_ptr(0); - select->rounding = 0.0f; - select->draw_begin = 0; - select->draw_end = 0; - - /* slider */ - slider = &style->slider; - nk_zero_struct(*slider); - slider->normal = nk_style_item_hide(); - slider->hover = nk_style_item_hide(); - slider->active = nk_style_item_hide(); - slider->bar_normal = table[NK_COLOR_SLIDER]; - slider->bar_hover = table[NK_COLOR_SLIDER]; - slider->bar_active = table[NK_COLOR_SLIDER]; - slider->bar_filled = table[NK_COLOR_SLIDER_CURSOR]; - slider->cursor_normal = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR]); - slider->cursor_hover = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_HOVER]); - slider->cursor_active = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_ACTIVE]); - slider->inc_symbol = NK_SYMBOL_TRIANGLE_RIGHT; - slider->dec_symbol = NK_SYMBOL_TRIANGLE_LEFT; - slider->cursor_size = nk_vec2(16,16); - slider->padding = nk_vec2(2,2); - slider->spacing = nk_vec2(2,2); - slider->userdata = nk_handle_ptr(0); - slider->show_buttons = nk_false; - slider->bar_height = 8; - slider->rounding = 0; - slider->draw_begin = 0; - slider->draw_end = 0; - - /* slider buttons */ - button = &style->slider.inc_button; - button->normal = nk_style_item_color(nk_rgb(40,40,40)); - button->hover = nk_style_item_color(nk_rgb(42,42,42)); - button->active = nk_style_item_color(nk_rgb(44,44,44)); - button->border_color = nk_rgb(65,65,65); - button->text_background = nk_rgb(40,40,40); - button->text_normal = nk_rgb(175,175,175); - button->text_hover = nk_rgb(175,175,175); - button->text_active = nk_rgb(175,175,175); - button->padding = nk_vec2(8.0f,8.0f); - button->touch_padding = nk_vec2(0.0f,0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 1.0f; - button->rounding = 0.0f; - button->draw_begin = 0; - button->draw_end = 0; - style->slider.dec_button = style->slider.inc_button; - - /* progressbar */ - prog = &style->progress; - nk_zero_struct(*prog); - prog->normal = nk_style_item_color(table[NK_COLOR_SLIDER]); - prog->hover = nk_style_item_color(table[NK_COLOR_SLIDER]); - prog->active = nk_style_item_color(table[NK_COLOR_SLIDER]); - prog->cursor_normal = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR]); - prog->cursor_hover = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_HOVER]); - prog->cursor_active = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_ACTIVE]); - prog->border_color = nk_rgba(0,0,0,0); - prog->cursor_border_color = nk_rgba(0,0,0,0); - prog->userdata = nk_handle_ptr(0); - prog->padding = nk_vec2(4,4); - prog->rounding = 0; - prog->border = 0; - prog->cursor_rounding = 0; - prog->cursor_border = 0; - prog->draw_begin = 0; - prog->draw_end = 0; - - /* scrollbars */ - scroll = &style->scrollh; - nk_zero_struct(*scroll); - scroll->normal = nk_style_item_color(table[NK_COLOR_SCROLLBAR]); - scroll->hover = nk_style_item_color(table[NK_COLOR_SCROLLBAR]); - scroll->active = nk_style_item_color(table[NK_COLOR_SCROLLBAR]); - scroll->cursor_normal = nk_style_item_color(table[NK_COLOR_SCROLLBAR_CURSOR]); - scroll->cursor_hover = nk_style_item_color(table[NK_COLOR_SCROLLBAR_CURSOR_HOVER]); - scroll->cursor_active = nk_style_item_color(table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE]); - scroll->dec_symbol = NK_SYMBOL_CIRCLE_SOLID; - scroll->inc_symbol = NK_SYMBOL_CIRCLE_SOLID; - scroll->userdata = nk_handle_ptr(0); - scroll->border_color = table[NK_COLOR_SCROLLBAR]; - scroll->cursor_border_color = table[NK_COLOR_SCROLLBAR]; - scroll->padding = nk_vec2(0,0); - scroll->show_buttons = nk_false; - scroll->border = 0; - scroll->rounding = 0; - scroll->border_cursor = 0; - scroll->rounding_cursor = 0; - scroll->draw_begin = 0; - scroll->draw_end = 0; - style->scrollv = style->scrollh; - - /* scrollbars buttons */ - button = &style->scrollh.inc_button; - button->normal = nk_style_item_color(nk_rgb(40,40,40)); - button->hover = nk_style_item_color(nk_rgb(42,42,42)); - button->active = nk_style_item_color(nk_rgb(44,44,44)); - button->border_color = nk_rgb(65,65,65); - button->text_background = nk_rgb(40,40,40); - button->text_normal = nk_rgb(175,175,175); - button->text_hover = nk_rgb(175,175,175); - button->text_active = nk_rgb(175,175,175); - button->padding = nk_vec2(4.0f,4.0f); - button->touch_padding = nk_vec2(0.0f,0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 1.0f; - button->rounding = 0.0f; - button->draw_begin = 0; - button->draw_end = 0; - style->scrollh.dec_button = style->scrollh.inc_button; - style->scrollv.inc_button = style->scrollh.inc_button; - style->scrollv.dec_button = style->scrollh.inc_button; - - /* edit */ - edit = &style->edit; - nk_zero_struct(*edit); - edit->normal = nk_style_item_color(table[NK_COLOR_EDIT]); - edit->hover = nk_style_item_color(table[NK_COLOR_EDIT]); - edit->active = nk_style_item_color(table[NK_COLOR_EDIT]); - edit->cursor_normal = table[NK_COLOR_TEXT]; - edit->cursor_hover = table[NK_COLOR_TEXT]; - edit->cursor_text_normal= table[NK_COLOR_EDIT]; - edit->cursor_text_hover = table[NK_COLOR_EDIT]; - edit->border_color = table[NK_COLOR_BORDER]; - edit->text_normal = table[NK_COLOR_TEXT]; - edit->text_hover = table[NK_COLOR_TEXT]; - edit->text_active = table[NK_COLOR_TEXT]; - edit->selected_normal = table[NK_COLOR_TEXT]; - edit->selected_hover = table[NK_COLOR_TEXT]; - edit->selected_text_normal = table[NK_COLOR_EDIT]; - edit->selected_text_hover = table[NK_COLOR_EDIT]; - edit->scrollbar_size = nk_vec2(10,10); - edit->scrollbar = style->scrollv; - edit->padding = nk_vec2(4,4); - edit->row_padding = 2; - edit->cursor_size = 4; - edit->border = 1; - edit->rounding = 0; - - /* property */ - property = &style->property; - nk_zero_struct(*property); - property->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]); - property->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]); - property->active = nk_style_item_color(table[NK_COLOR_PROPERTY]); - property->border_color = table[NK_COLOR_BORDER]; - property->label_normal = table[NK_COLOR_TEXT]; - property->label_hover = table[NK_COLOR_TEXT]; - property->label_active = table[NK_COLOR_TEXT]; - property->sym_left = NK_SYMBOL_TRIANGLE_LEFT; - property->sym_right = NK_SYMBOL_TRIANGLE_RIGHT; - property->userdata = nk_handle_ptr(0); - property->padding = nk_vec2(4,4); - property->border = 1; - property->rounding = 10; - property->draw_begin = 0; - property->draw_end = 0; - - /* property buttons */ - button = &style->property.dec_button; - nk_zero_struct(*button); - button->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]); - button->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]); - button->active = nk_style_item_color(table[NK_COLOR_PROPERTY]); - button->border_color = nk_rgba(0,0,0,0); - button->text_background = table[NK_COLOR_PROPERTY]; - button->text_normal = table[NK_COLOR_TEXT]; - button->text_hover = table[NK_COLOR_TEXT]; - button->text_active = table[NK_COLOR_TEXT]; - button->padding = nk_vec2(0.0f,0.0f); - button->touch_padding = nk_vec2(0.0f,0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 0.0f; - button->rounding = 0.0f; - button->draw_begin = 0; - button->draw_end = 0; - style->property.inc_button = style->property.dec_button; - - /* property edit */ - edit = &style->property.edit; - nk_zero_struct(*edit); - edit->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]); - edit->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]); - edit->active = nk_style_item_color(table[NK_COLOR_PROPERTY]); - edit->border_color = nk_rgba(0,0,0,0); - edit->cursor_normal = table[NK_COLOR_TEXT]; - edit->cursor_hover = table[NK_COLOR_TEXT]; - edit->cursor_text_normal= table[NK_COLOR_EDIT]; - edit->cursor_text_hover = table[NK_COLOR_EDIT]; - edit->text_normal = table[NK_COLOR_TEXT]; - edit->text_hover = table[NK_COLOR_TEXT]; - edit->text_active = table[NK_COLOR_TEXT]; - edit->selected_normal = table[NK_COLOR_TEXT]; - edit->selected_hover = table[NK_COLOR_TEXT]; - edit->selected_text_normal = table[NK_COLOR_EDIT]; - edit->selected_text_hover = table[NK_COLOR_EDIT]; - edit->padding = nk_vec2(0,0); - edit->cursor_size = 8; - edit->border = 0; - edit->rounding = 0; - - /* chart */ - chart = &style->chart; - nk_zero_struct(*chart); - chart->background = nk_style_item_color(table[NK_COLOR_CHART]); - chart->border_color = table[NK_COLOR_BORDER]; - chart->selected_color = table[NK_COLOR_CHART_COLOR_HIGHLIGHT]; - chart->color = table[NK_COLOR_CHART_COLOR]; - chart->padding = nk_vec2(4,4); - chart->border = 0; - chart->rounding = 0; - - /* combo */ - combo = &style->combo; - combo->normal = nk_style_item_color(table[NK_COLOR_COMBO]); - combo->hover = nk_style_item_color(table[NK_COLOR_COMBO]); - combo->active = nk_style_item_color(table[NK_COLOR_COMBO]); - combo->border_color = table[NK_COLOR_BORDER]; - combo->label_normal = table[NK_COLOR_TEXT]; - combo->label_hover = table[NK_COLOR_TEXT]; - combo->label_active = table[NK_COLOR_TEXT]; - combo->sym_normal = NK_SYMBOL_TRIANGLE_DOWN; - combo->sym_hover = NK_SYMBOL_TRIANGLE_DOWN; - combo->sym_active = NK_SYMBOL_TRIANGLE_DOWN; - combo->content_padding = nk_vec2(4,4); - combo->button_padding = nk_vec2(0,4); - combo->spacing = nk_vec2(4,0); - combo->border = 1; - combo->rounding = 0; - - /* combo button */ - button = &style->combo.button; - nk_zero_struct(*button); - button->normal = nk_style_item_color(table[NK_COLOR_COMBO]); - button->hover = nk_style_item_color(table[NK_COLOR_COMBO]); - button->active = nk_style_item_color(table[NK_COLOR_COMBO]); - button->border_color = nk_rgba(0,0,0,0); - button->text_background = table[NK_COLOR_COMBO]; - button->text_normal = table[NK_COLOR_TEXT]; - button->text_hover = table[NK_COLOR_TEXT]; - button->text_active = table[NK_COLOR_TEXT]; - button->padding = nk_vec2(2.0f,2.0f); - button->touch_padding = nk_vec2(0.0f,0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 0.0f; - button->rounding = 0.0f; - button->draw_begin = 0; - button->draw_end = 0; - - /* tab */ - tab = &style->tab; - tab->background = nk_style_item_color(table[NK_COLOR_TAB_HEADER]); - tab->border_color = table[NK_COLOR_BORDER]; - tab->text = table[NK_COLOR_TEXT]; - tab->sym_minimize = NK_SYMBOL_TRIANGLE_RIGHT; - tab->sym_maximize = NK_SYMBOL_TRIANGLE_DOWN; - tab->padding = nk_vec2(4,4); - tab->spacing = nk_vec2(4,4); - tab->indent = 10.0f; - tab->border = 1; - tab->rounding = 0; - - /* tab button */ - button = &style->tab.tab_minimize_button; - nk_zero_struct(*button); - button->normal = nk_style_item_color(table[NK_COLOR_TAB_HEADER]); - button->hover = nk_style_item_color(table[NK_COLOR_TAB_HEADER]); - button->active = nk_style_item_color(table[NK_COLOR_TAB_HEADER]); - button->border_color = nk_rgba(0,0,0,0); - button->text_background = table[NK_COLOR_TAB_HEADER]; - button->text_normal = table[NK_COLOR_TEXT]; - button->text_hover = table[NK_COLOR_TEXT]; - button->text_active = table[NK_COLOR_TEXT]; - button->padding = nk_vec2(2.0f,2.0f); - button->touch_padding = nk_vec2(0.0f,0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 0.0f; - button->rounding = 0.0f; - button->draw_begin = 0; - button->draw_end = 0; - style->tab.tab_maximize_button =*button; - - /* node button */ - button = &style->tab.node_minimize_button; - nk_zero_struct(*button); - button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]); - button->hover = nk_style_item_color(table[NK_COLOR_WINDOW]); - button->active = nk_style_item_color(table[NK_COLOR_WINDOW]); - button->border_color = nk_rgba(0,0,0,0); - button->text_background = table[NK_COLOR_TAB_HEADER]; - button->text_normal = table[NK_COLOR_TEXT]; - button->text_hover = table[NK_COLOR_TEXT]; - button->text_active = table[NK_COLOR_TEXT]; - button->padding = nk_vec2(2.0f,2.0f); - button->touch_padding = nk_vec2(0.0f,0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 0.0f; - button->rounding = 0.0f; - button->draw_begin = 0; - button->draw_end = 0; - style->tab.node_maximize_button =*button; - - /* window header */ - win = &style->window; - win->header.align = NK_HEADER_RIGHT; - win->header.close_symbol = NK_SYMBOL_X; - win->header.minimize_symbol = NK_SYMBOL_MINUS; - win->header.maximize_symbol = NK_SYMBOL_PLUS; - win->header.normal = nk_style_item_color(table[NK_COLOR_HEADER]); - win->header.hover = nk_style_item_color(table[NK_COLOR_HEADER]); - win->header.active = nk_style_item_color(table[NK_COLOR_HEADER]); - win->header.label_normal = table[NK_COLOR_TEXT]; - win->header.label_hover = table[NK_COLOR_TEXT]; - win->header.label_active = table[NK_COLOR_TEXT]; - win->header.label_padding = nk_vec2(4,4); - win->header.padding = nk_vec2(4,4); - win->header.spacing = nk_vec2(0,0); - - /* window header close button */ - button = &style->window.header.close_button; - nk_zero_struct(*button); - button->normal = nk_style_item_color(table[NK_COLOR_HEADER]); - button->hover = nk_style_item_color(table[NK_COLOR_HEADER]); - button->active = nk_style_item_color(table[NK_COLOR_HEADER]); - button->border_color = nk_rgba(0,0,0,0); - button->text_background = table[NK_COLOR_HEADER]; - button->text_normal = table[NK_COLOR_TEXT]; - button->text_hover = table[NK_COLOR_TEXT]; - button->text_active = table[NK_COLOR_TEXT]; - button->padding = nk_vec2(0.0f,0.0f); - button->touch_padding = nk_vec2(0.0f,0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 0.0f; - button->rounding = 0.0f; - button->draw_begin = 0; - button->draw_end = 0; - - /* window header minimize button */ - button = &style->window.header.minimize_button; - nk_zero_struct(*button); - button->normal = nk_style_item_color(table[NK_COLOR_HEADER]); - button->hover = nk_style_item_color(table[NK_COLOR_HEADER]); - button->active = nk_style_item_color(table[NK_COLOR_HEADER]); - button->border_color = nk_rgba(0,0,0,0); - button->text_background = table[NK_COLOR_HEADER]; - button->text_normal = table[NK_COLOR_TEXT]; - button->text_hover = table[NK_COLOR_TEXT]; - button->text_active = table[NK_COLOR_TEXT]; - button->padding = nk_vec2(0.0f,0.0f); - button->touch_padding = nk_vec2(0.0f,0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 0.0f; - button->rounding = 0.0f; - button->draw_begin = 0; - button->draw_end = 0; - - /* window */ - win->background = table[NK_COLOR_WINDOW]; - win->fixed_background = nk_style_item_color(table[NK_COLOR_WINDOW]); - win->border_color = table[NK_COLOR_BORDER]; - win->popup_border_color = table[NK_COLOR_BORDER]; - win->combo_border_color = table[NK_COLOR_BORDER]; - win->contextual_border_color = table[NK_COLOR_BORDER]; - win->menu_border_color = table[NK_COLOR_BORDER]; - win->group_border_color = table[NK_COLOR_BORDER]; - win->tooltip_border_color = table[NK_COLOR_BORDER]; - win->scaler = nk_style_item_color(table[NK_COLOR_TEXT]); - - win->rounding = 0.0f; - win->spacing = nk_vec2(4,4); - win->scrollbar_size = nk_vec2(10,10); - win->min_size = nk_vec2(64,64); - - win->combo_border = 1.0f; - win->contextual_border = 1.0f; - win->menu_border = 1.0f; - win->group_border = 1.0f; - win->tooltip_border = 1.0f; - win->popup_border = 1.0f; - win->border = 2.0f; - - win->padding = nk_vec2(4,4); - win->group_padding = nk_vec2(4,4); - win->popup_padding = nk_vec2(4,4); - win->combo_padding = nk_vec2(4,4); - win->contextual_padding = nk_vec2(4,4); - win->menu_padding = nk_vec2(4,4); - win->tooltip_padding = nk_vec2(4,4); -} - -NK_API void -nk_style_set_font(struct nk_context *ctx, const struct nk_user_font *font) -{ - struct nk_style *style; - NK_ASSERT(ctx); - if (!ctx) return; - style = &ctx->style; - style->font = font; - ctx->stacks.fonts.head = 0; -} - -NK_API int -nk_style_push_font(struct nk_context *ctx, struct nk_user_font *font) -{ - struct nk_config_stack_user_font *font_stack; - struct nk_config_stack_user_font_element *element; - - NK_ASSERT(ctx); - if (!ctx) return 0; - - font_stack = &ctx->stacks.fonts; - NK_ASSERT(font_stack->head < (int)NK_LEN(font_stack->elements)); - if (font_stack->head >= (int)NK_LEN(font_stack->elements)) - return 0; - - element = &font_stack->elements[font_stack->head++]; - element->address = &ctx->style.font; - element->old_value = ctx->style.font; - ctx->style.font = font; - return 1; -} - -NK_API int -nk_style_pop_font(struct nk_context *ctx) -{ - struct nk_config_stack_user_font *font_stack; - struct nk_config_stack_user_font_element *element; - - NK_ASSERT(ctx); - if (!ctx) return 0; - - font_stack = &ctx->stacks.fonts; - NK_ASSERT(font_stack->head > 0); - if (font_stack->head < 1) - return 0; - - element = &font_stack->elements[--font_stack->head]; - *element->address = element->old_value; - return 1; -} - -#define NK_STYLE_PUSH_IMPLEMENATION(prefix, type, stack) \ -nk_style_push_##type(struct nk_context *ctx, prefix##_##type *address, prefix##_##type value)\ -{\ - struct nk_config_stack_##type * type_stack;\ - struct nk_config_stack_##type##_element *element;\ - NK_ASSERT(ctx);\ - if (!ctx) return 0;\ - type_stack = &ctx->stacks.stack;\ - NK_ASSERT(type_stack->head < (int)NK_LEN(type_stack->elements));\ - if (type_stack->head >= (int)NK_LEN(type_stack->elements))\ - return 0;\ - element = &type_stack->elements[type_stack->head++];\ - element->address = address;\ - element->old_value = *address;\ - *address = value;\ - return 1;\ -} - -#define NK_STYLE_POP_IMPLEMENATION(type, stack) \ -nk_style_pop_##type(struct nk_context *ctx)\ -{\ - struct nk_config_stack_##type *type_stack;\ - struct nk_config_stack_##type##_element *element;\ - NK_ASSERT(ctx);\ - if (!ctx) return 0;\ - type_stack = &ctx->stacks.stack;\ - NK_ASSERT(type_stack->head > 0);\ - if (type_stack->head < 1)\ - return 0;\ - element = &type_stack->elements[--type_stack->head];\ - *element->address = element->old_value;\ - return 1;\ -} - -NK_API int NK_STYLE_PUSH_IMPLEMENATION(struct nk, style_item, style_items) -NK_API int NK_STYLE_PUSH_IMPLEMENATION(nk,float, floats) -NK_API int NK_STYLE_PUSH_IMPLEMENATION(struct nk, vec2, vectors) -NK_API int NK_STYLE_PUSH_IMPLEMENATION(nk,flags, flags) -NK_API int NK_STYLE_PUSH_IMPLEMENATION(struct nk,color, colors) - -NK_API int NK_STYLE_POP_IMPLEMENATION(style_item, style_items) -NK_API int NK_STYLE_POP_IMPLEMENATION(float,floats) -NK_API int NK_STYLE_POP_IMPLEMENATION(vec2, vectors) -NK_API int NK_STYLE_POP_IMPLEMENATION(flags,flags) -NK_API int NK_STYLE_POP_IMPLEMENATION(color,colors) - -NK_API int -nk_style_set_cursor(struct nk_context *ctx, enum nk_style_cursor c) -{ - struct nk_style *style; - NK_ASSERT(ctx); - if (!ctx) return 0; - style = &ctx->style; - if (style->cursors[c]) { - style->cursor_active = style->cursors[c]; - return 1; - } - return 0; -} - -NK_API void -nk_style_show_cursor(struct nk_context *ctx) -{ - ctx->style.cursor_visible = nk_true; -} - -NK_API void -nk_style_hide_cursor(struct nk_context *ctx) -{ - ctx->style.cursor_visible = nk_false; -} - -NK_API void -nk_style_load_cursor(struct nk_context *ctx, enum nk_style_cursor cursor, - const struct nk_cursor *c) -{ - struct nk_style *style; - NK_ASSERT(ctx); - if (!ctx) return; - style = &ctx->style; - style->cursors[cursor] = c; -} - -NK_API void -nk_style_load_all_cursors(struct nk_context *ctx, struct nk_cursor *cursors) -{ - int i = 0; - struct nk_style *style; - NK_ASSERT(ctx); - if (!ctx) return; - style = &ctx->style; - for (i = 0; i < NK_CURSOR_COUNT; ++i) - style->cursors[i] = &cursors[i]; - style->cursor_visible = nk_true; -} - -/* =============================================================== - * - * POOL - * - * ===============================================================*/ -NK_INTERN void -nk_pool_init(struct nk_pool *pool, struct nk_allocator *alloc, - unsigned int capacity) -{ - nk_zero(pool, sizeof(*pool)); - pool->alloc = *alloc; - pool->capacity = capacity; - pool->type = NK_BUFFER_DYNAMIC; - pool->pages = 0; -} - -NK_INTERN void -nk_pool_free(struct nk_pool *pool) -{ - struct nk_page *next; - struct nk_page *iter = pool->pages; - if (!pool) return; - if (pool->type == NK_BUFFER_FIXED) return; - while (iter) { - next = iter->next; - pool->alloc.free(pool->alloc.userdata, iter); - iter = next; - } -} - -NK_INTERN void -nk_pool_init_fixed(struct nk_pool *pool, void *memory, nk_size size) -{ - nk_zero(pool, sizeof(*pool)); - NK_ASSERT(size >= sizeof(struct nk_page)); - if (size < sizeof(struct nk_page)) return; - pool->capacity = (unsigned)(size - sizeof(struct nk_page)) / sizeof(struct nk_page_element); - pool->pages = (struct nk_page*)memory; - pool->type = NK_BUFFER_FIXED; - pool->size = size; -} - -NK_INTERN struct nk_page_element* -nk_pool_alloc(struct nk_pool *pool) -{ - if (!pool->pages || pool->pages->size >= pool->capacity) { - /* allocate new page */ - struct nk_page *page; - if (pool->type == NK_BUFFER_FIXED) { - if (!pool->pages) { - NK_ASSERT(pool->pages); - return 0; - } - NK_ASSERT(pool->pages->size < pool->capacity); - return 0; - } else { - nk_size size = sizeof(struct nk_page); - size += NK_POOL_DEFAULT_CAPACITY * sizeof(union nk_page_data); - page = (struct nk_page*)pool->alloc.alloc(pool->alloc.userdata,0, size); - page->next = pool->pages; - pool->pages = page; - page->size = 0; - } - } - return &pool->pages->win[pool->pages->size++]; -} - -/* =============================================================== - * - * CONTEXT - * - * ===============================================================*/ -NK_INTERN void* nk_create_window(struct nk_context *ctx); -NK_INTERN void nk_remove_window(struct nk_context*, struct nk_window*); -NK_INTERN void nk_free_window(struct nk_context *ctx, struct nk_window *win); -NK_INTERN void nk_free_table(struct nk_context *ctx, struct nk_table *tbl); -NK_INTERN void nk_remove_table(struct nk_window *win, struct nk_table *tbl); -NK_INTERN void* nk_create_panel(struct nk_context *ctx); -NK_INTERN void nk_free_panel(struct nk_context*, struct nk_panel *pan); - -NK_INTERN void -nk_setup(struct nk_context *ctx, const struct nk_user_font *font) -{ - NK_ASSERT(ctx); - if (!ctx) return; - nk_zero_struct(*ctx); - nk_style_default(ctx); - ctx->seq = 1; - if (font) ctx->style.font = font; -#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT - nk_draw_list_init(&ctx->draw_list); -#endif -} - -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_API int -nk_init_default(struct nk_context *ctx, const struct nk_user_font *font) -{ - struct nk_allocator alloc; - alloc.userdata.ptr = 0; - alloc.alloc = nk_malloc; - alloc.free = nk_mfree; - return nk_init(ctx, &alloc, font); -} -#endif - -NK_API int -nk_init_fixed(struct nk_context *ctx, void *memory, nk_size size, - const struct nk_user_font *font) -{ - NK_ASSERT(memory); - if (!memory) return 0; - nk_setup(ctx, font); - nk_buffer_init_fixed(&ctx->memory, memory, size); - ctx->use_pool = nk_false; - return 1; -} - -NK_API int -nk_init_custom(struct nk_context *ctx, struct nk_buffer *cmds, - struct nk_buffer *pool, const struct nk_user_font *font) -{ - NK_ASSERT(cmds); - NK_ASSERT(pool); - if (!cmds || !pool) return 0; - - nk_setup(ctx, font); - ctx->memory = *cmds; - if (pool->type == NK_BUFFER_FIXED) { - /* take memory from buffer and alloc fixed pool */ - nk_pool_init_fixed(&ctx->pool, pool->memory.ptr, pool->memory.size); - } else { - /* create dynamic pool from buffer allocator */ - struct nk_allocator *alloc = &pool->pool; - nk_pool_init(&ctx->pool, alloc, NK_POOL_DEFAULT_CAPACITY); - } - ctx->use_pool = nk_true; - return 1; -} - -NK_API int -nk_init(struct nk_context *ctx, struct nk_allocator *alloc, - const struct nk_user_font *font) -{ - NK_ASSERT(alloc); - if (!alloc) return 0; - nk_setup(ctx, font); - nk_buffer_init(&ctx->memory, alloc, NK_DEFAULT_COMMAND_BUFFER_SIZE); - nk_pool_init(&ctx->pool, alloc, NK_POOL_DEFAULT_CAPACITY); - ctx->use_pool = nk_true; - return 1; -} - -#ifdef NK_INCLUDE_COMMAND_USERDATA -NK_API void -nk_set_user_data(struct nk_context *ctx, nk_handle handle) -{ - if (!ctx) return; - ctx->userdata = handle; - if (ctx->current) - ctx->current->buffer.userdata = handle; -} -#endif - -NK_API void -nk_free(struct nk_context *ctx) -{ - NK_ASSERT(ctx); - if (!ctx) return; - nk_buffer_free(&ctx->memory); - if (ctx->use_pool) - nk_pool_free(&ctx->pool); - - nk_zero(&ctx->input, sizeof(ctx->input)); - nk_zero(&ctx->style, sizeof(ctx->style)); - nk_zero(&ctx->memory, sizeof(ctx->memory)); - - ctx->seq = 0; - ctx->build = 0; - ctx->begin = 0; - ctx->end = 0; - ctx->active = 0; - ctx->current = 0; - ctx->freelist = 0; - ctx->count = 0; -} - -NK_API void -nk_clear(struct nk_context *ctx) -{ - struct nk_window *iter; - struct nk_window *next; - NK_ASSERT(ctx); - - if (!ctx) return; - if (ctx->use_pool) - nk_buffer_clear(&ctx->memory); - else nk_buffer_reset(&ctx->memory, NK_BUFFER_FRONT); - - ctx->build = 0; - ctx->memory.calls = 0; - ctx->last_widget_state = 0; - ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_ARROW]; - NK_MEMSET(&ctx->overlay, 0, sizeof(ctx->overlay)); -#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT - nk_draw_list_clear(&ctx->draw_list); -#endif - - /* garbage collector */ - iter = ctx->begin; - while (iter) { - /* make sure minimized windows do not get removed */ - if ((iter->flags & NK_WINDOW_MINIMIZED) && - !(iter->flags & NK_WINDOW_CLOSED)) { - iter = iter->next; - continue; - } - - /* free unused popup windows */ - if (iter->popup.win && iter->popup.win->seq != ctx->seq) { - nk_free_window(ctx, iter->popup.win); - iter->popup.win = 0; - } - - /* remove unused window state tables */ - {struct nk_table *n, *it = iter->tables; - while (it) { - n = it->next; - if (it->seq != ctx->seq) { - nk_remove_table(iter, it); - nk_zero(it, sizeof(union nk_page_data)); - nk_free_table(ctx, it); - if (it == iter->tables) - iter->tables = n; - } - it = n; - }} - - /* window itself is not used anymore so free */ - if (iter->seq != ctx->seq || iter->flags & NK_WINDOW_CLOSED) { - next = iter->next; - nk_remove_window(ctx, iter); - nk_free_window(ctx, iter); - iter = next; - } else iter = iter->next; - } - ctx->seq++; -} - -/* ---------------------------------------------------------------- - * - * BUFFERING - * - * ---------------------------------------------------------------*/ -NK_INTERN void -nk_start_buffer(struct nk_context *ctx, struct nk_command_buffer *buffer) -{ - NK_ASSERT(ctx); - NK_ASSERT(buffer); - if (!ctx || !buffer) return; - buffer->begin = ctx->memory.allocated; - buffer->end = buffer->begin; - buffer->last = buffer->begin; - buffer->clip = nk_null_rect; -} - -NK_INTERN void -nk_start(struct nk_context *ctx, struct nk_window *win) -{ - NK_ASSERT(ctx); - NK_ASSERT(win); - nk_start_buffer(ctx, &win->buffer); -} - -NK_INTERN void -nk_start_popup(struct nk_context *ctx, struct nk_window *win) -{ - struct nk_popup_buffer *buf; - struct nk_panel *iter; - NK_ASSERT(ctx); - NK_ASSERT(win); - if (!ctx || !win) return; - - /* make sure to use the correct popup buffer*/ - iter = win->layout; - while (iter->parent) - iter = iter->parent; - - /* save buffer fill state for popup */ - buf = &iter->popup_buffer; - buf->begin = win->buffer.end; - buf->end = win->buffer.end; - buf->parent = win->buffer.last; - buf->last = buf->begin; - buf->active = nk_true; -} - -NK_INTERN void -nk_finish_popup(struct nk_context *ctx, struct nk_window *win) -{ - struct nk_popup_buffer *buf; - struct nk_panel *iter; - NK_ASSERT(ctx); - NK_ASSERT(win); - if (!ctx || !win) return; - - /* make sure to use the correct popup buffer*/ - iter = win->layout; - while (iter->parent) - iter = iter->parent; - - buf = &iter->popup_buffer; - buf->last = win->buffer.last; - buf->end = win->buffer.end; -} - -NK_INTERN void -nk_finish_buffer(struct nk_context *ctx, struct nk_command_buffer *buffer) -{ - NK_ASSERT(ctx); - NK_ASSERT(buffer); - if (!ctx || !buffer) return; - buffer->end = ctx->memory.allocated; -} - -NK_INTERN void -nk_finish(struct nk_context *ctx, struct nk_window *win) -{ - struct nk_popup_buffer *buf; - struct nk_command *parent_last; - struct nk_command *sublast; - struct nk_command *last; - void *memory; - - NK_ASSERT(ctx); - NK_ASSERT(win); - if (!ctx || !win) return; - nk_finish_buffer(ctx, &win->buffer); - if (!win->layout->popup_buffer.active) return; - - /* from here on is for popup window buffer handling */ - /*--------------------------------------------------*/ - buf = &win->layout->popup_buffer; - memory = ctx->memory.memory.ptr; - - /* redirect the sub-window buffer to the end of the window command buffer */ - parent_last = nk_ptr_add(struct nk_command, memory, buf->parent); - sublast = nk_ptr_add(struct nk_command, memory, buf->last); - last = nk_ptr_add(struct nk_command, memory, win->buffer.last); - - parent_last->next = buf->end; - sublast->next = last->next; - last->next = buf->begin; - win->buffer.last = buf->last; - win->buffer.end = buf->end; - buf->active = nk_false; -} - -NK_INTERN void -nk_build(struct nk_context *ctx) -{ - struct nk_window *iter; - struct nk_window *next; - struct nk_command *cmd; - nk_byte *buffer; - - /* draw cursor overlay */ - if (!ctx->style.cursor_active) - ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_ARROW]; - if (ctx->style.cursor_active && !ctx->input.mouse.grabbed && ctx->style.cursor_visible) { - struct nk_rect mouse_bounds; - const struct nk_cursor *cursor = ctx->style.cursor_active; - nk_command_buffer_init(&ctx->overlay, &ctx->memory, NK_CLIPPING_OFF); - nk_start_buffer(ctx, &ctx->overlay); - - mouse_bounds.x = ctx->input.mouse.pos.x - cursor->offset.x; - mouse_bounds.y = ctx->input.mouse.pos.y - cursor->offset.y; - mouse_bounds.w = cursor->size.x; - mouse_bounds.h = cursor->size.y; - - nk_draw_image(&ctx->overlay, mouse_bounds, &cursor->img, nk_white); - nk_finish_buffer(ctx, &ctx->overlay); - } - - /* build one big draw command list out of all buffers */ - iter = ctx->begin; - buffer = (nk_byte*)ctx->memory.memory.ptr; - while (iter != 0) { - next = iter->next; - if (iter->buffer.last == iter->buffer.begin || (iter->flags & NK_WINDOW_HIDDEN)) { - iter = next; - continue; - } - cmd = nk_ptr_add(struct nk_command, buffer, iter->buffer.last); - while (next && ((next->buffer.last == next->buffer.begin) || - (next->flags & NK_WINDOW_HIDDEN))) - next = next->next; /* skip empty command buffers */ - - if (next) { - cmd->next = next->buffer.begin; - } else { - if (ctx->overlay.end != ctx->overlay.begin) - cmd->next = ctx->overlay.begin; - else cmd->next = ctx->memory.allocated; - } - iter = next; - } -} - -NK_API const struct nk_command* -nk__begin(struct nk_context *ctx) -{ - struct nk_window *iter; - nk_byte *buffer; - NK_ASSERT(ctx); - if (!ctx) return 0; - if (!ctx->count) return 0; - - buffer = (nk_byte*)ctx->memory.memory.ptr; - if (!ctx->build) { - nk_build(ctx); - ctx->build = nk_true; - } - - iter = ctx->begin; - while (iter && ((iter->buffer.begin == iter->buffer.end) || (iter->flags & NK_WINDOW_HIDDEN))) - iter = iter->next; - if (!iter) return 0; - return nk_ptr_add_const(struct nk_command, buffer, iter->buffer.begin); -} - -NK_API const struct nk_command* -nk__next(struct nk_context *ctx, const struct nk_command *cmd) -{ - nk_byte *buffer; - const struct nk_command *next; - NK_ASSERT(ctx); - if (!ctx || !cmd || !ctx->count) return 0; - if (cmd->next >= ctx->memory.allocated) return 0; - buffer = (nk_byte*)ctx->memory.memory.ptr; - next = nk_ptr_add_const(struct nk_command, buffer, cmd->next); - return next; -} - -/* ---------------------------------------------------------------- - * - * PANEL - * - * ---------------------------------------------------------------*/ -static int -nk_panel_has_header(nk_flags flags, const char *title) -{ - /* window header state */ - int active = 0; - active = (flags & (NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE)); - active = active || (flags & NK_WINDOW_TITLE); - active = active && !(flags & NK_WINDOW_HIDDEN) && title; - return active; -} - -NK_INTERN struct nk_vec2 -nk_panel_get_padding(const struct nk_style *style, enum nk_panel_type type) -{ - switch (type) { - default: - case NK_PANEL_WINDOW: return style->window.padding; - case NK_PANEL_GROUP: return style->window.group_padding; - case NK_PANEL_POPUP: return style->window.popup_padding; - case NK_PANEL_CONTEXTUAL: return style->window.contextual_padding; - case NK_PANEL_COMBO: return style->window.combo_padding; - case NK_PANEL_MENU: return style->window.menu_padding; - case NK_PANEL_TOOLTIP: return style->window.menu_padding; - } -} - -NK_INTERN float -nk_panel_get_border(const struct nk_style *style, nk_flags flags, - enum nk_panel_type type) -{ - if (flags & NK_WINDOW_BORDER) { - switch (type) { - default: - case NK_PANEL_WINDOW: return style->window.border; - case NK_PANEL_GROUP: return style->window.group_border; - case NK_PANEL_POPUP: return style->window.popup_border; - case NK_PANEL_CONTEXTUAL: return style->window.contextual_border; - case NK_PANEL_COMBO: return style->window.combo_border; - case NK_PANEL_MENU: return style->window.menu_border; - case NK_PANEL_TOOLTIP: return style->window.menu_border; - }} else return 0; -} - -NK_INTERN struct nk_color -nk_panel_get_border_color(const struct nk_style *style, enum nk_panel_type type) -{ - switch (type) { - default: - case NK_PANEL_WINDOW: return style->window.border_color; - case NK_PANEL_GROUP: return style->window.group_border_color; - case NK_PANEL_POPUP: return style->window.popup_border_color; - case NK_PANEL_CONTEXTUAL: return style->window.contextual_border_color; - case NK_PANEL_COMBO: return style->window.combo_border_color; - case NK_PANEL_MENU: return style->window.menu_border_color; - case NK_PANEL_TOOLTIP: return style->window.menu_border_color; - } -} - -NK_INTERN int -nk_panel_is_sub(enum nk_panel_type type) -{ - return (type & NK_PANEL_SET_SUB)?1:0; -} - -NK_INTERN int -nk_panel_is_nonblock(enum nk_panel_type type) -{ - return (type & NK_PANEL_SET_NONBLOCK)?1:0; -} - -NK_INTERN int -nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type panel_type) -{ - struct nk_input *in; - struct nk_window *win; - struct nk_panel *layout; - struct nk_command_buffer *out; - const struct nk_style *style; - const struct nk_user_font *font; - - struct nk_vec2 scrollbar_size; - struct nk_vec2 panel_padding; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) return 0; - nk_zero(ctx->current->layout, sizeof(*ctx->current->layout)); - if (ctx->current->flags & NK_WINDOW_HIDDEN) - return 0; - - /* pull state into local stack */ - style = &ctx->style; - font = style->font; - in = &ctx->input; - win = ctx->current; - layout = win->layout; - out = &win->buffer; -#ifdef NK_INCLUDE_COMMAND_USERDATA - win->buffer.userdata = ctx->userdata; -#endif - - /* pull style configuration into local stack */ - scrollbar_size = style->window.scrollbar_size; - panel_padding = nk_panel_get_padding(style, panel_type); - - /* window movement */ - if ((win->flags & NK_WINDOW_MOVABLE) && !(win->flags & NK_WINDOW_ROM)) { - int left_mouse_down; - int left_mouse_click_in_cursor; - - /* calculate draggable window space */ - struct nk_rect header; - header.x = win->bounds.x; - header.y = win->bounds.y; - header.w = win->bounds.w; - if (nk_panel_has_header(win->flags, title)) { - header.h = font->height + 2.0f * style->window.header.padding.y; - header.h += 2.0f * style->window.header.label_padding.y; - } else header.h = panel_padding.y; - - /* window movement by dragging */ - left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down; - left_mouse_click_in_cursor = nk_input_has_mouse_click_down_in_rect(in, - NK_BUTTON_LEFT, header, nk_true); - if (left_mouse_down && left_mouse_click_in_cursor) { - win->bounds.x = win->bounds.x + in->mouse.delta.x; - win->bounds.y = win->bounds.y + in->mouse.delta.y; - in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x += in->mouse.delta.x; - in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y += in->mouse.delta.y; - ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_MOVE]; - } - } - - /* setup panel */ - layout->type = panel_type; - layout->flags = win->flags; - layout->bounds = win->bounds; - layout->bounds.x += panel_padding.x; - layout->bounds.w -= 2*panel_padding.x; - if (win->flags & NK_WINDOW_BORDER) { - layout->border = nk_panel_get_border(style, win->flags, panel_type); - layout->bounds = nk_shrink_rect(layout->bounds, layout->border); - } else layout->border = 0; - layout->at_y = layout->bounds.y; - layout->at_x = layout->bounds.x; - layout->max_x = 0; - layout->header_height = 0; - layout->footer_height = 0; - layout->row.index = 0; - layout->row.columns = 0; - layout->row.ratio = 0; - layout->row.item_width = 0; - layout->row.tree_depth = 0; - layout->row.height = panel_padding.y; - layout->has_scrolling = nk_true; - if (!(win->flags & NK_WINDOW_NO_SCROLLBAR)) - layout->bounds.w -= scrollbar_size.x; - if (!nk_panel_is_nonblock(panel_type)) { - layout->footer_height = 0; - if (!(win->flags & NK_WINDOW_NO_SCROLLBAR) || win->flags & NK_WINDOW_SCALABLE) - layout->footer_height = scrollbar_size.y; - layout->bounds.h -= layout->footer_height; - } - - /* panel header */ - if (nk_panel_has_header(win->flags, title)) - { - struct nk_text text; - struct nk_rect header; - const struct nk_style_item *background = 0; - - /* calculate header bounds */ - header.x = win->bounds.x; - header.y = win->bounds.y; - header.w = win->bounds.w; - header.h = font->height + 2.0f * style->window.header.padding.y; - header.h += (2.0f * style->window.header.label_padding.y); - - /* shrink panel by header */ - layout->header_height = header.h; - layout->bounds.y += header.h; - layout->bounds.h -= header.h; - layout->at_y += header.h; - - /* select correct header background and text color */ - if (ctx->active == win) { - background = &style->window.header.active; - text.text = style->window.header.label_active; - } else if (nk_input_is_mouse_hovering_rect(&ctx->input, header)) { - background = &style->window.header.hover; - text.text = style->window.header.label_hover; - } else { - background = &style->window.header.normal; - text.text = style->window.header.label_normal; - } - - /* draw header background */ - header.h += 1.0f; - if (background->type == NK_STYLE_ITEM_IMAGE) { - text.background = nk_rgba(0,0,0,0); - nk_draw_image(&win->buffer, header, &background->data.image, nk_white); - } else { - text.background = background->data.color; - nk_fill_rect(out, header, 0, background->data.color); - } - - /* window close button */ - {struct nk_rect button; - button.y = header.y + style->window.header.padding.y; - button.h = header.h - 2 * style->window.header.padding.y; - button.w = button.h; - if (win->flags & NK_WINDOW_CLOSABLE) { - nk_flags ws = 0; - if (style->window.header.align == NK_HEADER_RIGHT) { - button.x = (header.w + header.x) - (button.w + style->window.header.padding.x); - header.w -= button.w + style->window.header.spacing.x + style->window.header.padding.x; - } else { - button.x = header.x + style->window.header.padding.x; - header.x += button.w + style->window.header.spacing.x + style->window.header.padding.x; - } - - if (nk_do_button_symbol(&ws, &win->buffer, button, - style->window.header.close_symbol, NK_BUTTON_DEFAULT, - &style->window.header.close_button, in, style->font) && !(win->flags & NK_WINDOW_ROM)) - { - layout->flags |= NK_WINDOW_HIDDEN; - layout->flags |= NK_WINDOW_CLOSED; - layout->flags &= (nk_flags)~NK_WINDOW_MINIMIZED; - } - } - - /* window minimize button */ - if (win->flags & NK_WINDOW_MINIMIZABLE) { - nk_flags ws = 0; - if (style->window.header.align == NK_HEADER_RIGHT) { - button.x = (header.w + header.x) - button.w; - if (!(win->flags & NK_WINDOW_CLOSABLE)) { - button.x -= style->window.header.padding.x; - header.w -= style->window.header.padding.x; - } - header.w -= button.w + style->window.header.spacing.x; - } else { - button.x = header.x; - header.x += button.w + style->window.header.spacing.x + style->window.header.padding.x; - } - if (nk_do_button_symbol(&ws, &win->buffer, button, (layout->flags & NK_WINDOW_MINIMIZED)? - style->window.header.maximize_symbol: style->window.header.minimize_symbol, - NK_BUTTON_DEFAULT, &style->window.header.minimize_button, in, style->font) && !(win->flags & NK_WINDOW_ROM)) - layout->flags = (layout->flags & NK_WINDOW_MINIMIZED) ? - layout->flags & (nk_flags)~NK_WINDOW_MINIMIZED: - layout->flags | NK_WINDOW_MINIMIZED; - }} - - {/* window header title */ - int text_len = nk_strlen(title); - struct nk_rect label = {0,0,0,0}; - float t = font->width(font->userdata, font->height, title, text_len); - text.padding = nk_vec2(0,0); - - label.x = header.x + style->window.header.padding.x; - label.x += style->window.header.label_padding.x; - label.y = header.y + style->window.header.label_padding.y; - label.h = font->height + 2 * style->window.header.label_padding.y; - label.w = t + 2 * style->window.header.spacing.x; - nk_widget_text(out, label,(const char*)title, text_len, &text, NK_TEXT_LEFT, font);} - } - - /* draw window background */ - if (!(layout->flags & NK_WINDOW_MINIMIZED) && !(layout->flags & NK_WINDOW_DYNAMIC)) { - struct nk_rect body; - body.x = win->bounds.x; - body.w = win->bounds.w; - body.y = (win->bounds.y + layout->header_height); - body.h = (win->bounds.h - layout->header_height); - if (style->window.fixed_background.type == NK_STYLE_ITEM_IMAGE) - nk_draw_image(out, body, &style->window.fixed_background.data.image, nk_white); - else nk_fill_rect(out, body, 0, style->window.fixed_background.data.color); - } - - /* set clipping rectangle */ - {struct nk_rect clip; - layout->clip = layout->bounds; - nk_unify(&clip, &win->buffer.clip, layout->clip.x, layout->clip.y, - layout->clip.x + layout->clip.w, layout->clip.y + layout->clip.h); - nk_push_scissor(out, clip); - layout->clip = clip;} - return !(layout->flags & NK_WINDOW_HIDDEN) && !(layout->flags & NK_WINDOW_MINIMIZED); -} - -NK_INTERN void -nk_panel_end(struct nk_context *ctx) -{ - struct nk_input *in; - struct nk_window *window; - struct nk_panel *layout; - const struct nk_style *style; - struct nk_command_buffer *out; - - struct nk_vec2 scrollbar_size; - struct nk_vec2 panel_padding; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return; - - window = ctx->current; - layout = window->layout; - style = &ctx->style; - out = &window->buffer; - in = (layout->flags & NK_WINDOW_ROM) ? 0 :&ctx->input; - if (!nk_panel_is_sub(layout->type)) - nk_push_scissor(out, nk_null_rect); - - /* cache configuration data */ - scrollbar_size = style->window.scrollbar_size; - panel_padding = nk_panel_get_padding(style, layout->type); - - /* update the current cursor Y-position to point over the last added widget */ - layout->at_y += layout->row.height; - - /* dynamic panels */ - if (layout->flags & NK_WINDOW_DYNAMIC && !(layout->flags & NK_WINDOW_MINIMIZED)) - { - /* update panel height to fit dynamic growth */ - struct nk_rect empty_space; - if (layout->at_y < (layout->bounds.y + layout->bounds.h)) - layout->bounds.h = layout->at_y - layout->bounds.y; - - /* fill top empty space */ - empty_space.x = window->bounds.x; - empty_space.y = layout->bounds.y; - empty_space.h = panel_padding.y; - empty_space.w = window->bounds.w; - nk_fill_rect(out, empty_space, 0, style->window.background); - - /* fill left empty space */ - empty_space.x = window->bounds.x; - empty_space.y = layout->bounds.y; - empty_space.w = panel_padding.x + layout->border; - empty_space.h = layout->bounds.h; - nk_fill_rect(out, empty_space, 0, style->window.background); - - /* fill right empty space */ - empty_space.x = layout->bounds.x + layout->bounds.w - layout->border; - empty_space.y = layout->bounds.y; - empty_space.w = panel_padding.x + layout->border; - empty_space.h = layout->bounds.h; - if (*layout->offset_y == 0 && !(layout->flags & NK_WINDOW_NO_SCROLLBAR)) - empty_space.w += scrollbar_size.x; - nk_fill_rect(out, empty_space, 0, style->window.background); - - /* fill bottom empty space */ - if (*layout->offset_x != 0 && !(layout->flags & NK_WINDOW_NO_SCROLLBAR)) { - empty_space.x = window->bounds.x; - empty_space.y = layout->bounds.y + layout->bounds.h; - empty_space.w = window->bounds.w; - empty_space.h = scrollbar_size.y; - nk_fill_rect(out, empty_space, 0, style->window.background); - } - } - - /* scrollbars */ - if (!(layout->flags & NK_WINDOW_NO_SCROLLBAR) && - !(layout->flags & NK_WINDOW_MINIMIZED) && - window->scrollbar_hiding_timer < NK_SCROLLBAR_HIDING_TIMEOUT) - { - struct nk_rect scroll; - int scroll_has_scrolling; - float scroll_target; - float scroll_offset; - float scroll_step; - float scroll_inc; - { - /* vertical scrollbar */ - nk_flags state = 0; - scroll.x = layout->bounds.x + layout->bounds.w + panel_padding.x; - scroll.y = layout->bounds.y; - scroll.w = scrollbar_size.x; - scroll.h = layout->bounds.h; - - scroll_offset = (float)*layout->offset_y; - scroll_step = scroll.h * 0.10f; - scroll_inc = scroll.h * 0.01f; - scroll_target = (float)(int)(layout->at_y - scroll.y); - - /* scrolling by mouse wheel */ - if (nk_panel_is_sub(layout->type)) - { - /* sub-window scrollbar wheel scrolling */ - struct nk_window *root_window = window; - struct nk_panel *root_panel = window->layout; - while (root_panel->parent) - root_panel = root_panel->parent; - while (root_window->parent) - root_window = root_window->parent; - - /* only allow scrolling if parent window is active */ - scroll_has_scrolling = 0; - if ((root_window == ctx->active) && layout->has_scrolling) { - /* and panel is being hovered and inside clip rect*/ - if (nk_input_is_mouse_hovering_rect(in, layout->bounds) && - NK_INTERSECT(layout->bounds.x, layout->bounds.y, layout->bounds.w, layout->bounds.h, - root_panel->clip.x, root_panel->clip.y, root_panel->clip.w, root_panel->clip.h)) - { - /* deactivate all parent scrolling */ - root_panel = window->layout; - while (root_panel->parent) { - root_panel->has_scrolling = nk_false; - root_panel = root_panel->parent; - } - root_panel->has_scrolling = nk_false; - scroll_has_scrolling = nk_true; - } - } - } else if (!nk_panel_is_sub(layout->type)) { - /* window scrollbar wheel scrolling */ - scroll_has_scrolling = (window == ctx->active) && layout->has_scrolling; - if (in && in->mouse.scroll_delta > 0 && scroll_has_scrolling) - window->scrolled = nk_true; - else window->scrolled = nk_false; - } else scroll_has_scrolling = nk_false; - - /* execute scrollbar */ - scroll_offset = nk_do_scrollbarv(&state, out, scroll, scroll_has_scrolling, - scroll_offset, scroll_target, scroll_step, scroll_inc, - &ctx->style.scrollv, in, style->font); - *layout->offset_y = (nk_uint)scroll_offset; - if (in && scroll_has_scrolling) - in->mouse.scroll_delta = 0; - } - { - /* horizontal scrollbar */ - nk_flags state = 0; - scroll.x = layout->bounds.x; - scroll.y = layout->bounds.y + layout->bounds.h; - scroll.w = layout->bounds.w; - scroll.h = scrollbar_size.y; - - scroll_offset = (float)*layout->offset_x; - scroll_target = (float)(int)(layout->max_x - scroll.x); - scroll_step = layout->max_x * 0.05f; - scroll_inc = layout->max_x * 0.005f; - scroll_has_scrolling = nk_false; - scroll_offset = nk_do_scrollbarh(&state, out, scroll, scroll_has_scrolling, - scroll_offset, scroll_target, scroll_step, scroll_inc, - &ctx->style.scrollh, in, style->font); - *layout->offset_x = (nk_uint)scroll_offset; - } - } - - /* hide scroll if no user input */ - if (window->flags & NK_WINDOW_SCROLL_AUTO_HIDE) { - int has_input = ctx->input.mouse.delta.x != 0 || ctx->input.mouse.delta.y != 0 || ctx->input.mouse.scroll_delta != 0; - int is_window_hovered = nk_window_is_hovered(ctx); - int any_item_active = (ctx->last_widget_state & NK_WIDGET_STATE_MODIFIED); - if ((!has_input && is_window_hovered) || (!is_window_hovered && !any_item_active)) - window->scrollbar_hiding_timer += ctx->delta_time_seconds; - else window->scrollbar_hiding_timer = 0; - } else window->scrollbar_hiding_timer = 0; - - /* window border */ - if (layout->flags & NK_WINDOW_BORDER) - { - struct nk_color border_color = nk_panel_get_border_color(style, layout->type); - const float padding_y = (layout->flags & NK_WINDOW_MINIMIZED) ? - style->window.border + window->bounds.y + layout->header_height: - (layout->flags & NK_WINDOW_DYNAMIC)? - layout->bounds.y + layout->bounds.h + layout->footer_height: - window->bounds.y + window->bounds.h; - - /* draw border top */ - nk_stroke_line(out,window->bounds.x,window->bounds.y, - window->bounds.x + window->bounds.w, window->bounds.y, - layout->border, border_color); - - /* draw bottom border */ - nk_stroke_line(out, window->bounds.x, padding_y, - window->bounds.x + window->bounds.w, padding_y, layout->border, border_color); - - /* draw left border */ - nk_stroke_line(out, window->bounds.x + layout->border*0.5f, - window->bounds.y, window->bounds.x + layout->border*0.5f, - padding_y, layout->border, border_color); - - /* draw right border */ - nk_stroke_line(out, window->bounds.x + window->bounds.w - layout->border*0.5f, - window->bounds.y, window->bounds.x + window->bounds.w - layout->border*0.5f, - padding_y, layout->border, border_color); - } - - /* scaler */ - if ((layout->flags & NK_WINDOW_SCALABLE) && in && !(layout->flags & NK_WINDOW_MINIMIZED)) - { - /* calculate scaler bounds */ - struct nk_rect scaler; - scaler.w = scrollbar_size.x; - scaler.h = scrollbar_size.y; - scaler.y = layout->bounds.y + layout->bounds.h; - scaler.x = layout->bounds.x + layout->bounds.w + panel_padding.x; - if (layout->flags & NK_WINDOW_NO_SCROLLBAR) - scaler.x -= scaler.w; - - /* draw scaler */ - {const struct nk_style_item *item = &style->window.scaler; - if (item->type == NK_STYLE_ITEM_IMAGE) - nk_draw_image(out, scaler, &item->data.image, nk_white); - else nk_fill_triangle(out, scaler.x + scaler.w, scaler.y, scaler.x + scaler.w, - scaler.y + scaler.h, scaler.x, scaler.y + scaler.h, item->data.color); - } - - /* do window scaling */ - if (!(window->flags & NK_WINDOW_ROM)) { - struct nk_vec2 window_size = style->window.min_size; - int left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down; - int left_mouse_click_in_scaler = nk_input_has_mouse_click_down_in_rect(in, - NK_BUTTON_LEFT, scaler, nk_true); - - if (nk_input_is_mouse_down(in, NK_BUTTON_LEFT) && left_mouse_down && left_mouse_click_in_scaler) { - window->bounds.w = NK_MAX(window_size.x, window->bounds.w + in->mouse.delta.x); - /* dragging in y-direction is only possible if static window */ - if (!(layout->flags & NK_WINDOW_DYNAMIC)) - window->bounds.h = NK_MAX(window_size.y, window->bounds.h + in->mouse.delta.y); - ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_RESIZE_TOP_RIGHT_DOWN_LEFT]; - in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = scaler.x + in->mouse.delta.x + scaler.w/2.0f; - in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y = scaler.y + in->mouse.delta.y + scaler.h/2.0f; - } - } - } - - if (!nk_panel_is_sub(layout->type)) { - /* window is hidden so clear command buffer */ - if (layout->flags & NK_WINDOW_HIDDEN) - nk_command_buffer_reset(&window->buffer); - /* window is visible and not tab */ - else nk_finish(ctx, window); - } - - /* NK_WINDOW_REMOVE_ROM flag was set so remove NK_WINDOW_ROM */ - if (layout->flags & NK_WINDOW_REMOVE_ROM) { - layout->flags &= ~(nk_flags)NK_WINDOW_ROM; - layout->flags &= ~(nk_flags)NK_WINDOW_REMOVE_ROM; - } - window->flags = layout->flags; - - /* property garbage collector */ - if (window->property.active && window->property.old != window->property.seq && - window->property.active == window->property.prev) { - nk_zero(&window->property, sizeof(window->property)); - } else { - window->property.old = window->property.seq; - window->property.prev = window->property.active; - window->property.seq = 0; - } - - /* edit garbage collector */ - if (window->edit.active && window->edit.old != window->edit.seq && - window->edit.active == window->edit.prev) { - nk_zero(&window->edit, sizeof(window->edit)); - } else { - window->edit.old = window->edit.seq; - window->edit.prev = window->edit.active; - window->edit.seq = 0; - } - - /* contextual garbage collector */ - if (window->popup.active_con && window->popup.con_old != window->popup.con_count) { - window->popup.con_count = 0; - window->popup.con_old = 0; - window->popup.active_con = 0; - } else { - window->popup.con_old = window->popup.con_count; - window->popup.con_count = 0; - } - window->popup.combo_count = 0; - - /* helper to make sure you have a 'nk_tree_push' * for every 'nk_tree_pop' */ - NK_ASSERT(!layout->row.tree_depth); -} - -/* ---------------------------------------------------------------- - * - * PAGE ELEMENT - * - * ---------------------------------------------------------------*/ -NK_INTERN struct nk_page_element* -nk_create_page_element(struct nk_context *ctx) -{ - struct nk_page_element *elem; - if (ctx->freelist) { - /* unlink page element from free list */ - elem = ctx->freelist; - ctx->freelist = elem->next; - } else if (ctx->use_pool) { - /* allocate page element from memory pool */ - elem = nk_pool_alloc(&ctx->pool); - NK_ASSERT(elem); - if (!elem) return 0; - } else { - /* allocate new page element from the back of the fixed size memory buffer */ - NK_STORAGE const nk_size size = sizeof(struct nk_page_element); - NK_STORAGE const nk_size align = NK_ALIGNOF(struct nk_page_element); - elem = (struct nk_page_element*)nk_buffer_alloc(&ctx->memory, NK_BUFFER_BACK, size, align); - NK_ASSERT(elem); - if (!elem) return 0; - } - nk_zero_struct(*elem); - elem->next = 0; - elem->prev = 0; - return elem; -} - -NK_INTERN void -nk_link_page_element_into_freelist(struct nk_context *ctx, - struct nk_page_element *elem) -{ - /* link table into freelist */ - if (!ctx->freelist) { - ctx->freelist = elem; - } else { - elem->next = ctx->freelist; - ctx->freelist = elem; - } -} - -NK_INTERN void -nk_free_page_element(struct nk_context *ctx, struct nk_page_element *elem) -{ - /* we have a pool so just add to free list */ - if (ctx->use_pool) { - nk_link_page_element_into_freelist(ctx, elem); - return; - } - - /* if possible remove last element from back of fixed memory buffer */ - {void *elem_end = (void*)(elem + 1); - void *buffer_end = (nk_byte*)ctx->memory.memory.ptr + ctx->memory.size; - if (elem_end == buffer_end) - ctx->memory.size -= sizeof(struct nk_page_element); - else nk_link_page_element_into_freelist(ctx, elem);} -} - -/* ---------------------------------------------------------------- - * - * PANEL - * - * ---------------------------------------------------------------*/ -NK_INTERN void* -nk_create_panel(struct nk_context *ctx) -{ - struct nk_page_element *elem; - elem = nk_create_page_element(ctx); - if (!elem) return 0; - nk_zero_struct(*elem); - return &elem->data.pan; -} - -NK_INTERN void -nk_free_panel(struct nk_context *ctx, struct nk_panel *pan) -{ - union nk_page_data *pd = NK_CONTAINER_OF(pan, union nk_page_data, pan); - struct nk_page_element *pe = NK_CONTAINER_OF(pd, struct nk_page_element, data); - nk_free_page_element(ctx, pe); -} - -/* ---------------------------------------------------------------- - * - * TABLES - * - * ---------------------------------------------------------------*/ -NK_INTERN struct nk_table* -nk_create_table(struct nk_context *ctx) -{ - struct nk_page_element *elem; - elem = nk_create_page_element(ctx); - if (!elem) return 0; - nk_zero_struct(*elem); - return &elem->data.tbl; -} - -NK_INTERN void -nk_free_table(struct nk_context *ctx, struct nk_table *tbl) -{ - union nk_page_data *pd = NK_CONTAINER_OF(tbl, union nk_page_data, tbl); - struct nk_page_element *pe = NK_CONTAINER_OF(pd, struct nk_page_element, data); - nk_free_page_element(ctx, pe); -} - -NK_INTERN void -nk_push_table(struct nk_window *win, struct nk_table *tbl) -{ - if (!win->tables) { - win->tables = tbl; - tbl->next = 0; - tbl->prev = 0; - win->table_count = 1; - win->table_size = 0; - return; - } - win->tables->prev = tbl; - tbl->next = win->tables; - tbl->prev = 0; - win->tables = tbl; - win->table_count++; - win->table_size = 0; -} - -NK_INTERN void -nk_remove_table(struct nk_window *win, struct nk_table *tbl) -{ - if (win->tables == tbl) - win->tables = tbl->next; - if (tbl->next) - tbl->next->prev = tbl->prev; - if (tbl->prev) - tbl->prev->next = tbl->next; - tbl->next = 0; - tbl->prev = 0; -} - -NK_INTERN nk_uint* -nk_add_value(struct nk_context *ctx, struct nk_window *win, - nk_hash name, nk_uint value) -{ - NK_ASSERT(ctx); - NK_ASSERT(win); - if (!win || !ctx) return 0; - if (!win->tables || win->table_size >= NK_VALUE_PAGE_CAPACITY) { - struct nk_table *tbl = nk_create_table(ctx); - NK_ASSERT(tbl); - if (!tbl) return 0; - nk_push_table(win, tbl); - } - win->tables->seq = win->seq; - win->tables->keys[win->table_size] = name; - win->tables->values[win->table_size] = value; - return &win->tables->values[win->table_size++]; -} - -NK_INTERN nk_uint* -nk_find_value(struct nk_window *win, nk_hash name) -{ - nk_ushort size = win->table_size; - struct nk_table *iter = win->tables; - while (iter) { - nk_ushort i = 0; - for (i = 0; i < size; ++i) { - if (iter->keys[i] == name) { - iter->seq = win->seq; - return &iter->values[i]; - } - } - size = NK_VALUE_PAGE_CAPACITY; - iter = iter->next; - } - return 0; -} - -/* ---------------------------------------------------------------- - * - * WINDOW - * - * ---------------------------------------------------------------*/ -NK_INTERN void* -nk_create_window(struct nk_context *ctx) -{ - struct nk_page_element *elem; - elem = nk_create_page_element(ctx); - if (!elem) return 0; - elem->data.win.seq = ctx->seq; - return &elem->data.win; -} - -NK_INTERN void -nk_free_window(struct nk_context *ctx, struct nk_window *win) -{ - /* unlink windows from list */ - struct nk_table *n, *it = win->tables; - if (win->popup.win) { - nk_free_window(ctx, win->popup.win); - win->popup.win = 0; - } - win->next = 0; - win->prev = 0; - - while (it) { - /*free window state tables */ - n = it->next; - nk_remove_table(win, it); - nk_free_table(ctx, it); - if (it == win->tables) - win->tables = n; - it = n; - } - - /* link windows into freelist */ - {union nk_page_data *pd = NK_CONTAINER_OF(win, union nk_page_data, win); - struct nk_page_element *pe = NK_CONTAINER_OF(pd, struct nk_page_element, data); - nk_free_page_element(ctx, pe);} -} - -NK_INTERN struct nk_window* -nk_find_window(struct nk_context *ctx, nk_hash hash, const char *name) -{ - struct nk_window *iter; - iter = ctx->begin; - while (iter) { - NK_ASSERT(iter != iter->next); - if (iter->name == hash) { - int max_len = nk_strlen(iter->name_string); - if (!nk_stricmpn(iter->name_string, name, max_len)) - return iter; - } - iter = iter->next; - } - return 0; -} - -enum nk_window_insert_location { - NK_INSERT_BACK, /* inserts window into the back of list (front of screen) */ - NK_INSERT_FRONT /* inserts window into the front of list (back of screen) */ -}; -NK_INTERN void -nk_insert_window(struct nk_context *ctx, struct nk_window *win, - enum nk_window_insert_location loc) -{ - const struct nk_window *iter; - NK_ASSERT(ctx); - NK_ASSERT(win); - if (!win || !ctx) return; - - iter = ctx->begin; - while (iter) { - NK_ASSERT(iter != iter->next); - NK_ASSERT(iter != win); - if (iter == win) return; - iter = iter->next; - } - - if (!ctx->begin) { - win->next = 0; - win->prev = 0; - ctx->begin = win; - ctx->end = win; - ctx->count = 1; - return; - } - if (loc == NK_INSERT_BACK) { - struct nk_window *end; - end = ctx->end; - end->flags |= NK_WINDOW_ROM; - end->next = win; - win->prev = ctx->end; - win->next = 0; - ctx->end = win; - ctx->active = ctx->end; - ctx->end->flags &= ~(nk_flags)NK_WINDOW_ROM; - } else { - ctx->end->flags |= NK_WINDOW_ROM; - ctx->begin->prev = win; - win->next = ctx->begin; - win->prev = 0; - ctx->begin = win; - ctx->begin->flags &= ~(nk_flags)NK_WINDOW_ROM; - } - ctx->count++; -} - -NK_INTERN void -nk_remove_window(struct nk_context *ctx, struct nk_window *win) -{ - if (win == ctx->begin || win == ctx->end) { - if (win == ctx->begin) { - ctx->begin = win->next; - if (win->next) - win->next->prev = 0; - } - if (win == ctx->end) { - ctx->end = win->prev; - if (win->prev) - win->prev->next = 0; - } - } else { - if (win->next) - win->next->prev = win->prev; - if (win->prev) - win->prev->next = win->next; - } - if (win == ctx->active || !ctx->active) { - ctx->active = ctx->end; - if (ctx->end) - ctx->end->flags &= ~(nk_flags)NK_WINDOW_ROM; - } - win->next = 0; - win->prev = 0; - ctx->count--; -} - -NK_API int -nk_begin(struct nk_context *ctx, const char *title, - struct nk_rect bounds, nk_flags flags) -{ - return nk_begin_titled(ctx, title, title, bounds, flags); -} - -NK_API int -nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, - struct nk_rect bounds, nk_flags flags) -{ - struct nk_window *win; - struct nk_style *style; - nk_hash title_hash; - int title_len; - int ret = 0; - - NK_ASSERT(ctx); - NK_ASSERT(name); - NK_ASSERT(title); - NK_ASSERT(ctx->style.font && ctx->style.font->width && "if this triggers you forgot to add a font"); - NK_ASSERT(!ctx->current && "if this triggers you missed a `nk_end` call"); - if (!ctx || ctx->current || !title || !name) - return 0; - - /* find or create window */ - style = &ctx->style; - title_len = (int)nk_strlen(name); - title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE); - win = nk_find_window(ctx, title_hash, name); - if (!win) { - /* create new window */ - nk_size name_length = (nk_size)nk_strlen(name); - win = (struct nk_window*)nk_create_window(ctx); - NK_ASSERT(win); - if (!win) return 0; - - if (flags & NK_WINDOW_BACKGROUND) - nk_insert_window(ctx, win, NK_INSERT_FRONT); - else nk_insert_window(ctx, win, NK_INSERT_BACK); - nk_command_buffer_init(&win->buffer, &ctx->memory, NK_CLIPPING_ON); - - win->flags = flags; - win->bounds = bounds; - win->name = title_hash; - name_length = NK_MIN(name_length, NK_WINDOW_MAX_NAME-1); - NK_MEMCPY(win->name_string, name, name_length); - win->name_string[name_length] = 0; - win->popup.win = 0; - if (!ctx->active) - ctx->active = win; - } else { - /* update window */ - win->flags &= ~(nk_flags)(NK_WINDOW_PRIVATE-1); - win->flags |= flags; - if (!(win->flags & (NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE))) - win->bounds = bounds; - /* If this assert triggers you either: - * - * I.) Have more than one window with the same name or - * II.) You forgot to actually draw the window. - * More specific you did not call `nk_clear` (nk_clear will be - * automatically called for you if you are using one of the - * provided demo backends). */ - NK_ASSERT(win->seq != ctx->seq); - win->seq = ctx->seq; - if (!ctx->active) - ctx->active = win; - } - if (win->flags & NK_WINDOW_HIDDEN) { - ctx->current = win; - return 0; - } - - /* window overlapping */ - if (!(win->flags & NK_WINDOW_HIDDEN)) - { - int inpanel, ishovered; - const struct nk_window *iter = win; - float h = ctx->style.font->height + 2.0f * style->window.header.padding.y + - (2.0f * style->window.header.label_padding.y); - struct nk_rect win_bounds = (!(win->flags & NK_WINDOW_MINIMIZED))? - win->bounds: nk_rect(win->bounds.x, win->bounds.y, win->bounds.w, h); - - /* activate window if hovered and no other window is overlapping this window */ - nk_start(ctx, win); - inpanel = nk_input_has_mouse_click_down_in_rect(&ctx->input, NK_BUTTON_LEFT, win_bounds, nk_true); - inpanel = inpanel && ctx->input.mouse.buttons[NK_BUTTON_LEFT].clicked; - ishovered = nk_input_is_mouse_hovering_rect(&ctx->input, win_bounds); - if ((win != ctx->active) && ishovered && !ctx->input.mouse.buttons[NK_BUTTON_LEFT].down) { - iter = win->next; - while (iter) { - struct nk_rect iter_bounds = (!(iter->flags & NK_WINDOW_MINIMIZED))? - iter->bounds: nk_rect(iter->bounds.x, iter->bounds.y, iter->bounds.w, h); - if (NK_INTERSECT(win_bounds.x, win_bounds.y, win_bounds.w, win_bounds.h, - iter_bounds.x, iter_bounds.y, iter_bounds.w, iter_bounds.h) && - (!(iter->flags & NK_WINDOW_HIDDEN) || !(iter->flags & NK_WINDOW_BACKGROUND))) - break; - - if (iter->popup.win && iter->popup.active && !(iter->flags & NK_WINDOW_HIDDEN) && - NK_INTERSECT(win->bounds.x, win_bounds.y, win_bounds.w, win_bounds.h, - iter->popup.win->bounds.x, iter->popup.win->bounds.y, - iter->popup.win->bounds.w, iter->popup.win->bounds.h)) - break; - iter = iter->next; - } - } - - /* activate window if clicked */ - if (iter && inpanel && (win != ctx->end) && !(iter->flags & NK_WINDOW_BACKGROUND)) { - iter = win->next; - while (iter) { - /* try to find a panel with higher priority in the same position */ - struct nk_rect iter_bounds = (!(iter->flags & NK_WINDOW_MINIMIZED))? - iter->bounds: nk_rect(iter->bounds.x, iter->bounds.y, iter->bounds.w, h); - if (NK_INBOX(ctx->input.mouse.pos.x, ctx->input.mouse.pos.y, - iter_bounds.x, iter_bounds.y, iter_bounds.w, iter_bounds.h) && - !(iter->flags & NK_WINDOW_HIDDEN)) - break; - if (iter->popup.win && iter->popup.active && !(iter->flags & NK_WINDOW_HIDDEN) && - NK_INTERSECT(win_bounds.x, win_bounds.y, win_bounds.w, win_bounds.h, - iter->popup.win->bounds.x, iter->popup.win->bounds.y, - iter->popup.win->bounds.w, iter->popup.win->bounds.h)) - break; - iter = iter->next; - } - } - - if (!iter && ctx->end != win) { - if (!(win->flags & NK_WINDOW_BACKGROUND)) { - /* current window is active in that position so transfer to top - * at the highest priority in stack */ - nk_remove_window(ctx, win); - nk_insert_window(ctx, win, NK_INSERT_BACK); - } - win->flags &= ~(nk_flags)NK_WINDOW_ROM; - ctx->active = win; - } - if (ctx->end != win && !(win->flags & NK_WINDOW_BACKGROUND)) - win->flags |= NK_WINDOW_ROM; - } - - win->layout = (struct nk_panel*)nk_create_panel(ctx); - ctx->current = win; - ret = nk_panel_begin(ctx, title, NK_PANEL_WINDOW); - win->layout->offset_x = &win->scrollbar.x; - win->layout->offset_y = &win->scrollbar.y; - return ret; -} - -NK_API void -nk_end(struct nk_context *ctx) -{ - struct nk_panel *layout; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current && "if this triggers you forgot to call `nk_begin`"); - NK_ASSERT(ctx->current->layout); - - layout = ctx->current->layout; - if (!ctx || !ctx->current) return; - if (layout->type == NK_PANEL_WINDOW && (ctx->current->flags & NK_WINDOW_HIDDEN)) { - ctx->current = 0; - return; - } - nk_panel_end(ctx); - nk_free_panel(ctx, ctx->current->layout); - ctx->current = 0; -} - -NK_API struct nk_rect -nk_window_get_bounds(const struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) return nk_rect(0,0,0,0); - return ctx->current->bounds; -} - -NK_API struct nk_vec2 -nk_window_get_position(const struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) return nk_vec2(0,0); - return nk_vec2(ctx->current->bounds.x, ctx->current->bounds.y); -} - -NK_API struct nk_vec2 -nk_window_get_size(const struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) return nk_vec2(0,0); - return nk_vec2(ctx->current->bounds.w, ctx->current->bounds.h); -} - -NK_API float -nk_window_get_width(const struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) return 0; - return ctx->current->bounds.w; -} - -NK_API float -nk_window_get_height(const struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) return 0; - return ctx->current->bounds.h; -} - -NK_API struct nk_rect -nk_window_get_content_region(struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) return nk_rect(0,0,0,0); - return ctx->current->layout->clip; -} - -NK_API struct nk_vec2 -nk_window_get_content_region_min(struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current) return nk_vec2(0,0); - return nk_vec2(ctx->current->layout->clip.x, ctx->current->layout->clip.y); -} - -NK_API struct nk_vec2 -nk_window_get_content_region_max(struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current) return nk_vec2(0,0); - return nk_vec2(ctx->current->layout->clip.x + ctx->current->layout->clip.w, - ctx->current->layout->clip.y + ctx->current->layout->clip.h); -} - -NK_API struct nk_vec2 -nk_window_get_content_region_size(struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current) return nk_vec2(0,0); - return nk_vec2(ctx->current->layout->clip.w, ctx->current->layout->clip.h); -} - -NK_API struct nk_command_buffer* -nk_window_get_canvas(struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current) return 0; - return &ctx->current->buffer; -} - -NK_API struct nk_panel* -nk_window_get_panel(struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) return 0; - return ctx->current->layout; -} - -NK_API int -nk_window_has_focus(const struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current) return 0; - return ctx->current == ctx->active; -} - -NK_API int -nk_window_is_hovered(struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) return 0; - return nk_input_is_mouse_hovering_rect(&ctx->input, ctx->current->bounds); -} - -NK_API int -nk_window_is_any_hovered(struct nk_context *ctx) -{ - struct nk_window *iter; - NK_ASSERT(ctx); - if (!ctx) return 0; - iter = ctx->begin; - while (iter) { - /* check if window is being hovered */ - if (iter->flags & NK_WINDOW_MINIMIZED) { - struct nk_rect header = iter->bounds; - header.h = ctx->style.font->height + 2 * ctx->style.window.header.padding.y; - if (nk_input_is_mouse_hovering_rect(&ctx->input, header)) - return 1; - } else if (nk_input_is_mouse_hovering_rect(&ctx->input, iter->bounds)) { - return 1; - } - /* check if window popup is being hovered */ - if (iter->popup.active && iter->popup.win && nk_input_is_mouse_hovering_rect(&ctx->input, iter->popup.win->bounds)) - return 1; - iter = iter->next; - } - return 0; -} - -NK_API int -nk_item_is_any_active(struct nk_context *ctx) -{ - int any_hovered = nk_window_is_any_hovered(ctx); - int any_active = (ctx->last_widget_state & NK_WIDGET_STATE_MODIFIED); - return any_hovered || any_active; -} - -NK_API int -nk_window_is_collapsed(struct nk_context *ctx, const char *name) -{ - int title_len; - nk_hash title_hash; - struct nk_window *win; - NK_ASSERT(ctx); - if (!ctx) return 0; - - title_len = (int)nk_strlen(name); - title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE); - win = nk_find_window(ctx, title_hash, name); - if (!win) return 0; - return win->flags & NK_WINDOW_MINIMIZED; -} - -NK_API int -nk_window_is_closed(struct nk_context *ctx, const char *name) -{ - int title_len; - nk_hash title_hash; - struct nk_window *win; - NK_ASSERT(ctx); - if (!ctx) return 1; - - title_len = (int)nk_strlen(name); - title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE); - win = nk_find_window(ctx, title_hash, name); - if (!win) return 1; - return (win->flags & NK_WINDOW_CLOSED); -} - -NK_API int -nk_window_is_hidden(struct nk_context *ctx, const char *name) -{ - int title_len; - nk_hash title_hash; - struct nk_window *win; - NK_ASSERT(ctx); - if (!ctx) return 1; - - title_len = (int)nk_strlen(name); - title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE); - win = nk_find_window(ctx, title_hash, name); - if (!win) return 1; - return (win->flags & NK_WINDOW_HIDDEN); -} - -NK_API int -nk_window_is_active(struct nk_context *ctx, const char *name) -{ - int title_len; - nk_hash title_hash; - struct nk_window *win; - NK_ASSERT(ctx); - if (!ctx) return 0; - - title_len = (int)nk_strlen(name); - title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE); - win = nk_find_window(ctx, title_hash, name); - if (!win) return 0; - return win == ctx->active; -} - -NK_API struct nk_window* -nk_window_find(struct nk_context *ctx, const char *name) -{ - int title_len; - nk_hash title_hash; - title_len = (int)nk_strlen(name); - title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE); - return nk_find_window(ctx, title_hash, name); -} - -NK_API void -nk_window_close(struct nk_context *ctx, const char *name) -{ - struct nk_window *win; - NK_ASSERT(ctx); - if (!ctx) return; - win = nk_window_find(ctx, name); - if (!win) return; - NK_ASSERT(ctx->current != win && "You cannot close a currently active window"); - if (ctx->current == win) return; - win->flags |= NK_WINDOW_HIDDEN; - win->flags |= NK_WINDOW_CLOSED; -} - -NK_API void -nk_window_set_bounds(struct nk_context *ctx, struct nk_rect bounds) -{ - NK_ASSERT(ctx); NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) return; - ctx->current->bounds = bounds; -} - -NK_API void -nk_window_set_position(struct nk_context *ctx, struct nk_vec2 pos) -{ - NK_ASSERT(ctx); NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) return; - ctx->current->bounds.x = pos.x; - ctx->current->bounds.y = pos.y; -} - -NK_API void -nk_window_set_size(struct nk_context *ctx, struct nk_vec2 size) -{ - NK_ASSERT(ctx); NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) return; - ctx->current->bounds.w = size.x; - ctx->current->bounds.h = size.y; -} - -NK_API void -nk_window_collapse(struct nk_context *ctx, const char *name, - enum nk_collapse_states c) -{ - int title_len; - nk_hash title_hash; - struct nk_window *win; - NK_ASSERT(ctx); - if (!ctx) return; - - title_len = (int)nk_strlen(name); - title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE); - win = nk_find_window(ctx, title_hash, name); - if (!win) return; - if (c == NK_MINIMIZED) - win->flags |= NK_WINDOW_MINIMIZED; - else win->flags &= ~(nk_flags)NK_WINDOW_MINIMIZED; -} - -NK_API void -nk_window_collapse_if(struct nk_context *ctx, const char *name, - enum nk_collapse_states c, int cond) -{ - NK_ASSERT(ctx); - if (!ctx || !cond) return; - nk_window_collapse(ctx, name, c); -} - -NK_API void -nk_window_show(struct nk_context *ctx, const char *name, enum nk_show_states s) -{ - int title_len; - nk_hash title_hash; - struct nk_window *win; - NK_ASSERT(ctx); - if (!ctx) return; - - title_len = (int)nk_strlen(name); - title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE); - win = nk_find_window(ctx, title_hash, name); - if (!win) return; - if (s == NK_HIDDEN) - win->flags |= NK_WINDOW_HIDDEN; - else win->flags &= ~(nk_flags)NK_WINDOW_HIDDEN; -} - -NK_API void -nk_window_show_if(struct nk_context *ctx, const char *name, - enum nk_show_states s, int cond) -{ - NK_ASSERT(ctx); - if (!ctx || !cond) return; - nk_window_show(ctx, name, s); -} - -NK_API void -nk_window_set_focus(struct nk_context *ctx, const char *name) -{ - int title_len; - nk_hash title_hash; - struct nk_window *win; - NK_ASSERT(ctx); - if (!ctx) return; - - title_len = (int)nk_strlen(name); - title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE); - win = nk_find_window(ctx, title_hash, name); - if (win && ctx->end != win) { - nk_remove_window(ctx, win); - nk_insert_window(ctx, win, NK_INSERT_BACK); - } - ctx->active = win; -} - -/*---------------------------------------------------------------- - * - * MENUBAR - * - * --------------------------------------------------------------*/ -NK_API void -nk_menubar_begin(struct nk_context *ctx) -{ - struct nk_panel *layout; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return; - - layout = ctx->current->layout; - NK_ASSERT(layout->at_y == layout->bounds.y); - /* if this assert triggers you allocated space between nk_begin and nk_menubar_begin. - If you want a menubar the first nuklear function after `nk_begin` has to be a - `nk_menubar_begin` call. Inside the menubar you then have to allocate space for - widgets (also supports multiple rows). - Example: - if (nk_begin(...)) { - nk_menubar_begin(...); - nk_layout_xxxx(...); - nk_button(...); - nk_layout_xxxx(...); - nk_button(...); - nk_menubar_end(...); - } - nk_end(...); - */ - if (layout->flags & NK_WINDOW_HIDDEN || layout->flags & NK_WINDOW_MINIMIZED) - return; - - layout->menu.x = layout->at_x; - layout->menu.y = layout->at_y + layout->row.height; - layout->menu.w = layout->bounds.w; - layout->menu.offset.x = *layout->offset_x; - layout->menu.offset.y = *layout->offset_y; - *layout->offset_y = 0; -} - -NK_API void -nk_menubar_end(struct nk_context *ctx) -{ - struct nk_window *win; - struct nk_panel *layout; - struct nk_command_buffer *out; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return; - - win = ctx->current; - out = &win->buffer; - layout = win->layout; - if (layout->flags & NK_WINDOW_HIDDEN || layout->flags & NK_WINDOW_MINIMIZED) - return; - - layout->menu.h = layout->at_y - layout->menu.y; - layout->bounds.y += layout->menu.h + ctx->style.window.spacing.y + layout->row.height; - layout->bounds.h -= layout->menu.h + ctx->style.window.spacing.y + layout->row.height; - - *layout->offset_x = layout->menu.offset.x; - *layout->offset_y = layout->menu.offset.y; - layout->at_y = layout->bounds.y - layout->row.height; - - layout->clip.y = layout->bounds.y; - layout->clip.h = layout->bounds.h; - nk_push_scissor(out, layout->clip); -} -/* ------------------------------------------------------------- - * - * LAYOUT - * - * --------------------------------------------------------------*/ -#define NK_LAYOUT_DYNAMIC_FIXED 0 -#define NK_LAYOUT_DYNAMIC_ROW 1 -#define NK_LAYOUT_DYNAMIC_FREE 2 -#define NK_LAYOUT_DYNAMIC 3 -#define NK_LAYOUT_STATIC_FIXED 4 -#define NK_LAYOUT_STATIC_ROW 5 -#define NK_LAYOUT_STATIC_FREE 6 -#define NK_LAYOUT_STATIC 7 - -NK_INTERN void -nk_panel_layout(const struct nk_context *ctx, struct nk_window *win, - float height, int cols) -{ - struct nk_panel *layout; - const struct nk_style *style; - struct nk_command_buffer *out; - - struct nk_vec2 item_spacing; - struct nk_color color; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return; - - /* prefetch some configuration data */ - layout = win->layout; - style = &ctx->style; - out = &win->buffer; - color = style->window.background; - item_spacing = style->window.spacing; - - /* if one of these triggers you forgot to add an `if` condition around either - a window, group, popup, combobox or contextual menu `begin` and `end` block. - Example: - if (nk_begin(...) {...} nk_end(...); or - if (nk_group_begin(...) { nk_group_end(...);} */ - NK_ASSERT(!(layout->flags & NK_WINDOW_MINIMIZED)); - NK_ASSERT(!(layout->flags & NK_WINDOW_HIDDEN)); - NK_ASSERT(!(layout->flags & NK_WINDOW_CLOSED)); - - /* update the current row and set the current row layout */ - layout->row.index = 0; - layout->at_y += layout->row.height; - layout->row.columns = cols; - layout->row.height = height + item_spacing.y; - layout->row.item_offset = 0; - if (layout->flags & NK_WINDOW_DYNAMIC) { - /* draw background for dynamic panels */ - struct nk_rect background; - background.x = win->bounds.x; - background.w = win->bounds.w; - background.y = layout->at_y - 1.0f; - background.h = layout->row.height + 1.0f; - nk_fill_rect(out, background, 0, color); - } -} - -NK_INTERN void -nk_row_layout(struct nk_context *ctx, enum nk_layout_format fmt, - float height, int cols, int width) -{ - /* update the current row and set the current row layout */ - struct nk_window *win; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return; - - win = ctx->current; - nk_panel_layout(ctx, win, height, cols); - if (fmt == NK_DYNAMIC) - win->layout->row.type = NK_LAYOUT_DYNAMIC_FIXED; - else win->layout->row.type = NK_LAYOUT_STATIC_FIXED; - - win->layout->row.ratio = 0; - win->layout->row.filled = 0; - win->layout->row.item_offset = 0; - win->layout->row.item_width = (float)width; -} - -NK_API float -nk_layout_ratio_from_pixel(struct nk_context *ctx, float pixel_width) -{ - struct nk_window *win; - NK_ASSERT(ctx); - NK_ASSERT(pixel_width); - if (!ctx || !ctx->current || !ctx->current->layout) return 0; - win = ctx->current; - return NK_CLAMP(0.0f, pixel_width/win->bounds.x, 1.0f); -} - -NK_API void -nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols) -{ - nk_row_layout(ctx, NK_DYNAMIC, height, cols, 0); -} - -NK_API void -nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols) -{ - nk_row_layout(ctx, NK_STATIC, height, cols, item_width); -} - -NK_API void -nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt, - float row_height, int cols) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return; - - win = ctx->current; - layout = win->layout; - nk_panel_layout(ctx, win, row_height, cols); - if (fmt == NK_DYNAMIC) - layout->row.type = NK_LAYOUT_DYNAMIC_ROW; - else layout->row.type = NK_LAYOUT_STATIC_ROW; - - layout->row.ratio = 0; - layout->row.filled = 0; - layout->row.item_width = 0; - layout->row.item_offset = 0; - layout->row.columns = cols; -} - -NK_API void -nk_layout_row_push(struct nk_context *ctx, float ratio_or_width) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return; - - win = ctx->current; - layout = win->layout; - if (layout->row.type == NK_LAYOUT_DYNAMIC_ROW) { - float ratio = ratio_or_width; - if ((ratio + layout->row.filled) > 1.0f) return; - if (ratio > 0.0f) - layout->row.item_width = NK_SATURATE(ratio); - else layout->row.item_width = 1.0f - layout->row.filled; - } else layout->row.item_width = ratio_or_width; -} - -NK_API void -nk_layout_row_end(struct nk_context *ctx) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return; - - win = ctx->current; - layout = win->layout; - layout->row.item_width = 0; - layout->row.item_offset = 0; -} - -NK_API void -nk_layout_row(struct nk_context *ctx, enum nk_layout_format fmt, - float height, int cols, const float *ratio) -{ - int i; - int n_undef = 0; - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return; - - win = ctx->current; - layout = win->layout; - nk_panel_layout(ctx, win, height, cols); - if (fmt == NK_DYNAMIC) { - /* calculate width of undefined widget ratios */ - float r = 0; - layout->row.ratio = ratio; - for (i = 0; i < cols; ++i) { - if (ratio[i] < 0.0f) - n_undef++; - else r += ratio[i]; - } - r = NK_SATURATE(1.0f - r); - layout->row.type = NK_LAYOUT_DYNAMIC; - layout->row.item_width = (r > 0 && n_undef > 0) ? (r / (float)n_undef):0; - } else { - layout->row.ratio = ratio; - layout->row.type = NK_LAYOUT_STATIC; - layout->row.item_width = 0; - layout->row.item_offset = 0; - } - layout->row.item_offset = 0; - layout->row.filled = 0; -} - -NK_API void -nk_layout_space_begin(struct nk_context *ctx, enum nk_layout_format fmt, - float height, int widget_count) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return; - - win = ctx->current; - layout = win->layout; - nk_panel_layout(ctx, win, height, widget_count); - if (fmt == NK_STATIC) - layout->row.type = NK_LAYOUT_STATIC_FREE; - else layout->row.type = NK_LAYOUT_DYNAMIC_FREE; - - layout->row.ratio = 0; - layout->row.filled = 0; - layout->row.item_width = 0; - layout->row.item_offset = 0; -} - -NK_API void -nk_layout_space_end(struct nk_context *ctx) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return; - - win = ctx->current; - layout = win->layout; - layout->row.item_width = 0; - layout->row.item_height = 0; - layout->row.item_offset = 0; - nk_zero(&layout->row.item, sizeof(layout->row.item)); -} - -NK_API void -nk_layout_space_push(struct nk_context *ctx, struct nk_rect rect) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return; - - win = ctx->current; - layout = win->layout; - layout->row.item = rect; -} - -NK_API struct nk_rect -nk_layout_space_bounds(struct nk_context *ctx) -{ - struct nk_rect ret; - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - win = ctx->current; - layout = win->layout; - - ret.x = layout->clip.x; - ret.y = layout->clip.y; - ret.w = layout->clip.w; - ret.h = layout->row.height; - return ret; -} - -NK_API struct nk_vec2 -nk_layout_space_to_screen(struct nk_context *ctx, struct nk_vec2 ret) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - win = ctx->current; - layout = win->layout; - - ret.x += layout->at_x - *layout->offset_x; - ret.y += layout->at_y - *layout->offset_y; - return ret; -} - -NK_API struct nk_vec2 -nk_layout_space_to_local(struct nk_context *ctx, struct nk_vec2 ret) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - win = ctx->current; - layout = win->layout; - - ret.x += -layout->at_x + *layout->offset_x; - ret.y += -layout->at_y + *layout->offset_y; - return ret; -} - -NK_API struct nk_rect -nk_layout_space_rect_to_screen(struct nk_context *ctx, struct nk_rect ret) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - win = ctx->current; - layout = win->layout; - - ret.x += layout->at_x - *layout->offset_x; - ret.y += layout->at_y - *layout->offset_y; - return ret; -} - -NK_API struct nk_rect -nk_layout_space_rect_to_local(struct nk_context *ctx, struct nk_rect ret) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - win = ctx->current; - layout = win->layout; - - ret.x += -layout->at_x + *layout->offset_x; - ret.y += -layout->at_y + *layout->offset_y; - return ret; -} - -NK_INTERN void -nk_panel_alloc_row(const struct nk_context *ctx, struct nk_window *win) -{ - struct nk_panel *layout = win->layout; - struct nk_vec2 spacing = ctx->style.window.spacing; - const float row_height = layout->row.height - spacing.y; - nk_panel_layout(ctx, win, row_height, layout->row.columns); -} - -NK_INTERN void -nk_layout_widget_space(struct nk_rect *bounds, const struct nk_context *ctx, - struct nk_window *win, int modify) -{ - struct nk_panel *layout; - const struct nk_style *style; - - float item_offset = 0; - float item_width = 0; - float item_spacing = 0; - - float panel_padding; - float panel_spacing; - float panel_space; - - struct nk_vec2 spacing; - struct nk_vec2 padding; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return; - - win = ctx->current; - style = &ctx->style; - layout = win->layout; - NK_ASSERT(bounds); - - /* cache some configuration data */ - spacing = ctx->style.window.spacing; - padding = nk_panel_get_padding(style, layout->type); - - /* calculate the usable panel space */ - panel_padding = 2 * padding.x; - panel_spacing = (float)(layout->row.columns - 1) * spacing.x; - panel_space = layout->bounds.w - panel_padding - panel_spacing; - - /* calculate the width of one item inside the current layout space */ - switch (layout->row.type) { - case NK_LAYOUT_DYNAMIC_FIXED: { - /* scaling fixed size widgets item width */ - item_width = panel_space / (float)layout->row.columns; - item_offset = (float)layout->row.index * item_width; - item_spacing = (float)layout->row.index * spacing.x; - } break; - case NK_LAYOUT_DYNAMIC_ROW: { - /* scaling single ratio widget width */ - item_width = layout->row.item_width * panel_space; - item_offset = layout->row.item_offset; - item_spacing = 0; - - if (modify) { - layout->row.item_offset += item_width + spacing.x; - layout->row.filled += layout->row.item_width; - layout->row.index = 0; - } - } break; - case NK_LAYOUT_DYNAMIC_FREE: { - /* panel width depended free widget placing */ - bounds->x = layout->at_x + (layout->bounds.w * layout->row.item.x); - bounds->x -= *layout->offset_x; - bounds->y = layout->at_y + (layout->row.height * layout->row.item.y); - bounds->y -= *layout->offset_y; - bounds->w = layout->bounds.w * layout->row.item.w; - bounds->h = layout->row.height * layout->row.item.h; - return; - }; - case NK_LAYOUT_DYNAMIC: { - /* scaling arrays of panel width ratios for every widget */ - float ratio; - NK_ASSERT(layout->row.ratio); - ratio = (layout->row.ratio[layout->row.index] < 0) ? - layout->row.item_width : layout->row.ratio[layout->row.index]; - - item_spacing = (float)layout->row.index * spacing.x; - item_width = (ratio * panel_space); - item_offset = layout->row.item_offset; - - if (modify) { - layout->row.item_offset += item_width; - layout->row.filled += ratio; - } - } break; - case NK_LAYOUT_STATIC_FIXED: { - /* non-scaling fixed widgets item width */ - item_width = layout->row.item_width; - item_offset = (float)layout->row.index * item_width; - item_spacing = (float)layout->row.index * spacing.x; - } break; - case NK_LAYOUT_STATIC_ROW: { - /* scaling single ratio widget width */ - item_width = layout->row.item_width; - item_offset = layout->row.item_offset; - item_spacing = (float)layout->row.index * spacing.x; - if (modify) layout->row.item_offset += item_width; - } break; - case NK_LAYOUT_STATIC_FREE: { - /* free widget placing */ - bounds->x = layout->at_x + layout->row.item.x; - bounds->w = layout->row.item.w; - if (((bounds->x + bounds->w) > layout->max_x) && modify) - layout->max_x = (bounds->x + bounds->w); - bounds->x -= *layout->offset_x; - bounds->y = layout->at_y + layout->row.item.y; - bounds->y -= *layout->offset_y; - bounds->h = layout->row.item.h; - return; - }; - case NK_LAYOUT_STATIC: { - /* non-scaling array of panel pixel width for every widget */ - item_spacing = (float)layout->row.index * spacing.x; - item_width = layout->row.ratio[layout->row.index]; - item_offset = layout->row.item_offset; - if (modify) layout->row.item_offset += item_width; - } break; - default: NK_ASSERT(0); break; - }; - - /* set the bounds of the newly allocated widget */ - bounds->w = item_width; - bounds->h = layout->row.height - spacing.y; - bounds->y = layout->at_y - *layout->offset_y; - bounds->x = layout->at_x + item_offset + item_spacing + padding.x; - if (((bounds->x + bounds->w) > layout->max_x) && modify) - layout->max_x = bounds->x + bounds->w; - bounds->x -= *layout->offset_x; -} - -NK_INTERN void -nk_panel_alloc_space(struct nk_rect *bounds, const struct nk_context *ctx) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return; - - /* check if the end of the row has been hit and begin new row if so */ - win = ctx->current; - layout = win->layout; - if (layout->row.index >= layout->row.columns) - nk_panel_alloc_row(ctx, win); - - /* calculate widget position and size */ - nk_layout_widget_space(bounds, ctx, win, nk_true); - layout->row.index++; -} - -NK_INTERN void -nk_layout_peek(struct nk_rect *bounds, struct nk_context *ctx) -{ - float y; - int index; - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return; - - win = ctx->current; - layout = win->layout; - y = layout->at_y; - index = layout->row.index; - if (layout->row.index >= layout->row.columns) { - layout->at_y += layout->row.height; - layout->row.index = 0; - } - nk_layout_widget_space(bounds, ctx, win, nk_false); - layout->at_y = y; - layout->row.index = index; -} - -NK_INTERN int -nk_tree_state_base(struct nk_context *ctx, enum nk_tree_type type, - struct nk_image *img, const char *title, enum nk_collapse_states *state) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_style *style; - struct nk_command_buffer *out; - const struct nk_input *in; - const struct nk_style_button *button; - enum nk_symbol_type symbol; - - struct nk_vec2 item_spacing; - struct nk_rect header = {0,0,0,0}; - struct nk_rect sym = {0,0,0,0}; - struct nk_text text; - - nk_flags ws = 0; - enum nk_widget_layout_states widget_state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - /* cache some data */ - win = ctx->current; - layout = win->layout; - out = &win->buffer; - style = &ctx->style; - item_spacing = style->window.spacing; - - /* calculate header bounds and draw background */ - nk_layout_row_dynamic(ctx, style->font->height + 2 * style->tab.padding.y, 1); - widget_state = nk_widget(&header, ctx); - if (type == NK_TREE_TAB) { - const struct nk_style_item *background = &style->tab.background; - if (background->type == NK_STYLE_ITEM_IMAGE) { - nk_draw_image(out, header, &background->data.image, nk_white); - text.background = nk_rgba(0,0,0,0); - } else { - text.background = background->data.color; - nk_fill_rect(out, header, 0, style->tab.border_color); - nk_fill_rect(out, nk_shrink_rect(header, style->tab.border), - style->tab.rounding, background->data.color); - } - } else text.background = style->window.background; - - /* update node state */ - in = (!(layout->flags & NK_WINDOW_ROM)) ? &ctx->input: 0; - in = (in && widget_state == NK_WIDGET_VALID) ? &ctx->input : 0; - if (nk_button_behavior(&ws, header, in, NK_BUTTON_DEFAULT)) - *state = (*state == NK_MAXIMIZED) ? NK_MINIMIZED : NK_MAXIMIZED; - - /* select correct button style */ - if (*state == NK_MAXIMIZED) { - symbol = style->tab.sym_maximize; - if (type == NK_TREE_TAB) - button = &style->tab.tab_maximize_button; - else button = &style->tab.node_maximize_button; - } else { - symbol = style->tab.sym_minimize; - if (type == NK_TREE_TAB) - button = &style->tab.tab_minimize_button; - else button = &style->tab.node_minimize_button; - } - - {/* draw triangle button */ - sym.w = sym.h = style->font->height; - sym.y = header.y + style->tab.padding.y; - sym.x = header.x + style->tab.padding.x; - nk_do_button_symbol(&ws, &win->buffer, sym, symbol, NK_BUTTON_DEFAULT, - button, 0, style->font); - - if (img) { - /* draw optional image icon */ - sym.x = sym.x + sym.w + 4 * item_spacing.x; - nk_draw_image(&win->buffer, sym, img, nk_white); - sym.w = style->font->height + style->tab.spacing.x;} - } - - {/* draw label */ - struct nk_rect label; - header.w = NK_MAX(header.w, sym.w + item_spacing.x); - label.x = sym.x + sym.w + item_spacing.x; - label.y = sym.y; - label.w = header.w - (sym.w + item_spacing.y + style->tab.indent); - label.h = style->font->height; - text.text = style->tab.text; - text.padding = nk_vec2(0,0); - nk_widget_text(out, label, title, nk_strlen(title), &text, - NK_TEXT_LEFT, style->font);} - - /* increase x-axis cursor widget position pointer */ - if (*state == NK_MAXIMIZED) { - layout->at_x = header.x + *layout->offset_x + style->tab.indent; - layout->bounds.w = NK_MAX(layout->bounds.w, style->tab.indent); - layout->bounds.w -= (style->tab.indent + style->window.padding.x); - layout->row.tree_depth++; - return nk_true; - } else return nk_false; -} - -NK_INTERN int -nk_tree_base(struct nk_context *ctx, enum nk_tree_type type, - struct nk_image *img, const char *title, enum nk_collapse_states initial_state, - const char *hash, int len, int line) -{ - struct nk_window *win = ctx->current; - int title_len = 0; - nk_hash tree_hash = 0; - nk_uint *state = 0; - - /* retrieve tree state from internal widget state tables */ - if (!hash) { - title_len = (int)nk_strlen(title); - tree_hash = nk_murmur_hash(title, (int)title_len, (nk_hash)line); - } else tree_hash = nk_murmur_hash(hash, len, (nk_hash)line); - state = nk_find_value(win, tree_hash); - if (!state) { - state = nk_add_value(ctx, win, tree_hash, 0); - *state = initial_state; - } - return nk_tree_state_base(ctx, type, img, title, (enum nk_collapse_states*)state); -} - -NK_API int -nk_tree_state_push(struct nk_context *ctx, enum nk_tree_type type, - const char *title, enum nk_collapse_states *state) -{return nk_tree_state_base(ctx, type, 0, title, state);} - -NK_API int -nk_tree_state_image_push(struct nk_context *ctx, enum nk_tree_type type, - struct nk_image img, const char *title, enum nk_collapse_states *state) -{return nk_tree_state_base(ctx, type, &img, title, state);} - -NK_API void -nk_tree_state_pop(struct nk_context *ctx) -{ - struct nk_window *win = 0; - struct nk_panel *layout = 0; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return; - - win = ctx->current; - layout = win->layout; - layout->at_x -= ctx->style.tab.indent + ctx->style.window.padding.x; - layout->bounds.w += ctx->style.tab.indent + ctx->style.window.padding.x; - NK_ASSERT(layout->row.tree_depth); - layout->row.tree_depth--; -} - -NK_API int -nk_tree_push_hashed(struct nk_context *ctx, enum nk_tree_type type, - const char *title, enum nk_collapse_states initial_state, - const char *hash, int len, int line) -{return nk_tree_base(ctx, type, 0, title, initial_state, hash, len, line);} - -NK_API int -nk_tree_image_push_hashed(struct nk_context *ctx, enum nk_tree_type type, - struct nk_image img, const char *title, enum nk_collapse_states initial_state, - const char *hash, int len,int seed) -{return nk_tree_base(ctx, type, &img, title, initial_state, hash, len, seed);} - -NK_API void -nk_tree_pop(struct nk_context *ctx) -{nk_tree_state_pop(ctx);} - -/*---------------------------------------------------------------- - * - * WIDGETS - * - * --------------------------------------------------------------*/ -NK_API struct nk_rect -nk_widget_bounds(struct nk_context *ctx) -{ - struct nk_rect bounds; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) - return nk_rect(0,0,0,0); - nk_layout_peek(&bounds, ctx); - return bounds; -} - -NK_API struct nk_vec2 -nk_widget_position(struct nk_context *ctx) -{ - struct nk_rect bounds; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) - return nk_vec2(0,0); - - nk_layout_peek(&bounds, ctx); - return nk_vec2(bounds.x, bounds.y); -} - -NK_API struct nk_vec2 -nk_widget_size(struct nk_context *ctx) -{ - struct nk_rect bounds; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) - return nk_vec2(0,0); - - nk_layout_peek(&bounds, ctx); - return nk_vec2(bounds.w, bounds.h); -} - -NK_API float -nk_widget_width(struct nk_context *ctx) -{ - struct nk_rect bounds; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) - return 0; - - nk_layout_peek(&bounds, ctx); - return bounds.w; -} - -NK_API float -nk_widget_height(struct nk_context *ctx) -{ - struct nk_rect bounds; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) - return 0; - - nk_layout_peek(&bounds, ctx); - return bounds.h; -} - -NK_API int -nk_widget_is_hovered(struct nk_context *ctx) -{ - int ret; - struct nk_rect bounds; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) - return 0; - - nk_layout_peek(&bounds, ctx); - ret = (ctx->active == ctx->current); - ret = ret && nk_input_is_mouse_hovering_rect(&ctx->input, bounds); - return ret; -} - -NK_API int -nk_widget_is_mouse_clicked(struct nk_context *ctx, enum nk_buttons btn) -{ - int ret; - struct nk_rect bounds; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) - return 0; - - nk_layout_peek(&bounds, ctx); - ret = (ctx->active == ctx->current); - ret = ret && nk_input_mouse_clicked(&ctx->input, btn, bounds); - return ret; -} - -NK_API int -nk_widget_has_mouse_click_down(struct nk_context *ctx, enum nk_buttons btn, int down) -{ - int ret; - struct nk_rect bounds; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) - return 0; - - nk_layout_peek(&bounds, ctx); - ret = (ctx->active == ctx->current); - ret = ret && nk_input_has_mouse_click_down_in_rect(&ctx->input, btn, bounds, down); - return ret; -} - -NK_API enum nk_widget_layout_states -nk_widget(struct nk_rect *bounds, const struct nk_context *ctx) -{ - struct nk_rect *c = 0; - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return NK_WIDGET_INVALID; - - /* allocate space and check if the widget needs to be updated and drawn */ - nk_panel_alloc_space(bounds, ctx); - win = ctx->current; - layout = win->layout; - c = &layout->clip; - - /* if one of these triggers you forgot to add an `if` condition around either - a window, group, popup, combobox or contextual menu `begin` and `end` block. - Example: - if (nk_begin(...) {...} nk_end(...); or - if (nk_group_begin(...) { nk_group_end(...);} */ - NK_ASSERT(!(layout->flags & NK_WINDOW_MINIMIZED)); - NK_ASSERT(!(layout->flags & NK_WINDOW_HIDDEN)); - NK_ASSERT(!(layout->flags & NK_WINDOW_CLOSED)); - - /* need to convert to int here to remove floating point error */ - bounds->x = (float)((int)bounds->x); - bounds->y = (float)((int)bounds->y); - bounds->w = (float)((int)bounds->w); - bounds->h = (float)((int)bounds->h); - - if (!NK_INTERSECT(c->x, c->y, c->w, c->h, bounds->x, bounds->y, bounds->w, bounds->h)) - return NK_WIDGET_INVALID; - if (!NK_CONTAINS(bounds->x, bounds->y, bounds->w, bounds->h, c->x, c->y, c->w, c->h)) - return NK_WIDGET_ROM; - return NK_WIDGET_VALID; -} - -NK_API enum nk_widget_layout_states -nk_widget_fitting(struct nk_rect *bounds, struct nk_context *ctx, - struct nk_vec2 item_padding) -{ - /* update the bounds to stand without padding */ - struct nk_window *win; - struct nk_style *style; - struct nk_panel *layout; - enum nk_widget_layout_states state; - struct nk_vec2 panel_padding; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return NK_WIDGET_INVALID; - - win = ctx->current; - style = &ctx->style; - layout = win->layout; - state = nk_widget(bounds, ctx); - - panel_padding = nk_panel_get_padding(style, layout->type); - if (layout->row.index == 1) { - bounds->w += panel_padding.x; - bounds->x -= panel_padding.x; - } else bounds->x -= item_padding.x; - - if (layout->row.index == layout->row.columns) - bounds->w += panel_padding.x; - else bounds->w += item_padding.x; - return state; -} - -/*---------------------------------------------------------------- - * - * MISC - * - * --------------------------------------------------------------*/ -NK_API void -nk_spacing(struct nk_context *ctx, int cols) -{ - struct nk_window *win; - struct nk_panel *layout; - struct nk_rect nil; - int i, index, rows; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return; - - /* spacing over row boundaries */ - win = ctx->current; - layout = win->layout; - index = (layout->row.index + cols) % layout->row.columns; - rows = (layout->row.index + cols) / layout->row.columns; - if (rows) { - for (i = 0; i < rows; ++i) - nk_panel_alloc_row(ctx, win); - cols = index; - } - - /* non table layout need to allocate space */ - if (layout->row.type != NK_LAYOUT_DYNAMIC_FIXED && - layout->row.type != NK_LAYOUT_STATIC_FIXED) { - for (i = 0; i < cols; ++i) - nk_panel_alloc_space(&nil, ctx); - } - layout->row.index = index; -} - -/*---------------------------------------------------------------- - * - * TEXT - * - * --------------------------------------------------------------*/ -NK_API void -nk_text_colored(struct nk_context *ctx, const char *str, int len, - nk_flags alignment, struct nk_color color) -{ - struct nk_window *win; - const struct nk_style *style; - - struct nk_vec2 item_padding; - struct nk_rect bounds; - struct nk_text text; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) return; - - win = ctx->current; - style = &ctx->style; - nk_panel_alloc_space(&bounds, ctx); - item_padding = style->text.padding; - - text.padding.x = item_padding.x; - text.padding.y = item_padding.y; - text.background = style->window.background; - text.text = color; - nk_widget_text(&win->buffer, bounds, str, len, &text, alignment, style->font); -} - -NK_API void -nk_text_wrap_colored(struct nk_context *ctx, const char *str, - int len, struct nk_color color) -{ - struct nk_window *win; - const struct nk_style *style; - - struct nk_vec2 item_padding; - struct nk_rect bounds; - struct nk_text text; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) return; - - win = ctx->current; - style = &ctx->style; - nk_panel_alloc_space(&bounds, ctx); - item_padding = style->text.padding; - - text.padding.x = item_padding.x; - text.padding.y = item_padding.y; - text.background = style->window.background; - text.text = color; - nk_widget_text_wrap(&win->buffer, bounds, str, len, &text, style->font); -} - -#ifdef NK_INCLUDE_STANDARD_VARARGS -NK_API void -nk_labelf_colored(struct nk_context *ctx, nk_flags flags, - struct nk_color color, const char *fmt, ...) -{ - char buf[256]; - va_list args; - va_start(args, fmt); - nk_strfmt(buf, NK_LEN(buf), fmt, args); - nk_label_colored(ctx, buf, flags, color); - va_end(args); -} - -NK_API void -nk_labelf_colored_wrap(struct nk_context *ctx, struct nk_color color, - const char *fmt, ...) -{ - char buf[256]; - va_list args; - va_start(args, fmt); - nk_strfmt(buf, NK_LEN(buf), fmt, args); - nk_label_colored_wrap(ctx, buf, color); - va_end(args); -} - -NK_API void -nk_labelf(struct nk_context *ctx, nk_flags flags, const char *fmt, ...) -{ - char buf[256]; - va_list args; - va_start(args, fmt); - nk_strfmt(buf, NK_LEN(buf), fmt, args); - nk_label(ctx, buf, flags); - va_end(args); -} - -NK_API void -nk_labelf_wrap(struct nk_context *ctx, const char *fmt,...) -{ - char buf[256]; - va_list args; - va_start(args, fmt); - nk_strfmt(buf, NK_LEN(buf), fmt, args); - nk_label_wrap(ctx, buf); - va_end(args); -} - -NK_API void -nk_value_bool(struct nk_context *ctx, const char *prefix, int value) -{nk_labelf(ctx, NK_TEXT_LEFT, "%s: %s", prefix, ((value) ? "true": "false"));} - -NK_API void -nk_value_int(struct nk_context *ctx, const char *prefix, int value) -{nk_labelf(ctx, NK_TEXT_LEFT, "%s: %d", prefix, value);} - -NK_API void -nk_value_uint(struct nk_context *ctx, const char *prefix, unsigned int value) -{nk_labelf(ctx, NK_TEXT_LEFT, "%s: %u", prefix, value);} - -NK_API void -nk_value_float(struct nk_context *ctx, const char *prefix, float value) -{ - double double_value = (double)value; - nk_labelf(ctx, NK_TEXT_LEFT, "%s: %.3f", prefix, double_value); -} - -NK_API void -nk_value_color_byte(struct nk_context *ctx, const char *p, struct nk_color c) -{nk_labelf(ctx, NK_TEXT_LEFT, "%s: (%d, %d, %d, %d)", p, c.r, c.g, c.b, c.a);} - -NK_API void -nk_value_color_float(struct nk_context *ctx, const char *p, struct nk_color color) -{ - double c[4]; nk_color_dv(c, color); - nk_labelf(ctx, NK_TEXT_LEFT, "%s: (%.2f, %.2f, %.2f, %.2f)", - p, c[0], c[1], c[2], c[3]); -} - -NK_API void -nk_value_color_hex(struct nk_context *ctx, const char *prefix, struct nk_color color) -{ - char hex[16]; - nk_color_hex_rgba(hex, color); - nk_labelf(ctx, NK_TEXT_LEFT, "%s: %s", prefix, hex); -} -#endif - -NK_API void -nk_text(struct nk_context *ctx, const char *str, int len, nk_flags alignment) -{ - NK_ASSERT(ctx); - if (!ctx) return; - nk_text_colored(ctx, str, len, alignment, ctx->style.text.color); -} - -NK_API void -nk_text_wrap(struct nk_context *ctx, const char *str, int len) -{ - NK_ASSERT(ctx); - if (!ctx) return; - nk_text_wrap_colored(ctx, str, len, ctx->style.text.color); -} - -NK_API void -nk_label(struct nk_context *ctx, const char *str, nk_flags alignment) -{nk_text(ctx, str, nk_strlen(str), alignment);} - -NK_API void -nk_label_colored(struct nk_context *ctx, const char *str, nk_flags align, - struct nk_color color) -{nk_text_colored(ctx, str, nk_strlen(str), align, color);} - -NK_API void -nk_label_wrap(struct nk_context *ctx, const char *str) -{nk_text_wrap(ctx, str, nk_strlen(str));} - -NK_API void -nk_label_colored_wrap(struct nk_context *ctx, const char *str, struct nk_color color) -{nk_text_wrap_colored(ctx, str, nk_strlen(str), color);} - -NK_API void -nk_image(struct nk_context *ctx, struct nk_image img) -{ - struct nk_window *win; - struct nk_rect bounds; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) return; - - win = ctx->current; - if (!nk_widget(&bounds, ctx)) return; - nk_draw_image(&win->buffer, bounds, &img, nk_white); -} - -/*---------------------------------------------------------------- - * - * BUTTON - * - * --------------------------------------------------------------*/ -NK_API void -nk_button_set_behavior(struct nk_context *ctx, enum nk_button_behavior behavior) -{ - NK_ASSERT(ctx); - if (!ctx) return; - ctx->button_behavior = behavior; -} - -NK_API int -nk_button_push_behavior(struct nk_context *ctx, enum nk_button_behavior behavior) -{ - struct nk_config_stack_button_behavior *button_stack; - struct nk_config_stack_button_behavior_element *element; - - NK_ASSERT(ctx); - if (!ctx) return 0; - - button_stack = &ctx->stacks.button_behaviors; - NK_ASSERT(button_stack->head < (int)NK_LEN(button_stack->elements)); - if (button_stack->head >= (int)NK_LEN(button_stack->elements)) - return 0; - - element = &button_stack->elements[button_stack->head++]; - element->address = &ctx->button_behavior; - element->old_value = ctx->button_behavior; - ctx->button_behavior = behavior; - return 1; -} - -NK_API int -nk_button_pop_behavior(struct nk_context *ctx) -{ - struct nk_config_stack_button_behavior *button_stack; - struct nk_config_stack_button_behavior_element *element; - - NK_ASSERT(ctx); - if (!ctx) return 0; - - button_stack = &ctx->stacks.button_behaviors; - NK_ASSERT(button_stack->head > 0); - if (button_stack->head < 1) - return 0; - - element = &button_stack->elements[--button_stack->head]; - *element->address = element->old_value; - return 1; -} - -NK_API int -nk_button_text_styled(struct nk_context *ctx, - const struct nk_style_button *style, const char *title, int len) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(style); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!style || !ctx || !ctx->current || !ctx->current->layout) return 0; - - win = ctx->current; - layout = win->layout; - state = nk_widget(&bounds, ctx); - - if (!state) return 0; - in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - return nk_do_button_text(&ctx->last_widget_state, &win->buffer, bounds, - title, len, style->text_alignment, ctx->button_behavior, - style, in, ctx->style.font); -} - -NK_API int -nk_button_text(struct nk_context *ctx, const char *title, int len) -{ - NK_ASSERT(ctx); - if (!ctx) return 0; - return nk_button_text_styled(ctx, &ctx->style.button, title, len); -} - -NK_API int nk_button_label_styled(struct nk_context *ctx, - const struct nk_style_button *style, const char *title) -{return nk_button_text_styled(ctx, style, title, nk_strlen(title));} - -NK_API int nk_button_label(struct nk_context *ctx, const char *title) -{return nk_button_text(ctx, title, nk_strlen(title));} - -NK_API int -nk_button_color(struct nk_context *ctx, struct nk_color color) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - struct nk_style_button button; - - int ret = 0; - struct nk_rect bounds; - struct nk_rect content; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - layout = win->layout; - - state = nk_widget(&bounds, ctx); - if (!state) return 0; - in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - - button = ctx->style.button; - button.normal = nk_style_item_color(color); - button.hover = nk_style_item_color(color); - button.active = nk_style_item_color(color); - ret = nk_do_button(&ctx->last_widget_state, &win->buffer, bounds, - &button, in, ctx->button_behavior, &content); - nk_draw_button(&win->buffer, &bounds, ctx->last_widget_state, &button); - return ret; -} - -NK_API int -nk_button_symbol_styled(struct nk_context *ctx, - const struct nk_style_button *style, enum nk_symbol_type symbol) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - layout = win->layout; - state = nk_widget(&bounds, ctx); - if (!state) return 0; - in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - return nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, bounds, - symbol, ctx->button_behavior, style, in, ctx->style.font); -} - -NK_API int -nk_button_symbol(struct nk_context *ctx, enum nk_symbol_type symbol) -{ - NK_ASSERT(ctx); - if (!ctx) return 0; - return nk_button_symbol_styled(ctx, &ctx->style.button, symbol); -} - -NK_API int -nk_button_image_styled(struct nk_context *ctx, const struct nk_style_button *style, - struct nk_image img) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - layout = win->layout; - - state = nk_widget(&bounds, ctx); - if (!state) return 0; - in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - return nk_do_button_image(&ctx->last_widget_state, &win->buffer, bounds, - img, ctx->button_behavior, style, in); -} - -NK_API int -nk_button_image(struct nk_context *ctx, struct nk_image img) -{ - NK_ASSERT(ctx); - if (!ctx) return 0; - return nk_button_image_styled(ctx, &ctx->style.button, img); -} - -NK_API int -nk_button_symbol_text_styled(struct nk_context *ctx, - const struct nk_style_button *style, enum nk_symbol_type symbol, - const char *text, int len, nk_flags align) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - layout = win->layout; - - state = nk_widget(&bounds, ctx); - if (!state) return 0; - in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - return nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, bounds, - symbol, text, len, align, ctx->button_behavior, - style, ctx->style.font, in); -} - -NK_API int -nk_button_symbol_text(struct nk_context *ctx, enum nk_symbol_type symbol, - const char* text, int len, nk_flags align) -{ - NK_ASSERT(ctx); - if (!ctx) return 0; - return nk_button_symbol_text_styled(ctx, &ctx->style.button, symbol, text, len, align); -} - -NK_API int nk_button_symbol_label(struct nk_context *ctx, enum nk_symbol_type symbol, - const char *label, nk_flags align) -{return nk_button_symbol_text(ctx, symbol, label, nk_strlen(label), align);} - -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) -{return nk_button_symbol_text_styled(ctx, style, symbol, title, nk_strlen(title), align);} - -NK_API int -nk_button_image_text_styled(struct nk_context *ctx, - const struct nk_style_button *style, struct nk_image img, const char *text, - int len, nk_flags align) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - layout = win->layout; - - state = nk_widget(&bounds, ctx); - if (!state) return 0; - in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - return nk_do_button_text_image(&ctx->last_widget_state, &win->buffer, - bounds, img, text, len, align, ctx->button_behavior, - style, ctx->style.font, in); -} - -NK_API int -nk_button_image_text(struct nk_context *ctx, struct nk_image img, - const char *text, int len, nk_flags align) -{return nk_button_image_text_styled(ctx, &ctx->style.button,img, text, len, align);} - - -NK_API int nk_button_image_label(struct nk_context *ctx, struct nk_image img, - const char *label, nk_flags align) -{return nk_button_image_text(ctx, img, label, nk_strlen(label), align);} - -NK_API int nk_button_image_label_styled(struct nk_context *ctx, - const struct nk_style_button *style, struct nk_image img, - const char *label, nk_flags text_alignment) -{return nk_button_image_text_styled(ctx, style, img, label, nk_strlen(label), text_alignment);} - -/*---------------------------------------------------------------- - * - * SELECTABLE - * - * --------------------------------------------------------------*/ -NK_API int -nk_selectable_text(struct nk_context *ctx, const char *str, int len, - nk_flags align, int *value) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - const struct nk_style *style; - - enum nk_widget_layout_states state; - struct nk_rect bounds; - - NK_ASSERT(ctx); - NK_ASSERT(value); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout || !value) - return 0; - - win = ctx->current; - layout = win->layout; - style = &ctx->style; - - state = nk_widget(&bounds, ctx); - if (!state) return 0; - in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - return nk_do_selectable(&ctx->last_widget_state, &win->buffer, bounds, - str, len, align, value, &style->selectable, in, style->font); -} - -NK_API int -nk_selectable_image_text(struct nk_context *ctx, struct nk_image img, - const char *str, int len, nk_flags align, int *value) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - const struct nk_style *style; - - enum nk_widget_layout_states state; - struct nk_rect bounds; - - NK_ASSERT(ctx); - NK_ASSERT(value); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout || !value) - return 0; - - win = ctx->current; - layout = win->layout; - style = &ctx->style; - - state = nk_widget(&bounds, ctx); - if (!state) return 0; - in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - return nk_do_selectable_image(&ctx->last_widget_state, &win->buffer, bounds, - str, len, align, value, &img, &style->selectable, in, style->font); -} - -NK_API int nk_select_text(struct nk_context *ctx, const char *str, int len, - nk_flags align, int value) -{nk_selectable_text(ctx, str, len, align, &value);return value;} - -NK_API int nk_selectable_label(struct nk_context *ctx, const char *str, nk_flags align, int *value) -{return nk_selectable_text(ctx, str, nk_strlen(str), align, value);} - -NK_API int nk_selectable_image_label(struct nk_context *ctx,struct nk_image img, - const char *str, nk_flags align, int *value) -{return nk_selectable_image_text(ctx, img, str, nk_strlen(str), align, value);} - -NK_API int nk_select_label(struct nk_context *ctx, const char *str, nk_flags align, int value) -{nk_selectable_text(ctx, str, nk_strlen(str), align, &value);return value;} - -NK_API int nk_select_image_label(struct nk_context *ctx, struct nk_image img, - const char *str, nk_flags align, int value) -{nk_selectable_image_text(ctx, img, str, nk_strlen(str), align, &value);return value;} - -NK_API int nk_select_image_text(struct nk_context *ctx, struct nk_image img, - const char *str, int len, nk_flags align, int value) -{nk_selectable_image_text(ctx, img, str, len, align, &value);return value;} - -/*---------------------------------------------------------------- - * - * CHECKBOX - * - * --------------------------------------------------------------*/ -NK_API int -nk_check_text(struct nk_context *ctx, const char *text, int len, int active) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - const struct nk_style *style; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return active; - - win = ctx->current; - style = &ctx->style; - layout = win->layout; - - state = nk_widget(&bounds, ctx); - if (!state) return active; - in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &active, - text, len, NK_TOGGLE_CHECK, &style->checkbox, in, style->font); - return active; -} - -NK_API unsigned int -nk_check_flags_text(struct nk_context *ctx, const char *text, int len, - unsigned int flags, unsigned int value) -{ - int old_active; - NK_ASSERT(ctx); - NK_ASSERT(text); - if (!ctx || !text) return flags; - old_active = (int)((flags & value) & value); - if (nk_check_text(ctx, text, len, old_active)) - flags |= value; - else flags &= ~value; - return flags; -} - -NK_API int -nk_checkbox_text(struct nk_context *ctx, const char *text, int len, int *active) -{ - int old_val; - NK_ASSERT(ctx); - NK_ASSERT(text); - NK_ASSERT(active); - if (!ctx || !text || !active) return 0; - old_val = *active; - *active = nk_check_text(ctx, text, len, *active); - return old_val != *active; -} - -NK_API int -nk_checkbox_flags_text(struct nk_context *ctx, const char *text, int len, - unsigned int *flags, unsigned int value) -{ - int active; - NK_ASSERT(ctx); - NK_ASSERT(text); - NK_ASSERT(flags); - if (!ctx || !text || !flags) return 0; - - active = (int)((*flags & value) & value); - if (nk_checkbox_text(ctx, text, len, &active)) { - if (active) *flags |= value; - else *flags &= ~value; - return 1; - } - return 0; -} - -NK_API int nk_check_label(struct nk_context *ctx, const char *label, int active) -{return nk_check_text(ctx, label, nk_strlen(label), active);} - -NK_API unsigned int nk_check_flags_label(struct nk_context *ctx, const char *label, - unsigned int flags, unsigned int value) -{return nk_check_flags_text(ctx, label, nk_strlen(label), flags, value);} - -NK_API int nk_checkbox_label(struct nk_context *ctx, const char *label, int *active) -{return nk_checkbox_text(ctx, label, nk_strlen(label), active);} - -NK_API int nk_checkbox_flags_label(struct nk_context *ctx, const char *label, - unsigned int *flags, unsigned int value) -{return nk_checkbox_flags_text(ctx, label, nk_strlen(label), flags, value);} - -/*---------------------------------------------------------------- - * - * OPTION - * - * --------------------------------------------------------------*/ -NK_API int -nk_option_text(struct nk_context *ctx, const char *text, int len, int is_active) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - const struct nk_style *style; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return is_active; - - win = ctx->current; - style = &ctx->style; - layout = win->layout; - - state = nk_widget(&bounds, ctx); - if (!state) return state; - in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &is_active, - text, len, NK_TOGGLE_OPTION, &style->option, in, style->font); - return is_active; -} - -NK_API int -nk_radio_text(struct nk_context *ctx, const char *text, int len, int *active) -{ - int old_value; - NK_ASSERT(ctx); - NK_ASSERT(text); - NK_ASSERT(active); - if (!ctx || !text || !active) return 0; - old_value = *active; - *active = nk_option_text(ctx, text, len, old_value); - return old_value != *active; -} - -NK_API int -nk_option_label(struct nk_context *ctx, const char *label, int active) -{return nk_option_text(ctx, label, nk_strlen(label), active);} - -NK_API int -nk_radio_label(struct nk_context *ctx, const char *label, int *active) -{return nk_radio_text(ctx, label, nk_strlen(label), active);} - -/*---------------------------------------------------------------- - * - * SLIDER - * - * --------------------------------------------------------------*/ -NK_API int -nk_slider_float(struct nk_context *ctx, float min_value, float *value, float max_value, - float value_step) -{ - struct nk_window *win; - struct nk_panel *layout; - struct nk_input *in; - const struct nk_style *style; - - int ret = 0; - float old_value; - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - NK_ASSERT(value); - if (!ctx || !ctx->current || !ctx->current->layout || !value) - return ret; - - win = ctx->current; - style = &ctx->style; - layout = win->layout; - - state = nk_widget(&bounds, ctx); - if (!state) return ret; - in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - - old_value = *value; - *value = nk_do_slider(&ctx->last_widget_state, &win->buffer, bounds, min_value, - old_value, max_value, value_step, &style->slider, in, style->font); - return (old_value > *value || old_value < *value); -} - -NK_API float -nk_slide_float(struct nk_context *ctx, float min, float val, float max, float step) -{ - nk_slider_float(ctx, min, &val, max, step); return val; -} - -NK_API int -nk_slide_int(struct nk_context *ctx, int min, int val, int max, int step) -{ - float value = (float)val; - nk_slider_float(ctx, (float)min, &value, (float)max, (float)step); - return (int)value; -} - -NK_API int -nk_slider_int(struct nk_context *ctx, int min, int *val, int max, int step) -{ - int ret; - float value = (float)*val; - ret = nk_slider_float(ctx, (float)min, &value, (float)max, (float)step); - *val = (int)value; - return ret; -} - -/*---------------------------------------------------------------- - * - * PROGRESSBAR - * - * --------------------------------------------------------------*/ -NK_API int -nk_progress(struct nk_context *ctx, nk_size *cur, nk_size max, int is_modifyable) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_style *style; - const struct nk_input *in; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - nk_size old_value; - - NK_ASSERT(ctx); - NK_ASSERT(cur); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout || !cur) - return 0; - - win = ctx->current; - style = &ctx->style; - layout = win->layout; - state = nk_widget(&bounds, ctx); - if (!state) return 0; - - in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - old_value = *cur; - *cur = nk_do_progress(&ctx->last_widget_state, &win->buffer, bounds, - *cur, max, is_modifyable, &style->progress, in); - return (*cur != old_value); -} - -NK_API nk_size nk_prog(struct nk_context *ctx, nk_size cur, nk_size max, int modifyable) -{nk_progress(ctx, &cur, max, modifyable);return cur;} - -/*---------------------------------------------------------------- - * - * EDIT - * - * --------------------------------------------------------------*/ -NK_API void -nk_edit_focus(struct nk_context *ctx, nk_flags flags) -{ - nk_hash hash; - struct nk_window *win; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) return; - - win = ctx->current; - hash = win->edit.seq; - win->edit.active = nk_true; - win->edit.name = hash; - if (flags & NK_EDIT_ALWAYS_INSERT_MODE) - win->edit.mode = NK_TEXT_EDIT_MODE_INSERT; -} - -NK_API nk_flags -nk_edit_string(struct nk_context *ctx, nk_flags flags, - char *memory, int *len, int max, nk_plugin_filter filter) -{ - nk_hash hash; - nk_flags state; - struct nk_text_edit *edit; - struct nk_window *win; - - NK_ASSERT(ctx); - NK_ASSERT(memory); - NK_ASSERT(len); - if (!ctx || !memory || !len) - return 0; - - filter = (!filter) ? nk_filter_default: filter; - win = ctx->current; - hash = win->edit.seq; - edit = &ctx->text_edit; - nk_textedit_clear_state(&ctx->text_edit, (flags & NK_EDIT_MULTILINE)? - NK_TEXT_EDIT_MULTI_LINE: NK_TEXT_EDIT_SINGLE_LINE, filter); - - if (win->edit.active && hash == win->edit.name) { - if (flags & NK_EDIT_NO_CURSOR) - edit->cursor = nk_utf_len(memory, *len); - else edit->cursor = win->edit.cursor; - if (!(flags & NK_EDIT_SELECTABLE)) { - edit->select_start = win->edit.cursor; - edit->select_end = win->edit.cursor; - } else { - edit->select_start = win->edit.sel_start; - edit->select_end = win->edit.sel_end; - } - edit->mode = win->edit.mode; - edit->scrollbar.x = (float)win->edit.scrollbar.x; - edit->scrollbar.y = (float)win->edit.scrollbar.y; - edit->active = nk_true; - } else edit->active = nk_false; - - max = NK_MAX(1, max); - *len = NK_MIN(*len, max-1); - nk_str_init_fixed(&edit->string, memory, (nk_size)max); - edit->string.buffer.allocated = (nk_size)*len; - edit->string.len = nk_utf_len(memory, *len); - state = nk_edit_buffer(ctx, flags, edit, filter); - *len = (int)edit->string.buffer.allocated; - - if (edit->active) { - win->edit.cursor = edit->cursor; - win->edit.sel_start = edit->select_start; - win->edit.sel_end = edit->select_end; - win->edit.mode = edit->mode; - win->edit.scrollbar.x = (nk_ushort)edit->scrollbar.x; - win->edit.scrollbar.y = (nk_ushort)edit->scrollbar.y; - } - return state; -} - -NK_API nk_flags -nk_edit_buffer(struct nk_context *ctx, nk_flags flags, - struct nk_text_edit *edit, nk_plugin_filter filter) -{ - struct nk_window *win; - struct nk_style *style; - struct nk_input *in; - - enum nk_widget_layout_states state; - struct nk_rect bounds; - - nk_flags ret_flags = 0; - unsigned char prev_state; - nk_hash hash; - - /* make sure correct values */ - NK_ASSERT(ctx); - NK_ASSERT(edit); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - style = &ctx->style; - state = nk_widget(&bounds, ctx); - if (!state) return state; - in = (win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - - /* check if edit is currently hot item */ - hash = win->edit.seq++; - if (win->edit.active && hash == win->edit.name) { - if (flags & NK_EDIT_NO_CURSOR) - edit->cursor = edit->string.len; - if (!(flags & NK_EDIT_SELECTABLE)) { - edit->select_start = edit->cursor; - edit->select_end = edit->cursor; - } - if (flags & NK_EDIT_CLIPBOARD) - edit->clip = ctx->clip; - } - - filter = (!filter) ? nk_filter_default: filter; - prev_state = (unsigned char)edit->active; - in = (flags & NK_EDIT_READ_ONLY) ? 0: in; - ret_flags = nk_do_edit(&ctx->last_widget_state, &win->buffer, bounds, flags, - filter, edit, &style->edit, in, style->font); - - if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) - ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_TEXT]; - if (edit->active && prev_state != edit->active) { - /* current edit is now hot */ - win->edit.active = nk_true; - win->edit.name = hash; - } else if (prev_state && !edit->active) { - /* current edit is now cold */ - win->edit.active = nk_false; - } - return ret_flags; -} - -NK_API nk_flags -nk_edit_string_zero_terminated(struct nk_context *ctx, nk_flags flags, - char *buffer, int max, nk_plugin_filter filter) -{ - nk_flags result; - int len = nk_strlen(buffer); - result = nk_edit_string(ctx, flags, buffer, &len, max, filter); - buffer[NK_MIN(NK_MAX(max-1,0), len)] = '\0'; - return result; -} - -/*---------------------------------------------------------------- - * - * PROPERTY - * - * --------------------------------------------------------------*/ -NK_INTERN struct nk_property_variant -nk_property_variant_int(int value, int min_value, int max_value, int step) -{ - struct nk_property_variant result; - result.kind = NK_PROPERTY_INT; - result.value.i = value; - result.min_value.i = min_value; - result.max_value.i = max_value; - result.step.i = step; - return result; -} - -NK_INTERN struct nk_property_variant -nk_property_variant_float(float value, float min_value, float max_value, float step) -{ - struct nk_property_variant result; - result.kind = NK_PROPERTY_FLOAT; - result.value.f = value; - result.min_value.f = min_value; - result.max_value.f = max_value; - result.step.f = step; - return result; -} - -NK_INTERN struct nk_property_variant -nk_property_variant_double(double value, double min_value, double max_value, - double step) -{ - struct nk_property_variant result; - result.kind = NK_PROPERTY_DOUBLE; - result.value.d = value; - result.min_value.d = min_value; - result.max_value.d = max_value; - result.step.d = step; - return result; -} - -NK_INTERN 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) -{ - struct nk_window *win; - struct nk_panel *layout; - struct nk_input *in; - const struct nk_style *style; - - struct nk_rect bounds; - enum nk_widget_layout_states s; - - int *state = 0; - nk_hash hash = 0; - char *buffer = 0; - int *len = 0; - int *cursor = 0; - int old_state; - - char dummy_buffer[NK_MAX_NUMBER_BUFFER]; - int dummy_state = NK_PROPERTY_DEFAULT; - int dummy_length = 0; - int dummy_cursor = 0; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return; - - win = ctx->current; - layout = win->layout; - style = &ctx->style; - s = nk_widget(&bounds, ctx); - if (!s) return; - in = (s == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - - /* calculate hash from name */ - if (name[0] == '#') { - hash = nk_murmur_hash(name, (int)nk_strlen(name), win->property.seq++); - name++; /* special number hash */ - } else hash = nk_murmur_hash(name, (int)nk_strlen(name), 42); - - /* check if property is currently hot item */ - if (win->property.active && hash == win->property.name) { - buffer = win->property.buffer; - len = &win->property.length; - cursor = &win->property.cursor; - state = &win->property.state; - } else { - buffer = dummy_buffer; - len = &dummy_length; - cursor = &dummy_cursor; - state = &dummy_state; - } - - /* execute property widget */ - old_state = *state; - nk_do_property(&ctx->last_widget_state, &win->buffer, bounds, name, - variant, inc_per_pixel, buffer, len, state, cursor, - &style->property, filter, in, style->font, &ctx->text_edit); - - if (in && *state != NK_PROPERTY_DEFAULT && !win->property.active) { - /* current property is now hot */ - win->property.active = 1; - NK_MEMCPY(win->property.buffer, buffer, (nk_size)*len); - win->property.length = *len; - win->property.cursor = *cursor; - win->property.state = *state; - win->property.name = hash; - if (*state == NK_PROPERTY_DRAG) { - ctx->input.mouse.grab = nk_true; - ctx->input.mouse.grabbed = nk_true; - } - } - - /* check if previously active property is now inactive */ - if (*state == NK_PROPERTY_DEFAULT && old_state != NK_PROPERTY_DEFAULT) { - if (old_state == NK_PROPERTY_DRAG) { - ctx->input.mouse.grab = nk_false; - ctx->input.mouse.grabbed = nk_false; - ctx->input.mouse.ungrab = nk_true; - } - win->property.active = 0; - } -} - -NK_API void -nk_property_int(struct nk_context *ctx, const char *name, - int min, int *val, int max, int step, float inc_per_pixel) -{ - struct nk_property_variant variant; - NK_ASSERT(ctx); - NK_ASSERT(name); - NK_ASSERT(val); - - if (!ctx || !ctx->current || !name || !val) return; - variant = nk_property_variant_int(*val, min, max, step); - nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_INT); - *val = variant.value.i; -} - -NK_API void -nk_property_float(struct nk_context *ctx, const char *name, - float min, float *val, float max, float step, float inc_per_pixel) -{ - struct nk_property_variant variant; - NK_ASSERT(ctx); - NK_ASSERT(name); - NK_ASSERT(val); - - if (!ctx || !ctx->current || !name || !val) return; - variant = nk_property_variant_float(*val, min, max, step); - nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT); - *val = variant.value.f; -} - -NK_API void -nk_property_double(struct nk_context *ctx, const char *name, - double min, double *val, double max, double step, float inc_per_pixel) -{ - struct nk_property_variant variant; - NK_ASSERT(ctx); - NK_ASSERT(name); - NK_ASSERT(val); - - if (!ctx || !ctx->current || !name || !val) return; - variant = nk_property_variant_double(*val, min, max, step); - nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT); - *val = variant.value.d; -} - -NK_API int -nk_propertyi(struct nk_context *ctx, const char *name, int min, int val, - int max, int step, float inc_per_pixel) -{ - struct nk_property_variant variant; - NK_ASSERT(ctx); - NK_ASSERT(name); - - if (!ctx || !ctx->current || !name) return val; - variant = nk_property_variant_int(val, min, max, step); - nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_INT); - val = variant.value.i; - return val; -} - -NK_API float -nk_propertyf(struct nk_context *ctx, const char *name, float min, - float val, float max, float step, float inc_per_pixel) -{ - struct nk_property_variant variant; - NK_ASSERT(ctx); - NK_ASSERT(name); - - if (!ctx || !ctx->current || !name) return val; - variant = nk_property_variant_float(val, min, max, step); - nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT); - val = variant.value.f; - return val; -} - -NK_API double -nk_propertyd(struct nk_context *ctx, const char *name, double min, - double val, double max, double step, float inc_per_pixel) -{ - struct nk_property_variant variant; - NK_ASSERT(ctx); - NK_ASSERT(name); - - if (!ctx || !ctx->current || !name) return val; - variant = nk_property_variant_double(val, min, max, step); - nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT); - val = variant.value.d; - return val; -} - -/*---------------------------------------------------------------- - * - * COLOR PICKER - * - * --------------------------------------------------------------*/ -NK_API int -nk_color_pick(struct nk_context * ctx, struct nk_color *color, - enum nk_color_format fmt) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_style *config; - const struct nk_input *in; - - enum nk_widget_layout_states state; - struct nk_rect bounds; - - NK_ASSERT(ctx); - NK_ASSERT(color); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout || !color) - return 0; - - win = ctx->current; - config = &ctx->style; - layout = win->layout; - state = nk_widget(&bounds, ctx); - if (!state) return 0; - in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - return nk_do_color_picker(&ctx->last_widget_state, &win->buffer, color, fmt, bounds, - nk_vec2(0,0), in, config->font); -} - -NK_API struct nk_color -nk_color_picker(struct nk_context *ctx, struct nk_color color, - enum nk_color_format fmt) -{ - nk_color_pick(ctx, &color, fmt); - return color; -} - -/* ------------------------------------------------------------- - * - * CHART - * - * --------------------------------------------------------------*/ -NK_API int -nk_chart_begin_colored(struct nk_context *ctx, enum nk_chart_type type, - struct nk_color color, struct nk_color highlight, - int count, float min_value, float max_value) -{ - struct nk_window *win; - struct nk_chart *chart; - const struct nk_style *config; - const struct nk_style_chart *style; - - const struct nk_style_item *background; - struct nk_rect bounds = {0, 0, 0, 0}; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - - if (!ctx || !ctx->current || !ctx->current->layout) return 0; - if (!nk_widget(&bounds, ctx)) { - chart = &ctx->current->layout->chart; - nk_zero(chart, sizeof(*chart)); - return 0; - } - - win = ctx->current; - config = &ctx->style; - chart = &win->layout->chart; - style = &config->chart; - - /* setup basic generic chart */ - nk_zero(chart, sizeof(*chart)); - chart->x = bounds.x + style->padding.x; - chart->y = bounds.y + style->padding.y; - chart->w = bounds.w - 2 * style->padding.x; - chart->h = bounds.h - 2 * style->padding.y; - chart->w = NK_MAX(chart->w, 2 * style->padding.x); - chart->h = NK_MAX(chart->h, 2 * style->padding.y); - - /* add first slot into chart */ - {struct nk_chart_slot *slot = &chart->slots[chart->slot++]; - slot->type = type; - slot->count = count; - slot->color = color; - slot->highlight = highlight; - slot->min = NK_MIN(min_value, max_value); - slot->max = NK_MAX(min_value, max_value); - slot->range = slot->max - slot->min;} - - /* draw chart background */ - background = &style->background; - if (background->type == NK_STYLE_ITEM_IMAGE) { - nk_draw_image(&win->buffer, bounds, &background->data.image, nk_white); - } else { - nk_fill_rect(&win->buffer, bounds, style->rounding, style->border_color); - nk_fill_rect(&win->buffer, nk_shrink_rect(bounds, style->border), - style->rounding, style->background.data.color); - } - return 1; -} - -NK_API int -nk_chart_begin(struct nk_context *ctx, const enum nk_chart_type type, - int count, float min_value, float max_value) -{return nk_chart_begin_colored(ctx, type, ctx->style.chart.color, ctx->style.chart.selected_color, count, min_value, max_value);} - -NK_API void -nk_chart_add_slot_colored(struct nk_context *ctx, const enum nk_chart_type type, - struct nk_color color, struct nk_color highlight, - int count, float min_value, float max_value) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - NK_ASSERT(ctx->current->layout->chart.slot < NK_CHART_MAX_SLOT); - if (!ctx || !ctx->current || !ctx->current->layout) return; - if (ctx->current->layout->chart.slot >= NK_CHART_MAX_SLOT) return; - - /* add another slot into the graph */ - {struct nk_chart *chart = &ctx->current->layout->chart; - struct nk_chart_slot *slot = &chart->slots[chart->slot++]; - slot->type = type; - slot->count = count; - slot->color = color; - slot->highlight = highlight; - slot->min = NK_MIN(min_value, max_value); - slot->max = NK_MAX(min_value, max_value); - slot->range = slot->max - slot->min;} -} - -NK_API void -nk_chart_add_slot(struct nk_context *ctx, const enum nk_chart_type type, - int count, float min_value, float max_value) -{nk_chart_add_slot_colored(ctx, type, ctx->style.chart.color, ctx->style.chart.selected_color, count, min_value, max_value);} - -NK_INTERN nk_flags -nk_chart_push_line(struct nk_context *ctx, struct nk_window *win, - struct nk_chart *g, float value, int slot) -{ - struct nk_panel *layout = win->layout; - const struct nk_input *i = &ctx->input; - struct nk_command_buffer *out = &win->buffer; - - nk_flags ret = 0; - struct nk_vec2 cur; - struct nk_rect bounds; - struct nk_color color; - float step; - float range; - float ratio; - - NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT); - step = g->w / (float)g->slots[slot].count; - range = g->slots[slot].max - g->slots[slot].min; - ratio = (value - g->slots[slot].min) / range; - - if (g->slots[slot].index == 0) { - /* first data point does not have a connection */ - g->slots[slot].last.x = g->x; - g->slots[slot].last.y = (g->y + g->h) - ratio * (float)g->h; - - bounds.x = g->slots[slot].last.x - 2; - bounds.y = g->slots[slot].last.y - 2; - bounds.w = bounds.h = 4; - - color = g->slots[slot].color; - if (!(layout->flags & NK_WINDOW_ROM) && - NK_INBOX(i->mouse.pos.x,i->mouse.pos.y, g->slots[slot].last.x-3, g->slots[slot].last.y-3, 6, 6)){ - ret = nk_input_is_mouse_hovering_rect(i, bounds) ? NK_CHART_HOVERING : 0; - ret |= (i->mouse.buttons[NK_BUTTON_LEFT].down && - i->mouse.buttons[NK_BUTTON_LEFT].clicked) ? NK_CHART_CLICKED: 0; - color = g->slots[slot].highlight; - } - nk_fill_rect(out, bounds, 0, color); - g->slots[slot].index += 1; - return ret; - } - - /* draw a line between the last data point and the new one */ - color = g->slots[slot].color; - cur.x = g->x + (float)(step * (float)g->slots[slot].index); - cur.y = (g->y + g->h) - (ratio * (float)g->h); - nk_stroke_line(out, g->slots[slot].last.x, g->slots[slot].last.y, cur.x, cur.y, 1.0f, color); - - bounds.x = cur.x - 3; - bounds.y = cur.y - 3; - bounds.w = bounds.h = 6; - - /* user selection of current data point */ - if (!(layout->flags & NK_WINDOW_ROM)) { - if (nk_input_is_mouse_hovering_rect(i, bounds)) { - ret = NK_CHART_HOVERING; - ret |= (!i->mouse.buttons[NK_BUTTON_LEFT].down && - i->mouse.buttons[NK_BUTTON_LEFT].clicked) ? NK_CHART_CLICKED: 0; - color = g->slots[slot].highlight; - } - } - nk_fill_rect(out, nk_rect(cur.x - 2, cur.y - 2, 4, 4), 0, color); - - /* save current data point position */ - g->slots[slot].last.x = cur.x; - g->slots[slot].last.y = cur.y; - g->slots[slot].index += 1; - return ret; -} - -NK_INTERN nk_flags -nk_chart_push_column(const struct nk_context *ctx, struct nk_window *win, - struct nk_chart *chart, float value, int slot) -{ - struct nk_command_buffer *out = &win->buffer; - const struct nk_input *in = &ctx->input; - struct nk_panel *layout = win->layout; - - float ratio; - nk_flags ret = 0; - struct nk_color color; - struct nk_rect item = {0,0,0,0}; - - NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT); - if (chart->slots[slot].index >= chart->slots[slot].count) - return nk_false; - if (chart->slots[slot].count) { - float padding = (float)(chart->slots[slot].count-1); - item.w = (chart->w - padding) / (float)(chart->slots[slot].count); - } - - /* calculate bounds of current bar chart entry */ - color = chart->slots[slot].color;; - item.h = chart->h * NK_ABS((value/chart->slots[slot].range)); - if (value >= 0) { - ratio = (value + NK_ABS(chart->slots[slot].min)) / NK_ABS(chart->slots[slot].range); - item.y = (chart->y + chart->h) - chart->h * ratio; - } else { - ratio = (value - chart->slots[slot].max) / chart->slots[slot].range; - item.y = chart->y + (chart->h * NK_ABS(ratio)) - item.h; - } - item.x = chart->x + ((float)chart->slots[slot].index * item.w); - item.x = item.x + ((float)chart->slots[slot].index); - - /* user chart bar selection */ - if (!(layout->flags & NK_WINDOW_ROM) && - NK_INBOX(in->mouse.pos.x,in->mouse.pos.y,item.x,item.y,item.w,item.h)) { - ret = NK_CHART_HOVERING; - ret |= (!in->mouse.buttons[NK_BUTTON_LEFT].down && - in->mouse.buttons[NK_BUTTON_LEFT].clicked) ? NK_CHART_CLICKED: 0; - color = chart->slots[slot].highlight; - } - nk_fill_rect(out, item, 0, color); - chart->slots[slot].index += 1; - return ret; -} - -NK_API nk_flags -nk_chart_push_slot(struct nk_context *ctx, float value, int slot) -{ - nk_flags flags; - struct nk_window *win; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT); - NK_ASSERT(slot < ctx->current->layout->chart.slot); - if (!ctx || !ctx->current || slot >= NK_CHART_MAX_SLOT) return nk_false; - if (slot >= ctx->current->layout->chart.slot) return nk_false; - - win = ctx->current; - if (win->layout->chart.slot < slot) return nk_false; - switch (win->layout->chart.slots[slot].type) { - case NK_CHART_LINES: - flags = nk_chart_push_line(ctx, win, &win->layout->chart, value, slot); break; - case NK_CHART_COLUMN: - flags = nk_chart_push_column(ctx, win, &win->layout->chart, value, slot); break; - default: - case NK_CHART_MAX: - flags = 0; - } - return flags; -} - -NK_API nk_flags -nk_chart_push(struct nk_context *ctx, float value) -{return nk_chart_push_slot(ctx, value, 0);} - -NK_API void -nk_chart_end(struct nk_context *ctx) -{ - struct nk_window *win; - struct nk_chart *chart; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) - return; - - win = ctx->current; - chart = &win->layout->chart; - NK_MEMSET(chart, 0, sizeof(*chart)); - return; -} - -NK_API void -nk_plot(struct nk_context *ctx, enum nk_chart_type type, const float *values, - int count, int offset) -{ - int i = 0; - float min_value; - float max_value; - - NK_ASSERT(ctx); - NK_ASSERT(values); - if (!ctx || !values || !count) return; - - min_value = values[offset]; - max_value = values[offset]; - for (i = 0; i < count; ++i) { - min_value = NK_MIN(values[i + offset], min_value); - max_value = NK_MAX(values[i + offset], max_value); - } - nk_chart_begin(ctx, type, count, min_value, max_value); - for (i = 0; i < count; ++i) - nk_chart_push(ctx, values[i + offset]); - nk_chart_end(ctx); -} - -NK_API void -nk_plot_function(struct nk_context *ctx, enum nk_chart_type type, void *userdata, - float(*value_getter)(void* user, int index), int count, int offset) -{ - int i = 0; - float min_value; - float max_value; - - NK_ASSERT(ctx); - NK_ASSERT(value_getter); - if (!ctx || !value_getter || !count) return; - - max_value = min_value = value_getter(userdata, offset); - for (i = 0; i < count; ++i) { - float value = value_getter(userdata, i + offset); - min_value = NK_MIN(value, min_value); - max_value = NK_MAX(value, max_value); - } - nk_chart_begin(ctx, type, count, min_value, max_value); - for (i = 0; i < count; ++i) - nk_chart_push(ctx, value_getter(userdata, i + offset)); - nk_chart_end(ctx); -} - -/* ------------------------------------------------------------- - * - * GROUP - * - * --------------------------------------------------------------*/ -NK_API int -nk_group_scrolled_offset_begin(struct nk_context *ctx, - nk_uint *x_offset, nk_uint *y_offset, const char *title, nk_flags flags) -{ - struct nk_rect bounds; - struct nk_window panel; - struct nk_window *win; - - win = ctx->current; - nk_panel_alloc_space(&bounds, ctx); - - {const struct nk_rect *c = &win->layout->clip; - if (!NK_INTERSECT(c->x, c->y, c->w, c->h, bounds.x, bounds.y, bounds.w, bounds.h) && - !(flags & NK_WINDOW_MOVABLE)) { - return 0; - }} - if (win->flags & NK_WINDOW_ROM) - flags |= NK_WINDOW_ROM; - - /* initialize a fake window to create the layout from */ - nk_zero(&panel, sizeof(panel)); - panel.bounds = bounds; - panel.flags = flags; - panel.scrollbar.x = *x_offset; - panel.scrollbar.y = *y_offset; - panel.buffer = win->buffer; - panel.layout = (struct nk_panel*)nk_create_panel(ctx); - ctx->current = &panel; - nk_panel_begin(ctx, (flags & NK_WINDOW_TITLE) ? title: 0, NK_PANEL_GROUP); - - win->buffer = panel.buffer; - win->buffer.clip = panel.layout->clip; - panel.layout->offset_x = x_offset; - panel.layout->offset_y = y_offset; - panel.layout->parent = win->layout; - win->layout = panel.layout; - ctx->current = win; - return 1; - -} - -NK_API void -nk_group_scrolled_end(struct nk_context *ctx) -{ - struct nk_window *win; - struct nk_panel *parent; - struct nk_panel *g; - - struct nk_rect clip; - struct nk_window pan; - struct nk_vec2 panel_padding; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) - return; - - /* make sure nk_group_begin was called correctly */ - NK_ASSERT(ctx->current); - win = ctx->current; - NK_ASSERT(win->layout); - g = win->layout; - NK_ASSERT(g->parent); - parent = g->parent; - - /* dummy window */ - nk_zero_struct(pan); - panel_padding = nk_panel_get_padding(&ctx->style, NK_PANEL_GROUP); - pan.bounds.y = g->bounds.y - (g->header_height + g->menu.h); - pan.bounds.x = g->bounds.x - panel_padding.x; - pan.bounds.w = g->bounds.w + 2 * panel_padding.x; - pan.bounds.h = g->bounds.h + g->header_height + g->menu.h; - if (g->flags & NK_WINDOW_BORDER) { - pan.bounds.x -= g->border; - pan.bounds.y -= g->border; - pan.bounds.w += 2*g->border; - pan.bounds.h += 2*g->border; - } - if (!(g->flags & NK_WINDOW_NO_SCROLLBAR)) { - pan.bounds.w += ctx->style.window.scrollbar_size.x; - pan.bounds.h += ctx->style.window.scrollbar_size.y; - } - pan.scrollbar.x = *g->offset_x; - pan.scrollbar.y = *g->offset_y; - pan.flags = g->flags; - pan.buffer = win->buffer; - pan.layout = g; - pan.parent = win; - ctx->current = &pan; - - /* make sure group has correct clipping rectangle */ - nk_unify(&clip, &parent->clip, pan.bounds.x, pan.bounds.y, - pan.bounds.x + pan.bounds.w, pan.bounds.y + pan.bounds.h + panel_padding.x); - nk_push_scissor(&pan.buffer, clip); - nk_end(ctx); - - win->buffer = pan.buffer; - nk_push_scissor(&win->buffer, parent->clip); - ctx->current = win; - win->layout = parent; - g->bounds = pan.bounds; - return; -} - -NK_API int -nk_group_scrolled_begin(struct nk_context *ctx, - struct nk_scroll *scroll, const char *title, nk_flags flags) -{return nk_group_scrolled_offset_begin(ctx, &scroll->x, &scroll->y, title, flags);} - -NK_API int -nk_group_begin(struct nk_context *ctx, const char *title, nk_flags flags) -{ - int title_len; - nk_hash title_hash; - struct nk_window *win; - nk_uint *x_offset; - nk_uint *y_offset; - - NK_ASSERT(ctx); - NK_ASSERT(title); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout || !title) - return 0; - - /* find persistent group scrollbar value */ - win = ctx->current; - title_len = (int)nk_strlen(title); - title_hash = nk_murmur_hash(title, (int)title_len, NK_PANEL_GROUP); - x_offset = nk_find_value(win, title_hash); - if (!x_offset) { - x_offset = nk_add_value(ctx, win, title_hash, 0); - y_offset = nk_add_value(ctx, win, title_hash+1, 0); - - NK_ASSERT(x_offset); - NK_ASSERT(y_offset); - if (!x_offset || !y_offset) return 0; - *x_offset = *y_offset = 0; - } else y_offset = nk_find_value(win, title_hash+1); - return nk_group_scrolled_offset_begin(ctx, x_offset, y_offset, title, flags); -} - -NK_API void -nk_group_end(struct nk_context *ctx) -{nk_group_scrolled_end(ctx);} - -NK_API int -nk_list_view_begin(struct nk_context *ctx, struct nk_list_view *view, - const char *title, nk_flags flags, int row_height, int row_count) -{ - int title_len; - nk_hash title_hash; - nk_uint *x_offset; - nk_uint *y_offset; - - int result; - struct nk_window *win; - struct nk_panel *layout; - const struct nk_style *style; - struct nk_vec2 item_spacing; - - NK_ASSERT(ctx); - NK_ASSERT(view); - NK_ASSERT(title); - if (!ctx || !view || !title) return 0; - - win = ctx->current; - style = &ctx->style; - item_spacing = style->window.spacing; - row_height += NK_MAX(0, (int)item_spacing.y); - - /* find persistent list view scrollbar offset */ - title_len = (int)nk_strlen(title); - title_hash = nk_murmur_hash(title, (int)title_len, NK_PANEL_GROUP); - x_offset = nk_find_value(win, title_hash); - if (!x_offset) { - x_offset = nk_add_value(ctx, win, title_hash, 0); - y_offset = nk_add_value(ctx, win, title_hash+1, 0); - - NK_ASSERT(x_offset); - NK_ASSERT(y_offset); - if (!x_offset || !y_offset) return 0; - *x_offset = *y_offset = 0; - } else y_offset = nk_find_value(win, title_hash+1); - view->scroll_value = *y_offset; - view->scroll_pointer = y_offset; - - *y_offset = 0; - result = nk_group_scrolled_offset_begin(ctx, x_offset, y_offset, title, flags); - win = ctx->current; - layout = win->layout; - - view->total_height = row_height * NK_MAX(row_count,1); - view->begin = (int)NK_MAX((view->scroll_value / (float)row_height), 0.0f); - view->count = (int)NK_MAX(nk_iceilf((layout->clip.h)/(float)row_height), 0); - view->end = view->begin + view->count; - view->ctx = ctx; - return result; -} - -NK_API void -nk_list_view_end(struct nk_list_view *view) -{ - struct nk_context *ctx; - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(view); - NK_ASSERT(view->ctx); - NK_ASSERT(view->scroll_pointer); - if (!view || !view->ctx) return; - - ctx = view->ctx; - win = ctx->current; - layout = win->layout; - layout->at_y = layout->bounds.y + (float)view->total_height; - *view->scroll_pointer = *view->scroll_pointer + view->scroll_value; - nk_group_end(view->ctx); -} - -/* -------------------------------------------------------------- - * - * POPUP - * - * --------------------------------------------------------------*/ -NK_API int -nk_popup_begin(struct nk_context *ctx, enum nk_popup_type type, - const char *title, nk_flags flags, struct nk_rect rect) -{ - struct nk_window *popup; - struct nk_window *win; - struct nk_panel *panel; - - int title_len; - nk_hash title_hash; - nk_size allocated; - - NK_ASSERT(ctx); - NK_ASSERT(title); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - panel = win->layout; - NK_ASSERT(!(panel->type & NK_PANEL_SET_POPUP) && "popups are not allowed to have popups"); - title_len = (int)nk_strlen(title); - title_hash = nk_murmur_hash(title, (int)title_len, NK_PANEL_POPUP); - - popup = win->popup.win; - if (!popup) { - popup = (struct nk_window*)nk_create_window(ctx); - popup->parent = win; - win->popup.win = popup; - win->popup.active = 0; - win->popup.type = NK_PANEL_POPUP; - } - - /* make sure we have to correct popup */ - if (win->popup.name != title_hash) { - if (!win->popup.active) { - nk_zero(popup, sizeof(*popup)); - win->popup.name = title_hash; - win->popup.active = 1; - win->popup.type = NK_PANEL_POPUP; - } else return 0; - } - - /* popup position is local to window */ - ctx->current = popup; - rect.x += win->layout->clip.x; - rect.y += win->layout->clip.y; - - /* setup popup data */ - popup->parent = win; - popup->bounds = rect; - popup->seq = ctx->seq; - popup->layout = (struct nk_panel*)nk_create_panel(ctx); - popup->flags = flags; - popup->flags |= NK_WINDOW_BORDER; - if (type == NK_POPUP_DYNAMIC) - popup->flags |= NK_WINDOW_DYNAMIC; - - popup->buffer = win->buffer; - nk_start_popup(ctx, win); - allocated = ctx->memory.allocated; - nk_push_scissor(&popup->buffer, nk_null_rect); - - if (nk_panel_begin(ctx, title, NK_PANEL_POPUP)) { - /* popup is running therefore invalidate parent panels */ - struct nk_panel *root; - root = win->layout; - while (root) { - root->flags |= NK_WINDOW_ROM; - root->flags &= ~(nk_flags)NK_WINDOW_REMOVE_ROM; - root = root->parent; - } - win->popup.active = 1; - popup->layout->offset_x = &popup->scrollbar.x; - popup->layout->offset_y = &popup->scrollbar.y; - popup->layout->parent = win->layout; - return 1; - } else { - /* popup was closed/is invalid so cleanup */ - struct nk_panel *root; - root = win->layout; - while (root) { - root->flags |= NK_WINDOW_REMOVE_ROM; - root = root->parent; - } - win->layout->popup_buffer.active = 0; - win->popup.active = 0; - ctx->memory.allocated = allocated; - ctx->current = win; - nk_free_panel(ctx, popup->layout); - popup->layout = 0; - return 0; - } -} - -NK_INTERN 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) -{ - struct nk_window *popup; - struct nk_window *win; - struct nk_panel *panel; - int is_active = nk_true; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - /* popups cannot have popups */ - win = ctx->current; - panel = win->layout; - NK_ASSERT(!(panel->type & NK_PANEL_SET_POPUP)); - popup = win->popup.win; - if (!popup) { - /* create window for nonblocking popup */ - popup = (struct nk_window*)nk_create_window(ctx); - popup->parent = win; - win->popup.win = popup; - win->popup.type = panel_type; - nk_command_buffer_init(&popup->buffer, &ctx->memory, NK_CLIPPING_ON); - } else { - /* close the popup if user pressed outside or in the header */ - int pressed, in_body, in_header; - pressed = nk_input_is_mouse_pressed(&ctx->input, NK_BUTTON_LEFT); - in_body = nk_input_is_mouse_hovering_rect(&ctx->input, body); - in_header = nk_input_is_mouse_hovering_rect(&ctx->input, header); - if (pressed && (!in_body || in_header)) - is_active = nk_false; - } - win->popup.header = header; - - if (!is_active) { - /* remove read only mode from all parent panels */ - struct nk_panel *root; - root = win->layout; - while (root) { - root->flags |= NK_WINDOW_REMOVE_ROM; - root = root->parent; - } - return is_active; - } - - popup->bounds = body; - popup->parent = win; - popup->layout = (struct nk_panel*)nk_create_panel(ctx); - popup->flags = flags; - popup->flags |= NK_WINDOW_BORDER; - popup->flags |= NK_WINDOW_DYNAMIC; - popup->seq = ctx->seq; - win->popup.active = 1; - NK_ASSERT(popup->layout); - - nk_start_popup(ctx, win); - popup->buffer = win->buffer; - nk_push_scissor(&popup->buffer, nk_null_rect); - ctx->current = popup; - - nk_panel_begin(ctx, 0, panel_type); - win->buffer = popup->buffer; - popup->layout->parent = win->layout; - popup->layout->offset_x = &popup->scrollbar.x; - popup->layout->offset_y = &popup->scrollbar.y; - - /* set read only mode to all parent panels */ - {struct nk_panel *root; - root = win->layout; - while (root) { - root->flags |= NK_WINDOW_ROM; - root = root->parent; - }} - return is_active; -} - -NK_API void -nk_popup_close(struct nk_context *ctx) -{ - struct nk_window *popup; - NK_ASSERT(ctx); - if (!ctx || !ctx->current) return; - - popup = ctx->current; - NK_ASSERT(popup->parent); - NK_ASSERT(popup->layout->type & NK_PANEL_SET_POPUP); - popup->flags |= NK_WINDOW_HIDDEN; -} - -NK_API void -nk_popup_end(struct nk_context *ctx) -{ - struct nk_window *win; - struct nk_window *popup; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return; - - popup = ctx->current; - if (!popup->parent) return; - win = popup->parent; - if (popup->flags & NK_WINDOW_HIDDEN) { - struct nk_panel *root; - root = win->layout; - while (root) { - root->flags |= NK_WINDOW_REMOVE_ROM; - root = root->parent; - } - win->popup.active = 0; - } - nk_push_scissor(&popup->buffer, nk_null_rect); - nk_end(ctx); - - win->buffer = popup->buffer; - nk_finish_popup(ctx, win); - ctx->current = win; - nk_push_scissor(&win->buffer, win->layout->clip); -} -/* ------------------------------------------------------------- - * - * TOOLTIP - * - * -------------------------------------------------------------- */ -NK_API int -nk_tooltip_begin(struct nk_context *ctx, float width) -{ - struct nk_window *win; - const struct nk_input *in; - struct nk_rect bounds; - int ret; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - /* make sure that no nonblocking popup is currently active */ - win = ctx->current; - in = &ctx->input; - if (win->popup.win && (win->popup.type & NK_PANEL_SET_NONBLOCK)) - return 0; - - bounds.w = width; - bounds.h = nk_null_rect.h; - bounds.x = (in->mouse.pos.x + 1) - win->layout->clip.x; - bounds.y = (in->mouse.pos.y + 1) - win->layout->clip.y; - - ret = nk_popup_begin(ctx, NK_POPUP_DYNAMIC, - "__##Tooltip##__", NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER, bounds); - if (ret) win->layout->flags &= ~(nk_flags)NK_WINDOW_ROM; - win->popup.type = NK_PANEL_TOOLTIP; - ctx->current->layout->type = NK_PANEL_TOOLTIP; - return ret; -} - -NK_API void -nk_tooltip_end(struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) return; - ctx->current->seq--; - nk_popup_close(ctx); - nk_popup_end(ctx); -} - -NK_API void -nk_tooltip(struct nk_context *ctx, const char *text) -{ - const struct nk_style *style; - struct nk_vec2 padding; - - int text_len; - float text_width; - float text_height; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - NK_ASSERT(text); - if (!ctx || !ctx->current || !ctx->current->layout || !text) - return; - - /* fetch configuration data */ - style = &ctx->style; - padding = style->window.padding; - - /* calculate size of the text and tooltip */ - text_len = nk_strlen(text); - text_width = style->font->width(style->font->userdata, - style->font->height, text, text_len); - text_width += (4 * padding.x); - text_height = (style->font->height + 2 * padding.y); - - /* execute tooltip and fill with text */ - if (nk_tooltip_begin(ctx, (float)text_width)) { - nk_layout_row_dynamic(ctx, (float)text_height, 1); - nk_text(ctx, text, text_len, NK_TEXT_LEFT); - nk_tooltip_end(ctx); - } -} -/* ------------------------------------------------------------- - * - * CONTEXTUAL - * - * -------------------------------------------------------------- */ -NK_API int -nk_contextual_begin(struct nk_context *ctx, nk_flags flags, struct nk_vec2 size, - struct nk_rect trigger_bounds) -{ - struct nk_window *win; - struct nk_window *popup; - struct nk_rect body; - - NK_STORAGE const struct nk_rect null_rect = {0,0,0,0}; - int is_clicked = 0; - int is_active = 0; - int is_open = 0; - int ret = 0; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - ++win->popup.con_count; - - /* check if currently active contextual is active */ - popup = win->popup.win; - is_open = (popup && win->popup.type == NK_PANEL_CONTEXTUAL); - is_clicked = nk_input_mouse_clicked(&ctx->input, NK_BUTTON_RIGHT, trigger_bounds); - if (win->popup.active_con && win->popup.con_count != win->popup.active_con) - return 0; - if ((is_clicked && is_open && !is_active) || (!is_open && !is_active && !is_clicked)) - return 0; - - /* calculate contextual position on click */ - win->popup.active_con = win->popup.con_count; - if (is_clicked) { - body.x = ctx->input.mouse.pos.x; - body.y = ctx->input.mouse.pos.y; - } else { - body.x = popup->bounds.x; - body.y = popup->bounds.y; - } - body.w = size.x; - body.h = size.y; - - /* start nonblocking contextual popup */ - ret = nk_nonblock_begin(ctx, flags|NK_WINDOW_NO_SCROLLBAR, body, - null_rect, NK_PANEL_CONTEXTUAL); - if (ret) win->popup.type = NK_PANEL_CONTEXTUAL; - else { - win->popup.active_con = 0; - if (win->popup.win) - win->popup.win->flags = 0; - } - return ret; -} - -NK_API int -nk_contextual_item_text(struct nk_context *ctx, const char *text, int len, - nk_flags alignment) -{ - struct nk_window *win; - const struct nk_input *in; - const struct nk_style *style; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - style = &ctx->style; - state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding); - if (!state) return nk_false; - - in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - if (nk_do_button_text(&ctx->last_widget_state, &win->buffer, bounds, - text, len, alignment, NK_BUTTON_DEFAULT, &style->contextual_button, in, style->font)) { - nk_contextual_close(ctx); - return nk_true; - } - return nk_false; -} - -NK_API int nk_contextual_item_label(struct nk_context *ctx, const char *label, nk_flags align) -{return nk_contextual_item_text(ctx, label, nk_strlen(label), align);} - -NK_API int -nk_contextual_item_image_text(struct nk_context *ctx, struct nk_image img, - const char *text, int len, nk_flags align) -{ - struct nk_window *win; - const struct nk_input *in; - const struct nk_style *style; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - style = &ctx->style; - state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding); - if (!state) return nk_false; - - in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - if (nk_do_button_text_image(&ctx->last_widget_state, &win->buffer, bounds, - img, text, len, align, NK_BUTTON_DEFAULT, &style->contextual_button, style->font, in)){ - nk_contextual_close(ctx); - return nk_true; - } - return nk_false; -} - -NK_API int nk_contextual_item_image_label(struct nk_context *ctx, struct nk_image img, - const char *label, nk_flags align) -{return nk_contextual_item_image_text(ctx, img, label, nk_strlen(label), align);} - -NK_API int -nk_contextual_item_symbol_text(struct nk_context *ctx, enum nk_symbol_type symbol, - const char *text, int len, nk_flags align) -{ - struct nk_window *win; - const struct nk_input *in; - const struct nk_style *style; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - style = &ctx->style; - state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding); - if (!state) return nk_false; - - in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - if (nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, bounds, - symbol, text, len, align, NK_BUTTON_DEFAULT, &style->contextual_button, style->font, in)) { - nk_contextual_close(ctx); - return nk_true; - } - return nk_false; -} - -NK_API int nk_contextual_item_symbol_label(struct nk_context *ctx, enum nk_symbol_type symbol, - const char *text, nk_flags align) -{return nk_contextual_item_symbol_text(ctx, symbol, text, nk_strlen(text), align);} - -NK_API void -nk_contextual_close(struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) return; - nk_popup_close(ctx); -} - -NK_API void -nk_contextual_end(struct nk_context *ctx) -{ - struct nk_window *popup; - struct nk_panel *panel; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) return; - - popup = ctx->current; - panel = popup->layout; - NK_ASSERT(popup->parent); - NK_ASSERT(panel->type & NK_PANEL_SET_POPUP); - if (panel->flags & NK_WINDOW_DYNAMIC) { - /* Close behavior - This is a bit hack solution since we do not now before we end our popup - how big it will be. We therefore do not directly know when a - click outside the non-blocking popup must close it at that direct frame. - Instead it will be closed in the next frame.*/ - struct nk_rect body = {0,0,0,0}; - if (panel->at_y < (panel->bounds.y + panel->bounds.h)) { - struct nk_vec2 padding = nk_panel_get_padding(&ctx->style, panel->type); - body = panel->bounds; - body.y = (panel->at_y + panel->footer_height + panel->border + padding.y + panel->row.height); - body.h = (panel->bounds.y + panel->bounds.h) - body.y; - } - - {int pressed = nk_input_is_mouse_pressed(&ctx->input, NK_BUTTON_LEFT); - int in_body = nk_input_is_mouse_hovering_rect(&ctx->input, body); - if (pressed && in_body) - popup->flags |= NK_WINDOW_HIDDEN; - } - } - if (popup->flags & NK_WINDOW_HIDDEN) - popup->seq = 0; - nk_popup_end(ctx); - return; -} -/* ------------------------------------------------------------- - * - * COMBO - * - * --------------------------------------------------------------*/ -NK_INTERN int -nk_combo_begin(struct nk_context *ctx, struct nk_window *win, - struct nk_vec2 size, int is_clicked, struct nk_rect header) -{ - struct nk_window *popup; - int is_open = 0; - int is_active = 0; - struct nk_rect body; - nk_hash hash; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - popup = win->popup.win; - body.x = header.x; - body.w = size.x; - body.y = header.y + header.h-ctx->style.window.combo_border; - body.h = size.y; - - hash = win->popup.combo_count++; - is_open = (popup) ? nk_true:nk_false; - is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_COMBO); - if ((is_clicked && is_open && !is_active) || (is_open && !is_active) || - (!is_open && !is_active && !is_clicked)) return 0; - if (!nk_nonblock_begin(ctx, 0, body, - (is_clicked && is_open)?nk_rect(0,0,0,0):header, NK_PANEL_COMBO)) return 0; - - win->popup.type = NK_PANEL_COMBO; - win->popup.name = hash; - return 1; -} - -NK_API int -nk_combo_begin_text(struct nk_context *ctx, const char *selected, int len, - struct nk_vec2 size) -{ - const struct nk_input *in; - struct nk_window *win; - struct nk_style *style; - - enum nk_widget_layout_states s; - int is_clicked = nk_false; - struct nk_rect header; - const struct nk_style_item *background; - struct nk_text text; - - NK_ASSERT(ctx); - NK_ASSERT(selected); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout || !selected) - return 0; - - win = ctx->current; - style = &ctx->style; - s = nk_widget(&header, ctx); - if (s == NK_WIDGET_INVALID) - return 0; - - in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input; - if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT)) - is_clicked = nk_true; - - /* draw combo box header background and border */ - if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) { - background = &style->combo.active; - text.text = style->combo.label_active; - } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) { - background = &style->combo.hover; - text.text = style->combo.label_hover; - } else { - background = &style->combo.normal; - text.text = style->combo.label_normal; - } - if (background->type == NK_STYLE_ITEM_IMAGE) { - text.background = nk_rgba(0,0,0,0); - nk_draw_image(&win->buffer, header, &background->data.image, nk_white); - } else { - text.background = background->data.color; - nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color); - nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color); - } - { - /* print currently selected text item */ - struct nk_rect label; - struct nk_rect button; - struct nk_rect content; - - enum nk_symbol_type sym; - if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) - sym = style->combo.sym_hover; - else if (is_clicked) - sym = style->combo.sym_active; - else sym = style->combo.sym_normal; - - /* calculate button */ - button.w = header.h - 2 * style->combo.button_padding.y; - button.x = (header.x + header.w - header.h) - style->combo.button_padding.x; - button.y = header.y + style->combo.button_padding.y; - button.h = button.w; - - content.x = button.x + style->combo.button.padding.x; - content.y = button.y + style->combo.button.padding.y; - content.w = button.w - 2 * style->combo.button.padding.x; - content.h = button.h - 2 * style->combo.button.padding.y; - - /* draw selected label */ - text.padding = nk_vec2(0,0); - label.x = header.x + style->combo.content_padding.x; - label.y = header.y + style->combo.content_padding.y; - label.w = button.x - (style->combo.content_padding.x + style->combo.spacing.x) - label.x;; - label.h = header.h - 2 * style->combo.content_padding.y; - nk_widget_text(&win->buffer, label, selected, len, &text, - NK_TEXT_LEFT, ctx->style.font); - - /* draw open/close button */ - nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state, - &ctx->style.combo.button, sym, style->font); - } - return nk_combo_begin(ctx, win, size, is_clicked, header); -} - -NK_API int nk_combo_begin_label(struct nk_context *ctx, const char *selected, struct nk_vec2 size) -{return nk_combo_begin_text(ctx, selected, nk_strlen(selected), size);} - -NK_API int -nk_combo_begin_color(struct nk_context *ctx, struct nk_color color, struct nk_vec2 size) -{ - struct nk_window *win; - struct nk_style *style; - const struct nk_input *in; - - struct nk_rect header; - int is_clicked = nk_false; - enum nk_widget_layout_states s; - const struct nk_style_item *background; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - style = &ctx->style; - s = nk_widget(&header, ctx); - if (s == NK_WIDGET_INVALID) - return 0; - - in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input; - if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT)) - is_clicked = nk_true; - - /* draw combo box header background and border */ - if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) - background = &style->combo.active; - else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) - background = &style->combo.hover; - else background = &style->combo.normal; - - if (background->type == NK_STYLE_ITEM_IMAGE) { - nk_draw_image(&win->buffer, header, &background->data.image,nk_white); - } else { - nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color); - nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color); - } - { - struct nk_rect content; - struct nk_rect button; - struct nk_rect bounds; - - enum nk_symbol_type sym; - if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) - sym = style->combo.sym_hover; - else if (is_clicked) - sym = style->combo.sym_active; - else sym = style->combo.sym_normal; - - /* calculate button */ - button.w = header.h - 2 * style->combo.button_padding.y; - button.x = (header.x + header.w - header.h) - style->combo.button_padding.x; - button.y = header.y + style->combo.button_padding.y; - button.h = button.w; - - content.x = button.x + style->combo.button.padding.x; - content.y = button.y + style->combo.button.padding.y; - content.w = button.w - 2 * style->combo.button.padding.x; - content.h = button.h - 2 * style->combo.button.padding.y; - - /* draw color */ - bounds.h = header.h - 4 * style->combo.content_padding.y; - bounds.y = header.y + 2 * style->combo.content_padding.y; - bounds.x = header.x + 2 * style->combo.content_padding.x; - bounds.w = (button.x - (style->combo.content_padding.x + style->combo.spacing.x)) - bounds.x; - nk_fill_rect(&win->buffer, bounds, 0, color); - - /* draw open/close button */ - nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state, - &ctx->style.combo.button, sym, style->font); - } - return nk_combo_begin(ctx, win, size, is_clicked, header); -} - -NK_API int -nk_combo_begin_symbol(struct nk_context *ctx, enum nk_symbol_type symbol, struct nk_vec2 size) -{ - struct nk_window *win; - struct nk_style *style; - const struct nk_input *in; - - struct nk_rect header; - int is_clicked = nk_false; - enum nk_widget_layout_states s; - const struct nk_style_item *background; - struct nk_color sym_background; - struct nk_color symbol_color; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - style = &ctx->style; - s = nk_widget(&header, ctx); - if (s == NK_WIDGET_INVALID) - return 0; - - in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input; - if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT)) - is_clicked = nk_true; - - /* draw combo box header background and border */ - if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) { - background = &style->combo.active; - symbol_color = style->combo.symbol_active; - } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) { - background = &style->combo.hover; - symbol_color = style->combo.symbol_hover; - } else { - background = &style->combo.normal; - symbol_color = style->combo.symbol_hover; - } - - if (background->type == NK_STYLE_ITEM_IMAGE) { - sym_background = nk_rgba(0,0,0,0); - nk_draw_image(&win->buffer, header, &background->data.image, nk_white); - } else { - sym_background = background->data.color; - nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color); - nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color); - } - { - struct nk_rect bounds = {0,0,0,0}; - struct nk_rect content; - struct nk_rect button; - - enum nk_symbol_type sym; - if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) - sym = style->combo.sym_hover; - else if (is_clicked) - sym = style->combo.sym_active; - else sym = style->combo.sym_normal; - - /* calculate button */ - button.w = header.h - 2 * style->combo.button_padding.y; - button.x = (header.x + header.w - header.h) - style->combo.button_padding.y; - button.y = header.y + style->combo.button_padding.y; - button.h = button.w; - - content.x = button.x + style->combo.button.padding.x; - content.y = button.y + style->combo.button.padding.y; - content.w = button.w - 2 * style->combo.button.padding.x; - content.h = button.h - 2 * style->combo.button.padding.y; - - /* draw symbol */ - bounds.h = header.h - 2 * style->combo.content_padding.y; - bounds.y = header.y + style->combo.content_padding.y; - bounds.x = header.x + style->combo.content_padding.x; - bounds.w = (button.x - style->combo.content_padding.y) - bounds.x; - nk_draw_symbol(&win->buffer, symbol, bounds, sym_background, symbol_color, - 1.0f, style->font); - - /* draw open/close button */ - nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state, - &ctx->style.combo.button, sym, style->font); - } - return nk_combo_begin(ctx, win, size, is_clicked, header); -} - -NK_API int -nk_combo_begin_symbol_text(struct nk_context *ctx, const char *selected, int len, - enum nk_symbol_type symbol, struct nk_vec2 size) -{ - struct nk_window *win; - struct nk_style *style; - struct nk_input *in; - - struct nk_rect header; - int is_clicked = nk_false; - enum nk_widget_layout_states s; - const struct nk_style_item *background; - struct nk_color symbol_color; - struct nk_text text; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - style = &ctx->style; - s = nk_widget(&header, ctx); - if (!s) return 0; - - in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input; - if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT)) - is_clicked = nk_true; - - /* draw combo box header background and border */ - if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) { - background = &style->combo.active; - symbol_color = style->combo.symbol_active; - text.text = style->combo.label_active; - } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) { - background = &style->combo.hover; - symbol_color = style->combo.symbol_hover; - text.text = style->combo.label_hover; - } else { - background = &style->combo.normal; - symbol_color = style->combo.symbol_normal; - text.text = style->combo.label_normal; - } - if (background->type == NK_STYLE_ITEM_IMAGE) { - text.background = nk_rgba(0,0,0,0); - nk_draw_image(&win->buffer, header, &background->data.image, nk_white); - } else { - text.background = background->data.color; - nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color); - nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color); - } - { - struct nk_rect content; - struct nk_rect button; - struct nk_rect label; - struct nk_rect image; - - enum nk_symbol_type sym; - if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) - sym = style->combo.sym_hover; - else if (is_clicked) - sym = style->combo.sym_active; - else sym = style->combo.sym_normal; - - /* calculate button */ - button.w = header.h - 2 * style->combo.button_padding.y; - button.x = (header.x + header.w - header.h) - style->combo.button_padding.x; - button.y = header.y + style->combo.button_padding.y; - button.h = button.w; - - content.x = button.x + style->combo.button.padding.x; - content.y = button.y + style->combo.button.padding.y; - content.w = button.w - 2 * style->combo.button.padding.x; - content.h = button.h - 2 * style->combo.button.padding.y; - nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state, - &ctx->style.combo.button, sym, style->font); - - /* draw symbol */ - image.x = header.x + style->combo.content_padding.x; - image.y = header.y + style->combo.content_padding.y; - image.h = header.h - 2 * style->combo.content_padding.y; - image.w = image.h; - nk_draw_symbol(&win->buffer, symbol, image, text.background, symbol_color, - 1.0f, style->font); - - /* draw label */ - text.padding = nk_vec2(0,0); - label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x; - label.y = header.y + style->combo.content_padding.y; - label.w = (button.x - style->combo.content_padding.x) - label.x; - label.h = header.h - 2 * style->combo.content_padding.y; - nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font); - } - return nk_combo_begin(ctx, win, size, is_clicked, header); -} - -NK_API int -nk_combo_begin_image(struct nk_context *ctx, struct nk_image img, struct nk_vec2 size) -{ - struct nk_window *win; - struct nk_style *style; - const struct nk_input *in; - - struct nk_rect header; - int is_clicked = nk_false; - enum nk_widget_layout_states s; - const struct nk_style_item *background; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - style = &ctx->style; - s = nk_widget(&header, ctx); - if (s == NK_WIDGET_INVALID) - return 0; - - in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input; - if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT)) - is_clicked = nk_true; - - /* draw combo box header background and border */ - if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) - background = &style->combo.active; - else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) - background = &style->combo.hover; - else background = &style->combo.normal; - - if (background->type == NK_STYLE_ITEM_IMAGE) { - nk_draw_image(&win->buffer, header, &background->data.image, nk_white); - } else { - nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color); - nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color); - } - { - struct nk_rect bounds = {0,0,0,0}; - struct nk_rect content; - struct nk_rect button; - - enum nk_symbol_type sym; - if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) - sym = style->combo.sym_hover; - else if (is_clicked) - sym = style->combo.sym_active; - else sym = style->combo.sym_normal; - - /* calculate button */ - button.w = header.h - 2 * style->combo.button_padding.y; - button.x = (header.x + header.w - header.h) - style->combo.button_padding.y; - button.y = header.y + style->combo.button_padding.y; - button.h = button.w; - - content.x = button.x + style->combo.button.padding.x; - content.y = button.y + style->combo.button.padding.y; - content.w = button.w - 2 * style->combo.button.padding.x; - content.h = button.h - 2 * style->combo.button.padding.y; - - /* draw image */ - bounds.h = header.h - 2 * style->combo.content_padding.y; - bounds.y = header.y + style->combo.content_padding.y; - bounds.x = header.x + style->combo.content_padding.x; - bounds.w = (button.x - style->combo.content_padding.y) - bounds.x; - nk_draw_image(&win->buffer, bounds, &img, nk_white); - - /* draw open/close button */ - nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state, - &ctx->style.combo.button, sym, style->font); - } - return nk_combo_begin(ctx, win, size, is_clicked, header); -} - -NK_API int -nk_combo_begin_image_text(struct nk_context *ctx, const char *selected, int len, - struct nk_image img, struct nk_vec2 size) -{ - struct nk_window *win; - struct nk_style *style; - struct nk_input *in; - - struct nk_rect header; - int is_clicked = nk_false; - enum nk_widget_layout_states s; - const struct nk_style_item *background; - struct nk_text text; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - style = &ctx->style; - s = nk_widget(&header, ctx); - if (!s) return 0; - - in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input; - if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT)) - is_clicked = nk_true; - - /* draw combo box header background and border */ - if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) { - background = &style->combo.active; - text.text = style->combo.label_active; - } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) { - background = &style->combo.hover; - text.text = style->combo.label_hover; - } else { - background = &style->combo.normal; - text.text = style->combo.label_normal; - } - if (background->type == NK_STYLE_ITEM_IMAGE) { - text.background = nk_rgba(0,0,0,0); - nk_draw_image(&win->buffer, header, &background->data.image, nk_white); - } else { - text.background = background->data.color; - nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color); - nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color); - } - { - struct nk_rect content; - struct nk_rect button; - struct nk_rect label; - struct nk_rect image; - - enum nk_symbol_type sym; - if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) - sym = style->combo.sym_hover; - else if (is_clicked) - sym = style->combo.sym_active; - else sym = style->combo.sym_normal; - - /* calculate button */ - button.w = header.h - 2 * style->combo.button_padding.y; - button.x = (header.x + header.w - header.h) - style->combo.button_padding.x; - button.y = header.y + style->combo.button_padding.y; - button.h = button.w; - - content.x = button.x + style->combo.button.padding.x; - content.y = button.y + style->combo.button.padding.y; - content.w = button.w - 2 * style->combo.button.padding.x; - content.h = button.h - 2 * style->combo.button.padding.y; - nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state, - &ctx->style.combo.button, sym, style->font); - - /* draw image */ - image.x = header.x + style->combo.content_padding.x; - image.y = header.y + style->combo.content_padding.y; - image.h = header.h - 2 * style->combo.content_padding.y; - image.w = image.h; - nk_draw_image(&win->buffer, image, &img, nk_white); - - /* draw label */ - text.padding = nk_vec2(0,0); - label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x; - label.y = header.y + style->combo.content_padding.y; - label.w = (button.x - style->combo.content_padding.x) - label.x; - label.h = header.h - 2 * style->combo.content_padding.y; - nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font); - } - return nk_combo_begin(ctx, win, size, is_clicked, header); -} - -NK_API int nk_combo_begin_symbol_label(struct nk_context *ctx, - const char *selected, enum nk_symbol_type type, struct nk_vec2 size) -{return nk_combo_begin_symbol_text(ctx, selected, nk_strlen(selected), type, size);} - -NK_API int nk_combo_begin_image_label(struct nk_context *ctx, - const char *selected, struct nk_image img, struct nk_vec2 size) -{return nk_combo_begin_image_text(ctx, selected, nk_strlen(selected), img, size);} - -NK_API int nk_combo_item_text(struct nk_context *ctx, const char *text, int len,nk_flags align) -{return nk_contextual_item_text(ctx, text, len, align);} - -NK_API int nk_combo_item_label(struct nk_context *ctx, const char *label, nk_flags align) -{return nk_contextual_item_label(ctx, label, align);} - -NK_API int nk_combo_item_image_text(struct nk_context *ctx, struct nk_image img, const char *text, - int len, nk_flags alignment) -{return nk_contextual_item_image_text(ctx, img, text, len, alignment);} - -NK_API int nk_combo_item_image_label(struct nk_context *ctx, struct nk_image img, - const char *text, nk_flags alignment) -{return nk_contextual_item_image_label(ctx, img, text, alignment);} - -NK_API int nk_combo_item_symbol_text(struct nk_context *ctx, enum nk_symbol_type sym, - const char *text, int len, nk_flags alignment) -{return nk_contextual_item_symbol_text(ctx, sym, text, len, alignment);} - -NK_API int nk_combo_item_symbol_label(struct nk_context *ctx, enum nk_symbol_type sym, - const char *label, nk_flags alignment) -{return nk_contextual_item_symbol_label(ctx, sym, label, alignment);} - -NK_API void nk_combo_end(struct nk_context *ctx) -{nk_contextual_end(ctx);} - -NK_API void nk_combo_close(struct nk_context *ctx) -{nk_contextual_close(ctx);} - -NK_API int -nk_combo(struct nk_context *ctx, const char **items, int count, - int selected, int item_height, struct nk_vec2 size) -{ - int i = 0; - int max_height; - struct nk_vec2 item_spacing; - struct nk_vec2 window_padding; - - NK_ASSERT(ctx); - NK_ASSERT(items); - NK_ASSERT(ctx->current); - if (!ctx || !items ||!count) - return selected; - - item_spacing = ctx->style.window.spacing; - window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type); - max_height = count * item_height + count * (int)item_spacing.y; - max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2; - size.y = NK_MIN(size.y, (float)max_height); - if (nk_combo_begin_label(ctx, items[selected], size)) { - nk_layout_row_dynamic(ctx, (float)item_height, 1); - for (i = 0; i < count; ++i) { - if (nk_combo_item_label(ctx, items[i], NK_TEXT_LEFT)) - selected = i; - } - nk_combo_end(ctx); - } - return selected; -} - -NK_API int -nk_combo_separator(struct nk_context *ctx, const char *items_separated_by_separator, - int separator, int selected, int count, int item_height, struct nk_vec2 size) -{ - int i; - int max_height; - struct nk_vec2 item_spacing; - struct nk_vec2 window_padding; - const char *current_item; - const char *iter; - int length = 0; - - NK_ASSERT(ctx); - NK_ASSERT(items_separated_by_separator); - if (!ctx || !items_separated_by_separator) - return selected; - - /* calculate popup window */ - item_spacing = ctx->style.window.spacing; - window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type); - max_height = count * item_height + count * (int)item_spacing.y; - max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2; - size.y = NK_MIN(size.y, (float)max_height); - - /* find selected item */ - current_item = items_separated_by_separator; - for (i = 0; i < count; ++i) { - iter = current_item; - while (*iter && *iter != separator) iter++; - length = (int)(iter - current_item); - if (i == selected) break; - current_item = iter + 1; - } - - if (nk_combo_begin_text(ctx, current_item, length, size)) { - current_item = items_separated_by_separator; - nk_layout_row_dynamic(ctx, (float)item_height, 1); - for (i = 0; i < count; ++i) { - iter = current_item; - while (*iter && *iter != separator) iter++; - length = (int)(iter - current_item); - if (nk_combo_item_text(ctx, current_item, length, NK_TEXT_LEFT)) - selected = i; - current_item = current_item + length + 1; - } - nk_combo_end(ctx); - } - return selected; -} - -NK_API int -nk_combo_string(struct nk_context *ctx, const char *items_separated_by_zeros, - int selected, int count, int item_height, struct nk_vec2 size) -{return nk_combo_separator(ctx, items_separated_by_zeros, '\0', selected, count, item_height, size);} - -NK_API int -nk_combo_callback(struct nk_context *ctx, void(*item_getter)(void*, int, const char**), - void *userdata, int selected, int count, int item_height, struct nk_vec2 size) -{ - int i; - int max_height; - struct nk_vec2 item_spacing; - struct nk_vec2 window_padding; - const char *item; - - NK_ASSERT(ctx); - NK_ASSERT(item_getter); - if (!ctx || !item_getter) - return selected; - - /* calculate popup window */ - item_spacing = ctx->style.window.spacing; - window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type); - max_height = count * item_height + count * (int)item_spacing.y; - max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2; - size.y = NK_MIN(size.y, (float)max_height); - - item_getter(userdata, selected, &item); - if (nk_combo_begin_label(ctx, item, size)) { - nk_layout_row_dynamic(ctx, (float)item_height, 1); - for (i = 0; i < count; ++i) { - item_getter(userdata, i, &item); - if (nk_combo_item_label(ctx, item, NK_TEXT_LEFT)) - selected = i; - } - nk_combo_end(ctx); - } - return selected; -} - -NK_API void nk_combobox(struct nk_context *ctx, const char **items, int count, - int *selected, int item_height, struct nk_vec2 size) -{*selected = nk_combo(ctx, items, count, *selected, item_height, size);} - -NK_API void nk_combobox_string(struct nk_context *ctx, const char *items_separated_by_zeros, - int *selected, int count, int item_height, struct nk_vec2 size) -{*selected = nk_combo_string(ctx, items_separated_by_zeros, *selected, count, item_height, size);} - -NK_API void nk_combobox_separator(struct nk_context *ctx, const char *items_separated_by_separator, - int separator,int *selected, int count, int item_height, struct nk_vec2 size) -{*selected = nk_combo_separator(ctx, items_separated_by_separator, separator, - *selected, count, item_height, size);} - -NK_API void nk_combobox_callback(struct nk_context *ctx, - void(*item_getter)(void* data, int id, const char **out_text), - void *userdata, int *selected, int count, int item_height, struct nk_vec2 size) -{*selected = nk_combo_callback(ctx, item_getter, userdata, *selected, count, item_height, size);} - -/* - * ------------------------------------------------------------- - * - * MENU - * - * -------------------------------------------------------------- - */ -NK_INTERN int -nk_menu_begin(struct nk_context *ctx, struct nk_window *win, - const char *id, int is_clicked, struct nk_rect header, struct nk_vec2 size) -{ - int is_open = 0; - int is_active = 0; - struct nk_rect body; - struct nk_window *popup; - nk_hash hash = nk_murmur_hash(id, (int)nk_strlen(id), NK_PANEL_MENU); - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - body.x = header.x; - body.w = size.x; - body.y = header.y + header.h; - body.h = size.y; - - popup = win->popup.win; - is_open = popup ? nk_true : nk_false; - is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_MENU); - if ((is_clicked && is_open && !is_active) || (is_open && !is_active) || - (!is_open && !is_active && !is_clicked)) return 0; - if (!nk_nonblock_begin(ctx, NK_WINDOW_NO_SCROLLBAR, body, header, NK_PANEL_MENU)) - return 0; - - win->popup.type = NK_PANEL_MENU; - win->popup.name = hash; - return 1; -} - -NK_API int -nk_menu_begin_text(struct nk_context *ctx, const char *title, int len, - nk_flags align, struct nk_vec2 size) -{ - struct nk_window *win; - const struct nk_input *in; - struct nk_rect header; - int is_clicked = nk_false; - nk_flags state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - state = nk_widget(&header, ctx); - if (!state) return 0; - in = (state == NK_WIDGET_ROM || win->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - if (nk_do_button_text(&ctx->last_widget_state, &win->buffer, header, - title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in, ctx->style.font)) - is_clicked = nk_true; - return nk_menu_begin(ctx, win, title, is_clicked, header, size); -} - -NK_API int nk_menu_begin_label(struct nk_context *ctx, - const char *text, nk_flags align, struct nk_vec2 size) -{return nk_menu_begin_text(ctx, text, nk_strlen(text), align, size);} - -NK_API int -nk_menu_begin_image(struct nk_context *ctx, const char *id, struct nk_image img, - struct nk_vec2 size) -{ - struct nk_window *win; - struct nk_rect header; - const struct nk_input *in; - int is_clicked = nk_false; - nk_flags state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - state = nk_widget(&header, ctx); - if (!state) return 0; - in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - if (nk_do_button_image(&ctx->last_widget_state, &win->buffer, header, - img, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in)) - is_clicked = nk_true; - return nk_menu_begin(ctx, win, id, is_clicked, header, size); -} - -NK_API int -nk_menu_begin_symbol(struct nk_context *ctx, const char *id, - enum nk_symbol_type sym, struct nk_vec2 size) -{ - struct nk_window *win; - const struct nk_input *in; - struct nk_rect header; - int is_clicked = nk_false; - nk_flags state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - state = nk_widget(&header, ctx); - if (!state) return 0; - in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - if (nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, header, - sym, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in, ctx->style.font)) - is_clicked = nk_true; - return nk_menu_begin(ctx, win, id, is_clicked, header, size); -} - -NK_API int -nk_menu_begin_image_text(struct nk_context *ctx, const char *title, int len, - nk_flags align, struct nk_image img, struct nk_vec2 size) -{ - struct nk_window *win; - struct nk_rect header; - const struct nk_input *in; - int is_clicked = nk_false; - nk_flags state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - state = nk_widget(&header, ctx); - if (!state) return 0; - in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - if (nk_do_button_text_image(&ctx->last_widget_state, &win->buffer, - header, img, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button, - ctx->style.font, in)) - is_clicked = nk_true; - return nk_menu_begin(ctx, win, title, is_clicked, header, size); -} - -NK_API int nk_menu_begin_image_label(struct nk_context *ctx, - const char *title, nk_flags align, struct nk_image img, struct nk_vec2 size) -{return nk_menu_begin_image_text(ctx, title, nk_strlen(title), align, img, size);} - -NK_API int -nk_menu_begin_symbol_text(struct nk_context *ctx, const char *title, int len, - nk_flags align, enum nk_symbol_type sym, struct nk_vec2 size) -{ - struct nk_window *win; - struct nk_rect header; - const struct nk_input *in; - int is_clicked = nk_false; - nk_flags state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) - return 0; - - win = ctx->current; - state = nk_widget(&header, ctx); - if (!state) return 0; - - in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - if (nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, - header, sym, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button, - ctx->style.font, in)) is_clicked = nk_true; - return nk_menu_begin(ctx, win, title, is_clicked, header, size); -} - -NK_API int nk_menu_begin_symbol_label(struct nk_context *ctx, - const char *title, nk_flags align, enum nk_symbol_type sym, struct nk_vec2 size ) -{return nk_menu_begin_symbol_text(ctx, title, nk_strlen(title), align,sym,size);} - -NK_API int nk_menu_item_text(struct nk_context *ctx, const char *title, int len, nk_flags align) -{return nk_contextual_item_text(ctx, title, len, align);} - -NK_API int nk_menu_item_label(struct nk_context *ctx, const char *label, nk_flags align) -{return nk_contextual_item_label(ctx, label, align);} - -NK_API int nk_menu_item_image_label(struct nk_context *ctx, struct nk_image img, - const char *label, nk_flags align) -{return nk_contextual_item_image_label(ctx, img, label, align);} - -NK_API int nk_menu_item_image_text(struct nk_context *ctx, struct nk_image img, - const char *text, int len, nk_flags align) -{return nk_contextual_item_image_text(ctx, img, text, len, align);} - -NK_API int nk_menu_item_symbol_text(struct nk_context *ctx, enum nk_symbol_type sym, - const char *text, int len, nk_flags align) -{return nk_contextual_item_symbol_text(ctx, sym, text, len, align);} - -NK_API int nk_menu_item_symbol_label(struct nk_context *ctx, enum nk_symbol_type sym, - const char *label, nk_flags align) -{return nk_contextual_item_symbol_label(ctx, sym, label, align);} - -NK_API void nk_menu_close(struct nk_context *ctx) -{nk_contextual_close(ctx);} - -NK_API void -nk_menu_end(struct nk_context *ctx) -{nk_contextual_end(ctx);} - -#endif diff --git a/deps/nuklear/package.json b/deps/nuklear/package.json deleted file mode 100644 index edff9246..00000000 --- a/deps/nuklear/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "nuklear", - "version": "1.0.0", - "repo": "vurtun/nuklear", - "description": "A small ANSI C gui toolkit", - "keywords": ["gl", "ui", "toolkit"], - "src": ["nuklear.h"] -}

uSAz4o&1pNm*R!U!BvIYUG7T0KR^#j}r}{z8ux+2HuioEzy@de; z0+?`PU?6}IFt}t)o;uY(0%KPaMNQ!oWlD%f6^i3dU$3W|+a;O0y1H(N_({T$y@FhlBIXa1 zIt@0<+2^DBV?FYQ+@?DJAQQsXD@^l*F(6K;BBw2z)Ul7Ibv4OUGZUF(eH=wa6)G&3 zIfy?R7uNorTV8P6J231x%Suas0yg)^&!4wJm%D>=G&D5V)vy6cu&|!q-srB&wcq4f zE9cPAVE_m^f=2X`Kp|kCGvAb+Zavthd-1LQ1~1^Yq;TfN=I06U;OGc}9I9F`FhcPL z{nLQ^F1weJzw+OQe&BwB3ANCMW!Fb~Z*8hMs3c<-#3-|oz;>|xrgyyQUEMp?<8yRM z_`!9jqqn2b!k8ePhPKY*NAOoOP40IqhHb-k7dQw6!ne!sl00bUqg=VjfC4|P89cYV zj0fl@NmW|aaSG+v0gDyNa~KlWQ__(P^n!uaf$L$ul}g6`Lt4<{Bv{AgXe5PNn8i2r z8x-;dqOJA7@Gw?O+h=%PJ$|{5L`>KlYmx&gdpx}QrMf=$mW2vP6n?<*M!RuFKqlx_ zb8fOE*TPGg{e5*-#c`wif^sH8-c-km5)L$Obbl7sQ%HIE!9Dl`5B@-fZsCH<%}1H+ z&#XS9#9Dl!qJ6la^qn@U``cU8nu&|TMhk)OU4695rVsWh99){vQa&kPM`lP~yj~=H ze8_G!Z3F*RKSQSYN<&BJfnQ$LzOUSQFdtao=Oik|FIhT3)i@{UR&VJlSCG0!7I~sCS zRf$kdL^%8Tfi-e05sj(SuM-o5!eL{jra5 zku7)*>7tkG$G@l6Eh%O^r+1#i!&RaFcXLrwB0)zi91ssHK7;RkKl<1qL_{Z<94liL zom6nXOSffH8Siic#E1&3QmYws~AbA@C%x3Au>s0b-d4RiNG?M zxye)$q*kavlaHwSUrBId#%9~9B=WY6F!J*osrL_}ME|Dxz=-|oSP}ePDPN#>H9I2` zUe*B;QMFLUVAyhc#_7M!0}5G+ydmlMQxfImaxN#Svn*$66NQTz%gpQlGb1BxcwBuW zuQHf@XpAmzW>Gl?x&dB^Hp-9y_a|JVu@9g)F&}Fgv!o+&9BB{YQ zj_m%q;`rqNB@F9&;Fr0eDD zx=Fk*XuHi;uFLj5yr`I$_f|B=p9G9mfY#rsCroEIf3amFyqBPKo{*U9pl}^I!p8c( z+mA99IzDQ{1VR*442Ld?qUR5=L#?da6vYJGX`&2`iobt{FH95$w3J-#iZTp{okUjx zUtBskPYw4qC;$O`GCwcJ@=YJ#thSc3hc}}225o~|k5msbxJaug!zvat>h~2MBd+-0 zI#^Z1COF_Is9hy&ZmELpy~lH*N(>v7;D{2~Kw>vai1dc-+w>3SUnOT+(uEwWSI`@- zyJ&|)?xv6K73+4Jv>`s=&kmeLycLn?>Zii#WNd(%%4C|NLg zJ8Gy@c6R=kMzb&9HGIP7B}>T$#J;58>|7!QH99V{8>9kJNzL_I4G7YEw6@fw1$&#K z#%`+quLfyLNuoWI8FmZvAW%AV%4EoR8C*m%|0C1whc6uWx*e=0USrkjd)bvpEp(;7 zPA}O@(2!n}_&BX>yUW-NHw~=H^K?Gneog&c%Z9HnTi>$pE)~*NNq%+Nv)}#-!OM7T zP1h$=W)Tf^z+Jx-z;2aFwS9gfvdphk+0or7Z0$)_RvE$byfUri%iQW(+u7vx6pSYZ z8{ce?m;wuat`J*5g>b9YQj~|#w>LgI=4W0{Q25WMkr8rUHg9~w9B2U7)w*nvm5BzK z0^&<*p4gKVo4Vtwt-$l7m3zU9hyp{Jpm%0^%!t=$?es*{^t1pl`Va>S*y9rnqpmA` z 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⋘+$~gNA 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 G|NjBgQ8PXO diff --git a/deps/nuklear/example/images/image2.png b/deps/nuklear/example/images/image2.png deleted file mode 100644 index 4acafe533ebd169fb5265b7d6c4c775075bf4dec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5671 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