Browse Source

Merge branch 'master' of github.com:Immediate-Mode-UI/Nuklear into nk_input_is_mouse_moved

Rob Loach 1 year ago
parent
commit
4dab13fa6f
52 changed files with 1511 additions and 2617 deletions
  1. 5 5
      .github/workflows/ccpp.yml
  2. 1 15
      demo/allegro5/main.c
  3. 35 4
      demo/common/overview.c
  4. 42 1
      demo/common/style.c
  5. 0 14
      demo/d3d11/main.c
  6. 0 14
      demo/d3d12/main.c
  7. 0 14
      demo/d3d9/main.c
  8. 0 14
      demo/gdi/main.c
  9. 0 14
      demo/gdip/main.c
  10. 2 14
      demo/glfw_opengl2/main.c
  11. 1 14
      demo/glfw_opengl3/main.c
  12. 1 14
      demo/glfw_opengl4/main.c
  13. 1 15
      demo/glfw_vulkan/main.c
  14. 136 154
      demo/rawfb/nuklear_rawfb.h
  15. 1 1
      demo/rawfb/sdl/Makefile
  16. 23 12
      demo/rawfb/sdl/main.c
  17. 0 0
      demo/rawfb/wayland/.gitignore
  18. 0 0
      demo/rawfb/wayland/Makefile
  19. 120 127
      demo/rawfb/wayland/main.c
  20. 0 0
      demo/rawfb/x11/Makefile
  21. 8 21
      demo/rawfb/x11/main.c
  22. 12 19
      demo/rawfb/x11/nuklear_xlib.h
  23. 0 1083
      demo/sdl2surface_rawfb/sdl2surface_rawfb.h
  24. 0 13
      demo/sdl_opengl2/main.c
  25. 1 0
      demo/sdl_opengl2/nuklear_sdl_gl2.h
  26. 0 14
      demo/sdl_opengl3/main.c
  27. 1 0
      demo/sdl_opengl3/nuklear_sdl_gl3.h
  28. 0 14
      demo/sdl_opengles2/main.c
  29. 1 0
      demo/sdl_opengles2/nuklear_sdl_gles2.h
  30. 1 13
      demo/sdl_renderer/main.c
  31. 5 1
      demo/sdl_renderer/nuklear_sdl_renderer.h
  32. 0 14
      demo/sfml_opengl2/main.cpp
  33. 0 14
      demo/sfml_opengl3/main.cpp
  34. 0 869
      demo/wayland_rawfb/nuklear_raw_wayland.h
  35. 0 13
      demo/x11/main.c
  36. 0 13
      demo/x11_opengl2/main.c
  37. 0 13
      demo/x11_opengl3/main.c
  38. 0 13
      demo/x11_xft/main.c
  39. 24 0
      demo/xcb_cairo/Makefile
  40. 168 0
      demo/xcb_cairo/main.c
  41. 836 0
      demo/xcb_cairo/nuklear_xcb.h
  42. 43 22
      nuklear.h
  43. 9 5
      src/nuklear.h
  44. 13 0
      src/nuklear_button.c
  45. 1 1
      src/nuklear_context.c
  46. 6 6
      src/nuklear_font.c
  47. 2 2
      src/nuklear_internal.h
  48. 2 2
      src/nuklear_panel.c
  49. 1 1
      src/nuklear_pool.c
  50. 7 3
      src/nuklear_property.c
  51. 1 1
      src/nuklear_text_editor.c
  52. 1 1
      src/nuklear_util.c

+ 5 - 5
.github/workflows/ccpp.yml

@@ -6,7 +6,7 @@ jobs:
   build:
 
     runs-on: ubuntu-latest
-    
+
     steps:
     - uses: actions/checkout@v4
     - name: apt-update
@@ -31,10 +31,10 @@ jobs:
       run: make -C demo/sdl_opengles2
     - name: build sdl_renderer
       run: make -C demo/sdl_renderer
-    - name: build sdl2surface_rawfb
-      run: make -C demo/sdl2surface_rawfb
+    - name: build sdl_rawfb
+      run: make -C demo/rawfb/sdl
     - name: build wayland_rawfb
-      run: make -C demo/wayland_rawfb
+      run: make -C demo/rawfb/wayland
     - name: build x11
       run: make -C demo/x11
     - name: build x11_opengl2
@@ -42,7 +42,7 @@ jobs:
     - name: build x11_opengl3
       run: make -C demo/x11_opengl3
     - name: build x11_rawfb
-      run: make -C demo/x11_rawfb
+      run: make -C demo/rawfb/x11
     - name: build x11_xft
       run: make -C demo/x11_xft
     - name: build example

+ 1 - 15
demo/allegro5/main.c

@@ -41,7 +41,7 @@
 /*#define INCLUDE_STYLE */
 /*#define INCLUDE_CALCULATOR */
 /*#define INCLUDE_CANVAS */
-#define INCLUDE_OVERVIEW
+/*#define INCLUDE_OVERVIEW */
 /*#define INCLUDE_NODE_EDITOR */
 
 #ifdef INCLUDE_ALL
@@ -114,20 +114,6 @@ int main(void)
 
     ctx = nk_allegro5_init(font, display, WINDOW_WIDTH, WINDOW_HEIGHT);
 
-    /* style.c */
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-    #endif
-    #endif
-
     while(1)
     {
         bool get_event;

+ 35 - 4
demo/common/overview.c

@@ -4,15 +4,23 @@ overview(struct nk_context *ctx)
     /* window flags */
     static nk_bool show_menu = nk_true;
     static nk_flags window_flags = NK_WINDOW_TITLE|NK_WINDOW_BORDER|NK_WINDOW_SCALABLE|NK_WINDOW_MOVABLE|NK_WINDOW_MINIMIZABLE;
-    nk_flags actual_window_flags;
+    nk_flags actual_window_flags = 0;
+
+    /* widget flags */
+	static nk_bool disable_widgets = nk_false;
 
     /* popups */
     static enum nk_style_header_align header_align = NK_HEADER_RIGHT;
     static nk_bool show_app_about = nk_false;
 
-    ctx->style.window.header.align = header_align;
+#ifdef INCLUDE_STYLE
+    /* styles */
+    static const char* themes[] = {"Black", "White", "Red", "Blue", "Dark", "Dracula"};
+    static int current_theme = 0;
+#endif
 
-	static nk_bool disable_widgets = nk_false;
+    /* window flags */
+    ctx->style.window.header.align = header_align;
 
     actual_window_flags = window_flags;
     if (!(actual_window_flags & NK_WINDOW_TITLE))
@@ -120,6 +128,20 @@ overview(struct nk_context *ctx)
             } else show_app_about = nk_false;
         }
 
+#ifdef INCLUDE_STYLE
+        /* style selector */
+        nk_layout_row_dynamic(ctx, 0, 2);
+        {
+            int new_theme;
+            nk_label(ctx, "Style:", NK_TEXT_LEFT);
+            new_theme = nk_combo(ctx, themes, NK_LEN(themes), current_theme, 25, nk_vec2(200, 200));
+            if (new_theme != current_theme) {
+                current_theme = new_theme;
+                set_style(ctx, current_theme);
+            }
+        }
+#endif
+
         /* window flags */
         if (nk_tree_push(ctx, NK_TREE_TAB, "Window", NK_MINIMIZED)) {
             nk_layout_row_dynamic(ctx, 30, 2);
@@ -183,9 +205,13 @@ overview(struct nk_context *ctx)
                 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_UP_OUTLINE);
                 nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_DOWN);
+                nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_DOWN_OUTLINE);
                 nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_LEFT);
+                nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_LEFT_OUTLINE);
                 nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_RIGHT);
+                nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE);
 
                 nk_layout_row_static(ctx, 30, 100, 2);
                 nk_button_symbol_label(ctx, NK_SYMBOL_TRIANGLE_LEFT, "prev", NK_TEXT_RIGHT);
@@ -211,6 +237,7 @@ overview(struct nk_context *ctx)
                 static int range_int_value = 2048;
                 static int range_int_max = 4096;
                 static const float ratio[] = {120, 150};
+                static int range_int_value_hidden = 2048;
 
                 nk_layout_row_dynamic(ctx, 0, 1);
                 nk_checkbox_label(ctx, "CheckLeft TextLeft", &checkbox_left_text_left);
@@ -256,6 +283,10 @@ overview(struct nk_context *ctx)
                 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_layout_row_dynamic(ctx, 0, 2);
+                nk_label(ctx, "Hidden Label:", NK_TEXT_LEFT);
+                nk_property_int(ctx, "##Hidden Label", range_int_min, &range_int_value_hidden, INT_MAX, 1, 10);
+
                 nk_tree_pop(ctx);
             }
 
@@ -632,7 +663,7 @@ overview(struct nk_context *ctx)
             float id = 0;
             static int col_index = -1;
             static int line_index = -1;
-            static int show_markers = nk_true;
+            static nk_bool show_markers = nk_true;
             float step = (2*3.141592654f) / 32;
 
             int i;

+ 42 - 1
demo/common/style.c

@@ -1,4 +1,4 @@
-enum theme {THEME_BLACK, THEME_WHITE, THEME_RED, THEME_BLUE, THEME_DARK};
+enum theme {THEME_BLACK, THEME_WHITE, THEME_RED, THEME_BLUE, THEME_DARK, THEME_DRACULA};
 
 static void
 set_style(struct nk_context *ctx, enum theme theme)
@@ -124,6 +124,47 @@ set_style(struct nk_context *ctx, enum theme theme)
         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 if (theme == THEME_DRACULA) {
+        struct nk_color background = nk_rgba(40, 42, 54, 255);
+        struct nk_color currentline = nk_rgba(68, 71, 90, 255);
+        struct nk_color foreground = nk_rgba(248, 248, 242, 255);
+        struct nk_color comment = nk_rgba(98, 114, 164, 255);
+        /* struct nk_color cyan = nk_rgba(139, 233, 253, 255); */
+        /* struct nk_color green = nk_rgba(80, 250, 123, 255); */
+        /* struct nk_color orange = nk_rgba(255, 184, 108, 255); */
+        struct nk_color pink = nk_rgba(255, 121, 198, 255);
+        struct nk_color purple = nk_rgba(189, 147, 249, 255);
+        /* struct nk_color red = nk_rgba(255, 85, 85, 255); */
+        /* struct nk_color yellow = nk_rgba(241, 250, 140, 255); */
+        table[NK_COLOR_TEXT] = foreground;
+        table[NK_COLOR_WINDOW] = background;
+        table[NK_COLOR_HEADER] = currentline;
+        table[NK_COLOR_BORDER] = currentline;
+        table[NK_COLOR_BUTTON] = currentline;
+        table[NK_COLOR_BUTTON_HOVER] = comment;
+        table[NK_COLOR_BUTTON_ACTIVE] = purple;
+        table[NK_COLOR_TOGGLE] = currentline;
+        table[NK_COLOR_TOGGLE_HOVER] = comment;
+        table[NK_COLOR_TOGGLE_CURSOR] = pink;
+        table[NK_COLOR_SELECT] = currentline;
+        table[NK_COLOR_SELECT_ACTIVE] = comment;
+        table[NK_COLOR_SLIDER] = background;
+        table[NK_COLOR_SLIDER_CURSOR] = currentline;
+        table[NK_COLOR_SLIDER_CURSOR_HOVER] = comment;
+        table[NK_COLOR_SLIDER_CURSOR_ACTIVE] = comment;
+        table[NK_COLOR_PROPERTY] = currentline;
+        table[NK_COLOR_EDIT] = currentline;
+        table[NK_COLOR_EDIT_CURSOR] = foreground;
+        table[NK_COLOR_COMBO] = currentline;
+        table[NK_COLOR_CHART] = currentline;
+        table[NK_COLOR_CHART_COLOR] = comment;
+        table[NK_COLOR_CHART_COLOR_HIGHLIGHT] = purple;
+        table[NK_COLOR_SCROLLBAR] = background;
+        table[NK_COLOR_SCROLLBAR_CURSOR] = currentline;
+        table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = comment;
+        table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = purple;
+        table[NK_COLOR_TAB_HEADER] = currentline;
+        nk_style_from_table(ctx, table);
     } else {
         nk_style_default(ctx);
     }

+ 0 - 14
demo/d3d11/main.c

@@ -208,20 +208,6 @@ int main(void)
     /*nk_style_load_all_cursors(ctx, atlas->cursors);*/
     /*nk_style_set_font(ctx, &droid->handle)*/;}
 
-    /* style.c */
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-    #endif
-    #endif
-
     bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
     while (running)
     {

+ 0 - 14
demo/d3d12/main.c

@@ -300,20 +300,6 @@ int main(void)
     /* Now we can cleanup all resources consumed by font stashing that are no longer used */
     nk_d3d12_font_stash_cleanup();
 
-    /* style.c */
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-    #endif
-    #endif
-
     bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
     while (running)
     {

+ 0 - 14
demo/d3d9/main.c

@@ -214,20 +214,6 @@ int main(void)
     /*nk_style_load_all_cursors(ctx, atlas->cursors);*/
     /*nk_style_set_font(ctx, &droid->handle)*/;}
 
-    /* style.c */
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-    #endif
-    #endif
-
     bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
     while (running)
     {

+ 0 - 14
demo/gdi/main.c

@@ -113,20 +113,6 @@ int main(void)
     font = nk_gdifont_create("Arial", 14);
     ctx = nk_gdi_init(font, dc, WINDOW_WIDTH, WINDOW_HEIGHT);
 
-    /* style.c */
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-    #endif
-    #endif
-
     while (running)
     {
         /* Input */

+ 0 - 14
demo/gdip/main.c

@@ -109,20 +109,6 @@ int main(void)
     font = nk_gdipfont_create("Arial", 12);
     nk_gdip_set_font(font);
 
-    /* style.c */
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-    #endif
-    #endif
-
     while (running)
     {
         /* Input */

+ 2 - 14
demo/glfw_opengl2/main.c

@@ -40,7 +40,7 @@
 /* #define INCLUDE_ALL          */
 /* #define INCLUDE_STYLE        */
 /* #define INCLUDE_CALCULATOR   */
-#define INCLUDE_CANVAS
+/* #define INCLUDE_CANVAS       */
 /* #define INCLUDE_FILE_BROWSER */
 /* #define INCLUDE_OVERVIEW     */
 /* #define INCLUDE_NODE_EDITOR  */
@@ -49,6 +49,7 @@
   #define INCLUDE_STYLE
   #define INCLUDE_CALCULATOR
   #define INCLUDE_CANVAS
+  #define INCLUDE_FILE_BROWSER
   #define INCLUDE_OVERVIEW
   #define INCLUDE_NODE_EDITOR
 #endif
@@ -120,19 +121,6 @@ int main(void)
     /*nk_style_load_all_cursors(ctx, atlas->cursors);*/
     /*nk_style_set_font(ctx, &droid->handle);*/}
 
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-    #endif
-    #endif
-
     bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
 
     #ifdef INCLUDE_FILE_BROWSER

+ 1 - 14
demo/glfw_opengl3/main.c

@@ -42,7 +42,7 @@
 /*#define INCLUDE_STYLE */
 /*#define INCLUDE_CALCULATOR */
 /*#define INCLUDE_CANVAS */
-#define INCLUDE_OVERVIEW
+/*#define INCLUDE_OVERVIEW */
 /*#define INCLUDE_NODE_EDITOR */
 
 #ifdef INCLUDE_ALL
@@ -125,19 +125,6 @@ int main(void)
     /*nk_style_load_all_cursors(ctx, atlas->cursors);*/
     /*nk_style_set_font(ctx, &droid->handle);*/}
 
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-    #endif
-    #endif
-
     bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
     while (!glfwWindowShouldClose(win))
     {

+ 1 - 14
demo/glfw_opengl4/main.c

@@ -42,7 +42,7 @@
 /*#define INCLUDE_STYLE */
 /*#define INCLUDE_CALCULATOR */
 /*#define INCLUDE_CANVAS */
-#define INCLUDE_OVERVIEW
+/*#define INCLUDE_OVERVIEW */
 /*#define INCLUDE_NODE_EDITOR */
 
 #ifdef INCLUDE_ALL
@@ -125,19 +125,6 @@ int main(void)
     /*nk_style_load_all_cursors(ctx, atlas->cursors);*/
     /*nk_style_set_font(ctx, &droid->handle);*/}
 
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-    #endif
-    #endif
-
     /* Create bindless texture.
      * The index returned is not the opengl resource id.
      * IF you need the GL resource id use: nk_glfw3_get_tex_ogl_id() */

+ 1 - 15
demo/glfw_vulkan/main.c

@@ -35,7 +35,7 @@
  * ===============================================================*/
 /* 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 defines */
-#define INCLUDE_ALL
+/*#define INCLUDE_ALL */
 /*#define INCLUDE_STYLE */
 /*#define INCLUDE_CALCULATOR */
 /*#define INCLUDE_CANVAS */
@@ -2104,20 +2104,6 @@ int main(void) {
         /*nk_style_load_all_cursors(ctx, atlas->cursors);*/
     /*nk_style_set_font(ctx, &droid->handle);*/}
 
-#ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for
-     * anything else */
-#ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-#elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-#elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-#elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-#endif
-#endif
-
     img = nk_image_ptr(demo.demo_texture_image_view);
     bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
     while (!glfwWindowShouldClose(demo.win)) {

+ 136 - 154
demo/x11_rawfb/nuklear_rawfb.h → demo/rawfb/nuklear_rawfb.h

@@ -28,23 +28,23 @@
  *
  * ===============================================================
  */
+
 #ifndef NK_RAWFB_H_
 #define NK_RAWFB_H_
 
 struct rawfb_context;
 
-typedef enum rawfb_pixel_layout {
-    PIXEL_LAYOUT_XRGB_8888,
-    PIXEL_LAYOUT_RGBX_8888
-}
-rawfb_pl;
-
+struct rawfb_pl {
+    unsigned char bytesPerPixel;
+    unsigned char rshift, gshift, bshift, ashift;
+    unsigned char rloss, gloss, bloss, aloss;
+};
 
 /* All functions are thread-safe */
-NK_API struct rawfb_context *nk_rawfb_init(void *fb, void *tex_mem, const unsigned int w, const unsigned int h, const unsigned int pitch, const rawfb_pl pl);
+NK_API struct rawfb_context *nk_rawfb_init(void *fb, void *tex_mem, const unsigned int w, const unsigned int h, const unsigned int pitch, const struct rawfb_pl pl);
 NK_API void                  nk_rawfb_render(const struct rawfb_context *rawfb, const struct nk_color clear, const unsigned char enable_clear);
 NK_API void                  nk_rawfb_shutdown(struct rawfb_context *rawfb);
-NK_API void                  nk_rawfb_resize_fb(struct rawfb_context *rawfb, void *fb, const unsigned int w, const unsigned int h, const unsigned int pitch, const rawfb_pl pl);
+NK_API void                  nk_rawfb_resize_fb(struct rawfb_context *rawfb, void *fb, const unsigned int w, const unsigned int h, const unsigned int pitch, const struct rawfb_pl pl);
 
 #endif
 /*
@@ -62,8 +62,7 @@ NK_API void                  nk_rawfb_resize_fb(struct rawfb_context *rawfb, voi
 struct rawfb_image {
     void *pixels;
     int w, h, pitch;
-    rawfb_pl pl;
-    enum nk_font_atlas_format format;
+    struct rawfb_pl pl;
 };
 struct rawfb_context {
     struct nk_context ctx;
@@ -81,54 +80,28 @@ struct rawfb_context {
 #endif
 
 static unsigned int
-nk_rawfb_color2int(const struct nk_color c, rawfb_pl pl)
+nk_rawfb_color2int(const struct nk_color c, const struct rawfb_pl pl)
 {
     unsigned int res = 0;
 
-    switch (pl) {
-    case PIXEL_LAYOUT_RGBX_8888:
-	res |= c.r << 24;
-	res |= c.g << 16;
-	res |= c.b << 8;
-	res |= c.a;
-	break;
-    case PIXEL_LAYOUT_XRGB_8888:
-	res |= c.a << 24;
-	res |= c.r << 16;
-	res |= c.g << 8;
-	res |= c.b;
-	break;
-
-    default:
-	perror("nk_rawfb_color2int(): Unsupported pixel layout.\n");
-	break;
-    }
+    res |= (c.r >> pl.rloss) << pl.rshift;
+    res |= (c.g >> pl.gloss) << pl.gshift;
+    res |= (c.b >> pl.bloss) << pl.bshift;
+    res |= (c.a >> pl.aloss) << pl.ashift;
+
     return (res);
 }
 
 static struct nk_color
-nk_rawfb_int2color(const unsigned int i, rawfb_pl pl)
+nk_rawfb_int2color(const unsigned int i, const struct rawfb_pl pl)
 {
     struct nk_color col = {0,0,0,0};
 
-    switch (pl) {
-    case PIXEL_LAYOUT_RGBX_8888:
-	col.r = (i >> 24) & 0xff;
-	col.g = (i >> 16) & 0xff;
-	col.b = (i >> 8) & 0xff;
-	col.a = i & 0xff;
-	break;
-    case PIXEL_LAYOUT_XRGB_8888:
-	col.a = (i >> 24) & 0xff;
-	col.r = (i >> 16) & 0xff;
-	col.g = (i >> 8) & 0xff;
-	col.b = i & 0xff;
-	break;
-
-    default:
-	perror("nk_rawfb_int2color(): Unsupported pixel layout.\n");
-	break;
-    }
+    col.r = (pl.rloss == 8) ? 0xff : ((i >> pl.rshift) << pl.rloss) & 0xff;
+    col.g = (pl.gloss == 8) ? 0xff : ((i >> pl.gshift) << pl.gloss) & 0xff;
+    col.b = (pl.bloss == 8) ? 0xff : ((i >> pl.bshift) << pl.bloss) & 0xff;
+    col.a = (pl.aloss == 8) ? 0xff : ((i >> pl.ashift) << pl.aloss) & 0xff;
+
     return col;
 }
 
@@ -138,14 +111,20 @@ nk_rawfb_ctx_setpixel(const struct rawfb_context *rawfb,
 {
     unsigned int c = nk_rawfb_color2int(col, rawfb->fb.pl);
     unsigned char *pixels = rawfb->fb.pixels;
-    unsigned int *ptr;
 
     pixels += y0 * rawfb->fb.pitch;
-    ptr = (unsigned int *)pixels + x0;
 
     if (y0 < rawfb->scissors.h && y0 >= rawfb->scissors.y &&
-        x0 >= rawfb->scissors.x && x0 < rawfb->scissors.w)
-        *ptr = c;
+        x0 >= rawfb->scissors.x && x0 < rawfb->scissors.w) {
+
+        if (rawfb->fb.pl.bytesPerPixel == sizeof(unsigned int)) {
+            *((unsigned int *)pixels + x0) = c;
+        } else if (rawfb->fb.pl.bytesPerPixel == sizeof(unsigned short)) {
+            *((unsigned short *)pixels + x0) = c;
+        } else {
+            *((unsigned char *)pixels + x0) = c;
+        }
+    }
 }
 
 static void
@@ -156,22 +135,29 @@ nk_rawfb_line_horizontal(const struct rawfb_context *rawfb,
      * It does not check for scissors or image borders.
      * The caller has to make sure it does no exceed bounds. */
     unsigned int i, n;
-    unsigned int c[16];
+    unsigned char c[16 * 4];
     unsigned char *pixels = rawfb->fb.pixels;
-    unsigned int *ptr;
+    unsigned int bpp = rawfb->fb.pl.bytesPerPixel;
 
-    pixels += y * rawfb->fb.pitch;
-    ptr = (unsigned int *)pixels + x0;
+    pixels += (y * rawfb->fb.pitch) + (x0 * bpp);
 
-    n = x1 - x0;
-    for (i = 0; i < sizeof(c) / sizeof(c[0]); i++)
-        c[i] = nk_rawfb_color2int(col, rawfb->fb.pl);
+    n = (x1 - x0) * bpp;
+    if (bpp == sizeof(unsigned int)) {
+        for (i = 0; i < sizeof(c) / bpp; i++)
+            ((unsigned int *)c)[i] = nk_rawfb_color2int(col, rawfb->fb.pl);
+    } else if (bpp == sizeof(unsigned short)) {
+        for (i = 0; i < sizeof(c) / bpp; i++)
+            ((unsigned short *)c)[i] = nk_rawfb_color2int(col, rawfb->fb.pl);
+    } else {
+        for (i = 0; i < sizeof(c) / bpp; i++)
+            ((unsigned char *)c)[i] = nk_rawfb_color2int(col, rawfb->fb.pl);
+    }
 
-    while (n > 16) {
-        memcpy((void *)ptr, c, sizeof(c));
-        n -= 16; ptr += 16;
+    while (n > sizeof(c)) {
+        memcpy((void*)pixels, c, sizeof(c));
+        n -= sizeof(c); pixels += sizeof(c);
     } for (i = 0; i < n; i++)
-        ptr[i] = c[i];
+        pixels[i] = c[i];
 }
 
 static void
@@ -180,16 +166,16 @@ nk_rawfb_img_setpixel(const struct rawfb_image *img,
 {
     unsigned int c = nk_rawfb_color2int(col, img->pl);
     unsigned char *ptr;
-    unsigned int *pixel;
     NK_ASSERT(img);
     if (y0 < img->h && y0 >= 0 && x0 >= 0 && x0 < img->w) {
         ptr = (unsigned char *)img->pixels + (img->pitch * y0);
-	pixel = (unsigned int *)ptr;
 
-        if (img->format == NK_FONT_ATLAS_ALPHA8) {
-            ptr[x0] = col.a;
+        if (img->pl.bytesPerPixel == sizeof(unsigned int)) {
+            ((unsigned int *)ptr)[x0] = c;
+        } else if (img->pl.bytesPerPixel == sizeof(unsigned short)) {
+            ((unsigned short *)ptr)[x0] = c;
         } else {
-	    pixel[x0] = c;
+            ((unsigned char *)ptr)[x0] = c;
         }
     }
 }
@@ -204,12 +190,15 @@ nk_rawfb_img_getpixel(const struct rawfb_image *img, const int x0, const int y0)
     if (y0 < img->h && y0 >= 0 && x0 >= 0 && x0 < img->w) {
         ptr = (unsigned char *)img->pixels + (img->pitch * y0);
 
-        if (img->format == NK_FONT_ATLAS_ALPHA8) {
-            col.a = ptr[x0];
-            col.b = col.g = col.r = 0xff;
+        if (img->pl.bytesPerPixel == sizeof(unsigned int)) {
+            pixel = ((unsigned int *)ptr)[x0];
+            col = nk_rawfb_int2color(pixel, img->pl);
+        } else if (img->pl.bytesPerPixel == sizeof(unsigned short)) {
+            pixel = ((unsigned short *)ptr)[x0];
+            col = nk_rawfb_int2color(pixel, img->pl);
         } else {
-	    pixel = ((unsigned int *)ptr)[x0];
-	    col = nk_rawfb_int2color(pixel, img->pl);
+            pixel = ((unsigned char *)ptr)[x0];
+            col = nk_rawfb_int2color(pixel, img->pl);
         }
     } return col;
 }
@@ -598,7 +587,7 @@ nk_rawfb_draw_rect_multi_color(const struct rawfb_context *rawfb,
 
     edge_buf = malloc(((2*w) + (2*h)) * sizeof(struct nk_color));
     if (edge_buf == NULL)
-	return;
+        return;
 
     edge_t = edge_buf;
     edge_b = edge_buf + w;
@@ -608,51 +597,51 @@ nk_rawfb_draw_rect_multi_color(const struct rawfb_context *rawfb,
     /* Top and bottom edge gradients */
     for (i=0; i<w; i++)
     {
-	edge_t[i].r = (((((float)tr.r - tl.r)/(w-1))*i) + 0.5) + tl.r;
-	edge_t[i].g = (((((float)tr.g - tl.g)/(w-1))*i) + 0.5) + tl.g;
-	edge_t[i].b = (((((float)tr.b - tl.b)/(w-1))*i) + 0.5) + tl.b;
-	edge_t[i].a = (((((float)tr.a - tl.a)/(w-1))*i) + 0.5) + tl.a;
-
-	edge_b[i].r = (((((float)br.r - bl.r)/(w-1))*i) + 0.5) + bl.r;
-	edge_b[i].g = (((((float)br.g - bl.g)/(w-1))*i) + 0.5) + bl.g;
-	edge_b[i].b = (((((float)br.b - bl.b)/(w-1))*i) + 0.5) + bl.b;
-	edge_b[i].a = (((((float)br.a - bl.a)/(w-1))*i) + 0.5) + bl.a;
+        edge_t[i].r = (((((float)tr.r - tl.r)/(w-1))*i) + 0.5) + tl.r;
+        edge_t[i].g = (((((float)tr.g - tl.g)/(w-1))*i) + 0.5) + tl.g;
+        edge_t[i].b = (((((float)tr.b - tl.b)/(w-1))*i) + 0.5) + tl.b;
+        edge_t[i].a = (((((float)tr.a - tl.a)/(w-1))*i) + 0.5) + tl.a;
+
+        edge_b[i].r = (((((float)br.r - bl.r)/(w-1))*i) + 0.5) + bl.r;
+        edge_b[i].g = (((((float)br.g - bl.g)/(w-1))*i) + 0.5) + bl.g;
+        edge_b[i].b = (((((float)br.b - bl.b)/(w-1))*i) + 0.5) + bl.b;
+        edge_b[i].a = (((((float)br.a - bl.a)/(w-1))*i) + 0.5) + bl.a;
     }
 
     /* Left and right edge gradients */
     for (i=0; i<h; i++)
     {
-	edge_l[i].r = (((((float)bl.r - tl.r)/(h-1))*i) + 0.5) + tl.r;
-	edge_l[i].g = (((((float)bl.g - tl.g)/(h-1))*i) + 0.5) + tl.g;
-	edge_l[i].b = (((((float)bl.b - tl.b)/(h-1))*i) + 0.5) + tl.b;
-	edge_l[i].a = (((((float)bl.a - tl.a)/(h-1))*i) + 0.5) + tl.a;
-
-	edge_r[i].r = (((((float)br.r - tr.r)/(h-1))*i) + 0.5) + tr.r;
-	edge_r[i].g = (((((float)br.g - tr.g)/(h-1))*i) + 0.5) + tr.g;
-	edge_r[i].b = (((((float)br.b - tr.b)/(h-1))*i) + 0.5) + tr.b;
-	edge_r[i].a = (((((float)br.a - tr.a)/(h-1))*i) + 0.5) + tr.a;
+        edge_l[i].r = (((((float)bl.r - tl.r)/(h-1))*i) + 0.5) + tl.r;
+        edge_l[i].g = (((((float)bl.g - tl.g)/(h-1))*i) + 0.5) + tl.g;
+        edge_l[i].b = (((((float)bl.b - tl.b)/(h-1))*i) + 0.5) + tl.b;
+        edge_l[i].a = (((((float)bl.a - tl.a)/(h-1))*i) + 0.5) + tl.a;
+
+        edge_r[i].r = (((((float)br.r - tr.r)/(h-1))*i) + 0.5) + tr.r;
+        edge_r[i].g = (((((float)br.g - tr.g)/(h-1))*i) + 0.5) + tr.g;
+        edge_r[i].b = (((((float)br.b - tr.b)/(h-1))*i) + 0.5) + tr.b;
+        edge_r[i].a = (((((float)br.a - tr.a)/(h-1))*i) + 0.5) + tr.a;
     }
 
     for (i=0; i<h; i++) {
-	for (j=0; j<w; j++) {
-	    if (i==0) {
-		nk_rawfb_img_blendpixel(&rawfb->fb, x+j, y+i, edge_t[j]);
-	    } else if (i==h-1) {
-		nk_rawfb_img_blendpixel(&rawfb->fb, x+j, y+i, edge_b[j]);
-	    } else {
-		if (j==0) {
-		    nk_rawfb_img_blendpixel(&rawfb->fb, x+j, y+i, edge_l[i]);
-		} else if (j==w-1) {
-		    nk_rawfb_img_blendpixel(&rawfb->fb, x+j, y+i, edge_r[i]);
-		} else {
-		    pixel.r = (((((float)edge_r[i].r - edge_l[i].r)/(w-1))*j) + 0.5) + edge_l[i].r;
-		    pixel.g = (((((float)edge_r[i].g - edge_l[i].g)/(w-1))*j) + 0.5) + edge_l[i].g;
-		    pixel.b = (((((float)edge_r[i].b - edge_l[i].b)/(w-1))*j) + 0.5) + edge_l[i].b;
-		    pixel.a = (((((float)edge_r[i].a - edge_l[i].a)/(w-1))*j) + 0.5) + edge_l[i].a;
-		    nk_rawfb_img_blendpixel(&rawfb->fb, x+j, y+i, pixel);
-		}
-	    }
-	}
+        for (j=0; j<w; j++) {
+            if (i==0) {
+                nk_rawfb_img_blendpixel(&rawfb->fb, x+j, y+i, edge_t[j]);
+            } else if (i==h-1) {
+                nk_rawfb_img_blendpixel(&rawfb->fb, x+j, y+i, edge_b[j]);
+            } else {
+                if (j==0) {
+                    nk_rawfb_img_blendpixel(&rawfb->fb, x+j, y+i, edge_l[i]);
+                } else if (j==w-1) {
+                    nk_rawfb_img_blendpixel(&rawfb->fb, x+j, y+i, edge_r[i]);
+                } else {
+                    pixel.r = (((((float)edge_r[i].r - edge_l[i].r)/(w-1))*j) + 0.5) + edge_l[i].r;
+                    pixel.g = (((((float)edge_r[i].g - edge_l[i].g)/(w-1))*j) + 0.5) + edge_l[i].g;
+                    pixel.b = (((((float)edge_r[i].b - edge_l[i].b)/(w-1))*j) + 0.5) + edge_l[i].b;
+                    pixel.a = (((((float)edge_r[i].a - edge_l[i].a)/(w-1))*j) + 0.5) + edge_l[i].a;
+                    nk_rawfb_img_blendpixel(&rawfb->fb, x+j, y+i, pixel);
+                }
+            }
+        }
     }
 
     free(edge_buf);
@@ -823,62 +812,55 @@ nk_rawfb_clear(const struct rawfb_context *rawfb, const struct nk_color col)
 
 NK_API struct rawfb_context*
 nk_rawfb_init(void *fb, void *tex_mem, const unsigned int w, const unsigned int h,
-    const unsigned int pitch, const rawfb_pl pl)
+    const unsigned int pitch, const struct rawfb_pl pl)
 {
     const void *tex;
     struct rawfb_context *rawfb;
+
     rawfb = malloc(sizeof(struct rawfb_context));
     if (!rawfb)
         return NULL;
 
     memset(rawfb, 0, sizeof(struct rawfb_context));
     rawfb->font_tex.pixels = tex_mem;
-    rawfb->font_tex.format = NK_FONT_ATLAS_ALPHA8;
-    rawfb->font_tex.w = rawfb->font_tex.h = 0;
+    rawfb->font_tex.pl.bytesPerPixel = 1;
+    rawfb->font_tex.pl.rshift = 0;
+    rawfb->font_tex.pl.gshift = 0;
+    rawfb->font_tex.pl.bshift = 0;
+    rawfb->font_tex.pl.ashift = 0;
+    rawfb->font_tex.pl.rloss = 8;
+    rawfb->font_tex.pl.gloss = 8;
+    rawfb->font_tex.pl.bloss = 8;
+    rawfb->font_tex.pl.aloss = 0;
+    rawfb->font_tex.w = rawfb->font_tex.h = rawfb->font_tex.pitch = 0;
 
     rawfb->fb.pixels = fb;
-    rawfb->fb.w= w;
+    rawfb->fb.w = w;
     rawfb->fb.h = h;
-    rawfb->fb.pl = pl;
-
-    if (pl == PIXEL_LAYOUT_RGBX_8888 || pl == PIXEL_LAYOUT_XRGB_8888) {
-    rawfb->fb.format = NK_FONT_ATLAS_RGBA32;
     rawfb->fb.pitch = pitch;
-    }
-    else {
-	perror("nk_rawfb_init(): Unsupported pixel layout.\n");
-	free(rawfb);
-	return NULL;
-    }
+    rawfb->fb.pl = pl;
 
     if (0 == nk_init_default(&rawfb->ctx, 0)) {
-	free(rawfb);
-	return NULL;
+        free(rawfb);
+        return NULL;
     }
 
     nk_font_atlas_init_default(&rawfb->atlas);
     nk_font_atlas_begin(&rawfb->atlas);
-    tex = nk_font_atlas_bake(&rawfb->atlas, &rawfb->font_tex.w, &rawfb->font_tex.h, rawfb->font_tex.format);
+    tex = nk_font_atlas_bake(&rawfb->atlas, &rawfb->font_tex.w, &rawfb->font_tex.h, NK_FONT_ATLAS_ALPHA8);
     if (!tex) {
-	free(rawfb);
-	return NULL;
+        free(rawfb);
+        return NULL;
     }
 
-    switch(rawfb->font_tex.format) {
-    case NK_FONT_ATLAS_ALPHA8:
-        rawfb->font_tex.pitch = rawfb->font_tex.w * 1;
-        break;
-    case NK_FONT_ATLAS_RGBA32:
-        rawfb->font_tex.pitch = rawfb->font_tex.w * 4;
-        break;
-    };
-    /* Store the font texture in tex scratch memory */
+    rawfb->font_tex.pitch = rawfb->font_tex.w * 1;
     memcpy(rawfb->font_tex.pixels, tex, rawfb->font_tex.pitch * rawfb->font_tex.h);
     nk_font_atlas_end(&rawfb->atlas, nk_handle_ptr(NULL), NULL);
     if (rawfb->atlas.default_font)
         nk_style_set_font(&rawfb->ctx, &rawfb->atlas.default_font->handle);
     nk_style_load_all_cursors(&rawfb->ctx, rawfb->atlas.cursors);
     nk_rawfb_scissor(rawfb, 0, 0, rawfb->fb.w, rawfb->fb.h);
+
     return rawfb;
 }
 
@@ -905,12 +887,12 @@ nk_rawfb_stretch_image(const struct rawfb_image *dst,
                     continue;
             }
             col = nk_rawfb_img_getpixel(src, (int)xoff, (int) yoff);
-	    if (col.r || col.g || col.b)
-	    {
-		col.r = fg->r;
-		col.g = fg->g;
-		col.b = fg->b;
-	    }
+            if (col.r || col.g || col.b)
+            {
+                col.r = fg->r;
+                col.g = fg->g;
+                col.b = fg->b;
+            }
             nk_rawfb_img_blendpixel(dst, i + (int)(dst_rect->x + 0.5f), j + (int)(dst_rect->y + 0.5f), col);
             xoff += xinc;
         }
@@ -986,8 +968,8 @@ nk_rawfb_draw_text(const struct rawfb_context *rawfb,
 
         dst_rect.x = x + g.offset.x + rect.x;
         dst_rect.y = g.offset.y + rect.y;
-        dst_rect.w = ceilf(g.width);
-        dst_rect.h = ceilf(g.height);
+        dst_rect.w = ceil(g.width);
+        dst_rect.h = ceil(g.height);
 
         /* Use software rescaling to blit glyph from font_text to framebuffer */
         nk_rawfb_stretch_image(&rawfb->fb, &rawfb->font_tex, &dst_rect, &src_rect, &rawfb->scissors, &fg);
@@ -1024,9 +1006,9 @@ NK_API void
 nk_rawfb_shutdown(struct rawfb_context *rawfb)
 {
     if (rawfb) {
-	nk_free(&rawfb->ctx);
-	memset(rawfb, 0, sizeof(struct rawfb_context));
-	free(rawfb);
+        nk_free(&rawfb->ctx);
+        memset(rawfb, 0, sizeof(struct rawfb_context));
+        free(rawfb);
     }
 }
 
@@ -1036,7 +1018,7 @@ nk_rawfb_resize_fb(struct rawfb_context *rawfb,
                    const unsigned int w,
                    const unsigned int h,
                    const unsigned int pitch,
-		   const rawfb_pl pl)
+                   const struct rawfb_pl pl)
 {
     rawfb->fb.w = w;
     rawfb->fb.h = h;
@@ -1117,9 +1099,9 @@ nk_rawfb_render(const struct rawfb_context *rawfb,
                 q->end, 22, q->line_thickness, q->color);
         } break;
         case NK_COMMAND_RECT_MULTI_COLOR: {
-	    const struct nk_command_rect_multi_color *q = (const struct nk_command_rect_multi_color *)cmd;
-	    nk_rawfb_draw_rect_multi_color(rawfb, q->x, q->y, q->w, q->h, q->left, q->top, q->right, q->bottom);
-	} break;
+            const struct nk_command_rect_multi_color *q = (const struct nk_command_rect_multi_color *)cmd;
+            nk_rawfb_draw_rect_multi_color(rawfb, q->x, q->y, q->w, q->h, q->left, q->top, q->right, q->bottom);
+        } break;
         case NK_COMMAND_IMAGE: {
             const struct nk_command_image *q = (const struct nk_command_image *)cmd;
             nk_rawfb_drawimage(rawfb, q->x, q->y, q->w, q->h, &q->img, &q->col);

+ 1 - 1
demo/sdl2surface_rawfb/Makefile → demo/rawfb/sdl/Makefile

@@ -2,7 +2,7 @@ CFLAGS=`sdl2-config --cflags --libs`   -std=c89 -Wall -Wextra -pedantic -Wno-unu
 
 .PHONY: clean
 
-demo: main.c sdl2surface_rawfb.h
+demo: main.c ../nuklear_rawfb.h
 	$(CC) -o demo *.c $(CFLAGS) -lrt -lm
 
 clean:

+ 23 - 12
demo/sdl2surface_rawfb/main.c → demo/rawfb/sdl/main.c

@@ -18,9 +18,9 @@
 #define NK_INCLUDE_FONT_BAKING
 #define NK_INCLUDE_DEFAULT_FONT
 #define NK_INCLUDE_SOFTWARE_FONT
-#include "../../nuklear.h"
-#define NK_SDLSURFACE_IMPLEMENTATION
-#include "sdl2surface_rawfb.h"
+#include "../../../nuklear.h"
+#define NK_RAWFB_IMPLEMENTATION
+#include "../nuklear_rawfb.h"
 
 /* ===============================================================
  *
@@ -45,19 +45,19 @@
 #endif
 
 #ifdef INCLUDE_STYLE
-  #include "../../demo/common/style.c"
+  #include "../../common/style.c"
 #endif
 #ifdef INCLUDE_CALCULATOR
-  #include "../../demo/common/calculator.c"
+  #include "../../common/calculator.c"
 #endif
 #ifdef INCLUDE_CANVAS
-  #include "../../demo/common/canvas.c"
+  #include "../../common/canvas.c"
 #endif
 #ifdef INCLUDE_OVERVIEW
-  #include "../../demo/common/overview.c"
+  #include "../../common/overview.c"
 #endif
 #ifdef INCLUDE_NODE_EDITOR
-  #include "../../demo/common/node_editor.c"
+  #include "../../common/node_editor.c"
 #endif
 
 static int translate_sdl_key(struct SDL_Keysym const *k)
@@ -131,7 +131,9 @@ int main(int argc, char **argv)
     struct nk_color clear = {0,100,0,255};
     struct nk_vec2 vec;
     struct nk_rect bounds = {40,40,0,0};
-    struct sdlsurface_context *context;
+    struct rawfb_context *context;
+    struct rawfb_pl pl;
+    unsigned char tex_scratch[512 * 512];
 
     SDL_DisplayMode dm;
     SDL_Window *window;
@@ -164,8 +166,17 @@ int main(int argc, char **argv)
 
     surface = SDL_CreateRGBSurfaceWithFormat(0, dm.w-200, dm.h-200, 32, SDL_PIXELFORMAT_ARGB8888);
 
+    pl.bytesPerPixel = surface->format->BytesPerPixel;
+    pl.rshift = surface->format->Rshift;
+    pl.gshift = surface->format->Gshift;
+    pl.bshift = surface->format->Bshift;
+    pl.ashift = surface->format->Ashift;
+    pl.rloss = surface->format->Rloss;
+    pl.gloss = surface->format->Gloss;
+    pl.bloss = surface->format->Bloss;
+    pl.aloss = surface->format->Aloss;
 
-    context = nk_sdlsurface_init(surface, 13.0f);
+    context = nk_rawfb_init(surface->pixels, tex_scratch, surface->w, surface->h, surface->pitch, pl);
 
 
     while(1)
@@ -240,7 +251,7 @@ int main(int argc, char **argv)
         #endif
         /* ----------------------------------------- */
 
-        nk_sdlsurface_render(context, clear, 1);
+        nk_rawfb_render(context, clear, 1);
 
 
 
@@ -252,7 +263,7 @@ int main(int argc, char **argv)
 
     }
 
-    nk_sdlsurface_shutdown(context);
+    nk_rawfb_shutdown(context);
 
     SDL_FreeSurface(surface);
     SDL_DestroyRenderer(renderer);

+ 0 - 0
demo/wayland_rawfb/.gitignore → demo/rawfb/wayland/.gitignore


+ 0 - 0
demo/wayland_rawfb/Makefile → demo/rawfb/wayland/Makefile


+ 120 - 127
demo/wayland_rawfb/main.c → demo/rawfb/wayland/main.c

@@ -4,11 +4,11 @@
 #define NK_INCLUDE_STANDARD_VARARGS
 #define NK_INCLUDE_DEFAULT_ALLOCATOR
 #define NK_IMPLEMENTATION
+#define NK_RAWFB_IMPLEMENTATION
 #define NK_INCLUDE_FONT_BAKING
 #define NK_INCLUDE_DEFAULT_FONT
 #define NK_INCLUDE_SOFTWARE_FONT
 
-
 #include <wayland-client.h>
 #include <stdlib.h>
 #include <fcntl.h>
@@ -20,11 +20,34 @@
 #include <time.h>
 #include <sys/time.h>
 
-#include "../../nuklear.h"
+#include "../../../nuklear.h"
 
 #include "xdg-shell.h"
-#include "nuklear_raw_wayland.h"
+#include "../nuklear_rawfb.h"
+
+struct nk_wayland {
+    /*wayland vars*/
+    struct wl_display *display;
+    struct wl_compositor *compositor;
+    struct xdg_wm_base *xdg_wm_base;
+    struct wl_shm *wl_shm;
+    struct wl_seat* seat;
+    struct wl_callback *frame_callback;
+    struct wl_surface *surface;
+    struct xdg_surface *xdg_surface;
+    struct xdg_toplevel *xdg_toplevel;
+    struct wl_buffer *front_buffer;
+
+    int32_t *data;
+    int mouse_pointer_x;
+    int mouse_pointer_y;
+    uint8_t tex_scratch[512 * 512];
+
+    struct rawfb_context *rawfb;
+};
 
+#define WIDTH 800
+#define HEIGHT 600
 
 #define DTIME           20
 
@@ -51,19 +74,19 @@
 #endif
 
 #ifdef INCLUDE_STYLE
-  #include "../../demo/common/style.c"
+  #include "../../common/style.c"
 #endif
 #ifdef INCLUDE_CALCULATOR
-  #include "../../demo/common/calculator.c"
+  #include "../../common/calculator.c"
 #endif
 #ifdef INCLUDE_CANVAS
-  #include "../../demo/common/canvas.c"
+  #include "../../common/canvas.c"
 #endif
 #ifdef INCLUDE_OVERVIEW
-  #include "../../demo/common/overview.c"
+  #include "../../common/overview.c"
 #endif
 #ifdef INCLUDE_NODE_EDITOR
-  #include "../../demo/common/node_editor.c"
+  #include "../../common/node_editor.c"
 #endif
 
 
@@ -113,7 +136,7 @@ static const struct wl_output_listener nk_wayland_output_listener =
 //-------------------------------------------------------------------- endof WAYLAND OUTPUT INTERFACE
 
 //WAYLAND POINTER INTERFACE (mouse/touchpad)
-static void nk_wayland_pointer_enter (void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y) 
+static void nk_wayland_pointer_enter (void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y)
 {
     NK_UNUSED(data);
     NK_UNUSED(pointer);
@@ -123,7 +146,7 @@ static void nk_wayland_pointer_enter (void *data, struct wl_pointer *pointer, ui
     NK_UNUSED(surface_y);
 }
 
-static void nk_wayland_pointer_leave (void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface) 
+static void nk_wayland_pointer_leave (void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface)
 {
     NK_UNUSED(data);
     NK_UNUSED(pointer);
@@ -131,7 +154,7 @@ static void nk_wayland_pointer_leave (void *data, struct wl_pointer *pointer, ui
     NK_UNUSED(surface);
 }
 
-static void nk_wayland_pointer_motion (void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t x, wl_fixed_t y) 
+static void nk_wayland_pointer_motion (void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t x, wl_fixed_t y)
 {
     struct nk_wayland* win = (struct nk_wayland*)data;
 
@@ -140,11 +163,11 @@ static void nk_wayland_pointer_motion (void *data, struct wl_pointer *pointer, u
 
     win->mouse_pointer_x = wl_fixed_to_int(x);
     win->mouse_pointer_y = wl_fixed_to_int(y);
-    
-    nk_input_motion(&(win->ctx), win->mouse_pointer_x, win->mouse_pointer_y);
+
+    nk_input_motion(&(win->rawfb->ctx), win->mouse_pointer_x, win->mouse_pointer_y);
 }
 
-static void nk_wayland_pointer_button (void *data, struct wl_pointer *pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state) 
+static void nk_wayland_pointer_button (void *data, struct wl_pointer *pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state)
 {
     struct nk_wayland* win = (struct nk_wayland*)data;
 
@@ -155,15 +178,15 @@ static void nk_wayland_pointer_button (void *data, struct wl_pointer *pointer, u
     if (button == 272){ //left mouse button
         if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
            // printf("nk_input_button x=%d, y=%d press: 1 \n", win->mouse_pointer_x, win->mouse_pointer_y);
-            nk_input_button(&(win->ctx), NK_BUTTON_LEFT, win->mouse_pointer_x, win->mouse_pointer_y, 1);
-            
+            nk_input_button(&(win->rawfb->ctx), NK_BUTTON_LEFT, win->mouse_pointer_x, win->mouse_pointer_y, 1);
+
         } else if (state == WL_POINTER_BUTTON_STATE_RELEASED) {
-            nk_input_button(&(win->ctx), NK_BUTTON_LEFT, win->mouse_pointer_x, win->mouse_pointer_y, 0);
+            nk_input_button(&(win->rawfb->ctx), NK_BUTTON_LEFT, win->mouse_pointer_x, win->mouse_pointer_y, 0);
         }
     }
 }
 
-static void nk_wayland_pointer_axis (void *data, struct wl_pointer *pointer, uint32_t time, uint32_t axis, wl_fixed_t value) 
+static void nk_wayland_pointer_axis (void *data, struct wl_pointer *pointer, uint32_t time, uint32_t axis, wl_fixed_t value)
 {
     NK_UNUSED(data);
     NK_UNUSED(pointer);
@@ -172,12 +195,12 @@ static void nk_wayland_pointer_axis (void *data, struct wl_pointer *pointer, uin
     NK_UNUSED(value);
 }
 
-static struct wl_pointer_listener nk_wayland_pointer_listener = 
+static struct wl_pointer_listener nk_wayland_pointer_listener =
 {
-    &nk_wayland_pointer_enter, 
-    &nk_wayland_pointer_leave, 
-    &nk_wayland_pointer_motion, 
-    &nk_wayland_pointer_button, 
+    &nk_wayland_pointer_enter,
+    &nk_wayland_pointer_leave,
+    &nk_wayland_pointer_motion,
+    &nk_wayland_pointer_button,
     &nk_wayland_pointer_axis,
     NULL,
     NULL,
@@ -187,7 +210,7 @@ static struct wl_pointer_listener nk_wayland_pointer_listener =
 //-------------------------------------------------------------------- endof WAYLAND POINTER INTERFACE
 
 //WAYLAND KEYBOARD INTERFACE
-static void nk_wayland_keyboard_keymap (void *data, struct wl_keyboard *keyboard, uint32_t format, int32_t fd, uint32_t size) 
+static void nk_wayland_keyboard_keymap (void *data, struct wl_keyboard *keyboard, uint32_t format, int32_t fd, uint32_t size)
 {
     NK_UNUSED(data);
     NK_UNUSED(keyboard);
@@ -196,7 +219,7 @@ static void nk_wayland_keyboard_keymap (void *data, struct wl_keyboard *keyboard
     NK_UNUSED(size);
 }
 
-static void nk_wayland_keyboard_enter (void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys) 
+static void nk_wayland_keyboard_enter (void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys)
 {
     NK_UNUSED(data);
     NK_UNUSED(keyboard);
@@ -205,7 +228,7 @@ static void nk_wayland_keyboard_enter (void *data, struct wl_keyboard *keyboard,
     NK_UNUSED(keys);
 }
 
-static void nk_wayland_keyboard_leave (void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface) 
+static void nk_wayland_keyboard_leave (void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface)
 {
     NK_UNUSED(data);
     NK_UNUSED(keyboard);
@@ -213,7 +236,7 @@ static void nk_wayland_keyboard_leave (void *data, struct wl_keyboard *keyboard,
     NK_UNUSED(surface);
 }
 
-static void nk_wayland_keyboard_key (void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) 
+static void nk_wayland_keyboard_key (void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
 {
     NK_UNUSED(data);
     NK_UNUSED(keyboard);
@@ -234,22 +257,22 @@ static void nk_wayland_keyboard_modifiers (void *data, struct wl_keyboard *keybo
     NK_UNUSED(group);
 }
 
-static struct wl_keyboard_listener nk_wayland_keyboard_listener = 
+static struct wl_keyboard_listener nk_wayland_keyboard_listener =
 {
-    &nk_wayland_keyboard_keymap, 
-    &nk_wayland_keyboard_enter, 
-    &nk_wayland_keyboard_leave, 
-    &nk_wayland_keyboard_key, 
+    &nk_wayland_keyboard_keymap,
+    &nk_wayland_keyboard_enter,
+    &nk_wayland_keyboard_leave,
+    &nk_wayland_keyboard_key,
     &nk_wayland_keyboard_modifiers,
     NULL
 };
 //-------------------------------------------------------------------- endof WAYLAND KEYBOARD INTERFACE
 
 //WAYLAND SEAT INTERFACE
-static void seat_capabilities (void *data, struct wl_seat *seat, uint32_t capabilities) 
+static void seat_capabilities (void *data, struct wl_seat *seat, uint32_t capabilities)
 {
      struct nk_wayland* win = (struct nk_wayland*)data;
-     
+
 	if (capabilities & WL_SEAT_CAPABILITY_POINTER) {
 		struct wl_pointer *pointer = wl_seat_get_pointer (seat);
 		wl_pointer_add_listener (pointer, &nk_wayland_pointer_listener, win);
@@ -314,7 +337,7 @@ static struct xdg_toplevel_listener nk_wayland_xdg_toplevel_listener =
 
 
 // WAYLAND REGISTRY INTERFACE
-static void nk_wayland_registry_add_object (void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) 
+static void nk_wayland_registry_add_object (void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version)
 {
     struct nk_wayland* win = (struct nk_wayland*)data;
 
@@ -323,76 +346,38 @@ static void nk_wayland_registry_add_object (void *data, struct wl_registry *regi
     //printf("looking for %s interface \n", interface);
 	if (!strcmp(interface,"wl_compositor")) {
 		win->compositor = wl_registry_bind (registry, name, &wl_compositor_interface, 1);
-        
+
 	} else if (!strcmp(interface,"xdg_wm_base")) {
 		win->xdg_wm_base = wl_registry_bind (registry, name, &xdg_wm_base_interface, 1);
 		xdg_wm_base_add_listener (win->xdg_wm_base, &nk_wayland_xdg_wm_base_listener, win);
 	} else if (!strcmp(interface,"wl_shm")) {
 		win->wl_shm = wl_registry_bind (registry, name, &wl_shm_interface, 1);
-        
+
 	} else if (!strcmp(interface,"wl_seat")) {
 		win->seat = wl_registry_bind (registry, name, &wl_seat_interface, 1);
 		wl_seat_add_listener (win->seat, &seat_listener, win);
-        
+
 	} else if (!strcmp(interface, "wl_output")) {
         struct wl_output *wl_output = wl_registry_bind(registry, name, &wl_output_interface, 1);
         wl_output_add_listener(wl_output, &nk_wayland_output_listener, NULL);
     }
 }
 
-static void nk_wayland_registry_remove_object (void *data, struct wl_registry *registry, uint32_t name) 
+static void nk_wayland_registry_remove_object (void *data, struct wl_registry *registry, uint32_t name)
 {
     NK_UNUSED(data);
     NK_UNUSED(registry);
     NK_UNUSED(name);
 }
 
-static struct wl_registry_listener nk_wayland_registry_listener = 
+static struct wl_registry_listener nk_wayland_registry_listener =
 {
-    &nk_wayland_registry_add_object, 
+    &nk_wayland_registry_add_object,
     &nk_wayland_registry_remove_object
 };
 //------------------------------------------------------------------------------------------------ endof WAYLAND REGISTRY INTERFACE
 
-
-static void nk_wayland_init(struct nk_wayland* win)
-{
-    const void *tex;
-    
-    win->font_tex.pixels = win->tex_scratch;
-    win->font_tex.format = NK_FONT_ATLAS_ALPHA8;
-    win->font_tex.w = win->font_tex.h = 0;
-
-    if (0 == nk_init_default(&(win->ctx), 0)) {
-        return;
-    }
-
-    nk_font_atlas_init_default(&(win->atlas));
-    nk_font_atlas_begin(&(win->atlas));
-    tex = nk_font_atlas_bake(&(win->atlas), &(win->font_tex.w), &(win->font_tex.h), win->font_tex.format);
-    if (!tex) {
-        return;
-    }
-
-    switch(win->font_tex.format) {
-    case NK_FONT_ATLAS_ALPHA8:
-        win->font_tex.pitch = win->font_tex.w * 1;
-        break;
-    case NK_FONT_ATLAS_RGBA32:
-        win->font_tex.pitch = win->font_tex.w * 4;
-        break;
-    };
-    /* Store the font texture in tex scratch memory */
-    memcpy(win->font_tex.pixels, tex, win->font_tex.pitch * win->font_tex.h);
-    nk_font_atlas_end(&(win->atlas), nk_handle_ptr(NULL), NULL);
-    if (win->atlas.default_font)
-        nk_style_set_font(&(win->ctx), &(win->atlas.default_font->handle));
-    nk_style_load_all_cursors(&(win->ctx), win->atlas.cursors);
-    nk_wayland_scissor(win, 0, 0, win->width, win->height);
-    
-}
-
-static void nk_wayland_deinit(struct nk_wayland *win) 
+static void nk_wayland_deinit(struct nk_wayland *win)
 {
 	xdg_toplevel_destroy (win->xdg_toplevel);
 	xdg_surface_destroy (win->xdg_surface);
@@ -421,16 +406,16 @@ static void nk_wayland_surf_clear(struct nk_wayland* win)
 {
     int x, y;
     int pix_idx;
-    
-    for (y = 0; y < win->height; y++){
-        for (x = 0; x < win->width; x++){ 
-            pix_idx = y * win->width + x;
+
+    for (y = 0; y < HEIGHT; y++){
+        for (x = 0; x < WIDTH; x++){
+            pix_idx = y * WIDTH + x;
             win->data[pix_idx] = 0xFF000000;
         }
     }
 }
 
-//This causes the screen to refresh 
+//This causes the screen to refresh
 static const struct wl_callback_listener frame_listener;
 
 static void redraw(void *data, struct wl_callback *callback, uint32_t time)
@@ -442,15 +427,15 @@ static void redraw(void *data, struct wl_callback *callback, uint32_t time)
     NK_UNUSED(time);
 
     wl_callback_destroy(win->frame_callback);
-    wl_surface_damage(win->surface, 0, 0, WIDTH, HEIGHT); 
-    
+    wl_surface_damage(win->surface, 0, 0, WIDTH, HEIGHT);
+
 
 
     win->frame_callback = wl_surface_frame(win->surface);
     wl_surface_attach(win->surface, win->front_buffer, 0, 0);
     wl_callback_add_listener(win->frame_callback, &frame_listener, win);
     wl_surface_commit(win->surface);
-    
+
 }
 
 
@@ -458,30 +443,28 @@ static const struct wl_callback_listener frame_listener = {
     redraw
 };
 
-int main () 
+int main ()
 {
     long dt;
     long started;
     struct nk_wayland nk_wayland_ctx;
     struct wl_registry *registry;
     int running = 1;
-    
+    struct rawfb_pl pl;
+
     //1. Initialize display
 	nk_wayland_ctx.display = wl_display_connect (NULL);
     if (nk_wayland_ctx.display == NULL) {
         printf("no wayland display found. do you have wayland composer running? \n");
         return -1;
     }
-    
+
 	registry = wl_display_get_registry (nk_wayland_ctx.display);
 	wl_registry_add_listener (registry, &nk_wayland_registry_listener, &nk_wayland_ctx);
 	wl_display_roundtrip (nk_wayland_ctx.display);
-	
-    
-    //2. Create Window
-    nk_wayland_ctx.width = WIDTH;
-	nk_wayland_ctx.height = HEIGHT;
 
+
+    //2. Create Window
 	nk_wayland_ctx.surface = wl_compositor_create_surface (nk_wayland_ctx.compositor);
 
 	nk_wayland_ctx.xdg_surface = xdg_wm_base_get_xdg_surface(nk_wayland_ctx.xdg_wm_base, nk_wayland_ctx.surface);
@@ -508,70 +491,80 @@ int main ()
 	wl_display_roundtrip (nk_wayland_ctx.display);
 
 
-    //3. Clear window and start rendering loop    
+    //3. Clear window and start rendering loop
 	nk_wayland_surf_clear(&nk_wayland_ctx);
     wl_surface_attach (nk_wayland_ctx.surface, nk_wayland_ctx.front_buffer, 0, 0);
     wl_surface_commit (nk_wayland_ctx.surface);
 
-    nk_wayland_init(&nk_wayland_ctx);
-    
-    
+    pl.bytesPerPixel = 4;
+    pl.ashift = 24;
+    pl.rshift = 16;
+    pl.gshift = 8;
+    pl.bshift = 0;
+    pl.aloss = 0;
+    pl.rloss = 0;
+    pl.gloss = 0;
+    pl.bloss = 0;
+
+    nk_rawfb_init(nk_wayland_ctx.data, nk_wayland_ctx.tex_scratch, WIDTH, HEIGHT, WIDTH*4, pl);
+
+
     //4. rendering UI
     while (running) {
-        started = timestamp(); 
-      
-        // GUI 
-        if (nk_begin(&(nk_wayland_ctx.ctx), "Demo", nk_rect(50, 50, 200, 200),
+        started = timestamp();
+
+        // GUI
+        if (nk_begin(&(nk_wayland_ctx.rawfb->ctx), "Demo", nk_rect(50, 50, 200, 200),
             NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|
             NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE)) {
             enum {EASY, HARD};
             static int op = EASY;
             static int property = 20;
 
-            nk_layout_row_static(&(nk_wayland_ctx.ctx), 30, 80, 1);
-            if (nk_button_label(&(nk_wayland_ctx.ctx), "button")){
+            nk_layout_row_static(&(nk_wayland_ctx.rawfb->ctx), 30, 80, 1);
+            if (nk_button_label(&(nk_wayland_ctx.rawfb->ctx), "button")){
                 printf("button pressed\n");
             }
-            nk_layout_row_dynamic(&(nk_wayland_ctx.ctx), 30, 2);
-            if (nk_option_label(&(nk_wayland_ctx.ctx), "easy", op == EASY)) op = EASY;
-            if (nk_option_label(&(nk_wayland_ctx.ctx), "hard", op == HARD)) op = HARD;
-            nk_layout_row_dynamic(&(nk_wayland_ctx.ctx), 25, 1);
-            nk_property_int(&(nk_wayland_ctx.ctx), "Compression:", 0, &property, 100, 10, 1);
+            nk_layout_row_dynamic(&(nk_wayland_ctx.rawfb->ctx), 30, 2);
+            if (nk_option_label(&(nk_wayland_ctx.rawfb->ctx), "easy", op == EASY)) op = EASY;
+            if (nk_option_label(&(nk_wayland_ctx.rawfb->ctx), "hard", op == HARD)) op = HARD;
+            nk_layout_row_dynamic(&(nk_wayland_ctx.rawfb->ctx), 25, 1);
+            nk_property_int(&(nk_wayland_ctx.rawfb->ctx), "Compression:", 0, &property, 100, 10, 1);
         }
-        nk_end(&(nk_wayland_ctx.ctx));
-        
-        if (nk_window_is_closed(&(nk_wayland_ctx.ctx), "Demo")) break;
+        nk_end(&(nk_wayland_ctx.rawfb->ctx));
+
+        if (nk_window_is_closed(&(nk_wayland_ctx.rawfb->ctx), "Demo")) break;
 
         /* -------------- EXAMPLES ---------------- */
         #ifdef INCLUDE_CALCULATOR
-          calculator(&(nk_wayland_ctx.ctx));
+          calculator(&(nk_wayland_ctx.rawfb->ctx));
         #endif
         #ifdef INCLUDE_CANVAS
-          canvas(&(nk_wayland_ctx.ctx));
+          canvas(&(nk_wayland_ctx.rawfb->ctx));
         #endif
         #ifdef INCLUDE_OVERVIEW
-          overview(&(nk_wayland_ctx.ctx));
+          overview(&(nk_wayland_ctx.rawfb->ctx));
         #endif
         #ifdef INCLUDE_NODE_EDITOR
-          node_editor(&(nk_wayland_ctx.ctx));
+          node_editor(&(nk_wayland_ctx.rawfb->ctx));
         #endif
         /* ----------------------------------------- */
 
-        // Draw framebuffer 
-        nk_wayland_render(&nk_wayland_ctx, nk_rgb(30,30,30), 1);
-        
-        
+        // Draw framebuffer
+        nk_rawfb_render(nk_wayland_ctx.rawfb, nk_rgb(30,30,30), 1);
+
+
         //handle wayland stuff (send display to FB & get inputs)
-        nk_input_begin(&(nk_wayland_ctx.ctx));
+        nk_input_begin(&(nk_wayland_ctx.rawfb->ctx));
         wl_display_dispatch(nk_wayland_ctx.display);
-        nk_input_end(&(nk_wayland_ctx.ctx));
-        
-        // Timing 
+        nk_input_end(&(nk_wayland_ctx.rawfb->ctx));
+
+        // Timing
         dt = timestamp() - started;
         if (dt < DTIME)
             sleep_for(DTIME - dt);
     }
-	
+
 	nk_wayland_deinit (&nk_wayland_ctx);
 	wl_display_disconnect (nk_wayland_ctx.display);
 	return 0;

+ 0 - 0
demo/x11_rawfb/Makefile → demo/rawfb/x11/Makefile


+ 8 - 21
demo/x11_rawfb/main.c → demo/rawfb/x11/main.c

@@ -46,8 +46,8 @@
 #define NK_INCLUDE_DEFAULT_FONT
 #define NK_INCLUDE_SOFTWARE_FONT
 
-#include "../../nuklear.h"
-#include "nuklear_rawfb.h"
+#include "../../../nuklear.h"
+#include "../nuklear_rawfb.h"
 #include "nuklear_xlib.h"
 
 #define DTIME           20
@@ -126,19 +126,19 @@ sleep_for(long t)
 #endif
 
 #ifdef INCLUDE_STYLE
-  #include "../../demo/common/style.c"
+  #include "../../common/style.c"
 #endif
 #ifdef INCLUDE_CALCULATOR
-  #include "../../demo/common/calculator.c"
+  #include "../../common/calculator.c"
 #endif
 #ifdef INCLUDE_CANVAS
-  #include "../../demo/common/canvas.c"
+  #include "../../common/canvas.c"
 #endif
 #ifdef INCLUDE_OVERVIEW
-  #include "../../demo/common/overview.c"
+  #include "../../common/overview.c"
 #endif
 #ifdef INCLUDE_NODE_EDITOR
-  #include "../../demo/common/node_editor.c"
+  #include "../../common/node_editor.c"
 #endif
 
 /* ===============================================================
@@ -156,7 +156,7 @@ main(void)
     XWindow xw;
     struct rawfb_context *rawfb;
     void *fb = NULL;
-    rawfb_pl pl;
+    struct rawfb_pl pl;
     unsigned char tex_scratch[512 * 512];
 
     /* X11 */
@@ -193,19 +193,6 @@ main(void)
     rawfb = nk_rawfb_init(fb, tex_scratch, xw.width, xw.height, xw.width * 4, pl);
     if (!rawfb) running = 0;
 
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(&rawfb->ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(&rawfb->ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(&rawfb->ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(&rawfb->ctx, THEME_DARK);
-    #endif
-    #endif
-
     while (running) {
         /* Input */
         XEvent evt;

+ 12 - 19
demo/x11_rawfb/nuklear_xlib.h → demo/rawfb/x11/nuklear_xlib.h

@@ -35,7 +35,7 @@
 
 #include <X11/Xlib.h>
 
-NK_API int  nk_xlib_init(Display *dpy, Visual *vis, int screen, Window root, unsigned int w, unsigned int h, void **fb, rawfb_pl *pl);
+NK_API int  nk_xlib_init(Display *dpy, Visual *vis, int screen, Window root, unsigned int w, unsigned int h, void **fb, struct rawfb_pl *pl);
 NK_API int  nk_xlib_handle_event(Display *dpy, int screen, Window win, XEvent *evt, struct rawfb_context *rawfb);
 NK_API void nk_xlib_render(Drawable screen);
 NK_API void nk_xlib_shutdown(void);
@@ -74,7 +74,7 @@ static struct  {
 
 NK_API int
 nk_xlib_init(Display *dpy, Visual *vis, int screen, Window root,
-    unsigned int w, unsigned int h, void **fb, rawfb_pl *pl)
+    unsigned int w, unsigned int h, void **fb, struct rawfb_pl *pl)
 {
     unsigned int depth = XDefaultDepth(dpy, screen);
     xlib.dpy = dpy;
@@ -138,22 +138,15 @@ nk_xlib_init(Display *dpy, Visual *vis, int screen, Window root,
     xlib.gc = XDefaultGC(dpy, screen);
     *fb = xlib.ximg->data;
 
-    if (xlib.ximg->red_mask == 0xff0000 &&
-	xlib.ximg->green_mask == 0xff00 &&
-	xlib.ximg->blue_mask == 0xff &&
-	xlib.ximg->bits_per_pixel == 32) {
-	*pl = PIXEL_LAYOUT_XRGB_8888;
-    }
-    else if (xlib.ximg->red_mask == 0xff000000 &&
-	     xlib.ximg->green_mask == 0xff0000 &&
-	     xlib.ximg->blue_mask == 0xff00 &&
-	     xlib.ximg->bits_per_pixel == 32) {
-	*pl = PIXEL_LAYOUT_RGBX_8888;
-    }
-    else {
-	perror("nk_xlib_init(): Unrecognized pixel layout.\n");
-	return 0;
-    }
+    pl->bytesPerPixel = xlib.ximg->bits_per_pixel / 8;
+    pl->rshift = __builtin_ctzl(xlib.ximg->red_mask);
+    pl->gshift = __builtin_ctzl(xlib.ximg->green_mask);
+    pl->bshift = __builtin_ctzl(xlib.ximg->blue_mask);
+    pl->ashift = 0;
+    pl->rloss = 8 - __builtin_popcount(xlib.ximg->red_mask);
+    pl->gloss = 8 - __builtin_popcount(xlib.ximg->green_mask);
+    pl->bloss = 8 - __builtin_popcount(xlib.ximg->blue_mask);
+    pl->aloss = 8;
 
     return 1;
 }
@@ -257,7 +250,7 @@ nk_xlib_handle_event(Display *dpy, int screen, Window win, XEvent *evt, struct r
     } else if (evt->type == Expose || evt->type == ConfigureNotify) {
         /* Window resize handler */
         void *fb;
-        rawfb_pl pl;
+        struct rawfb_pl pl;
         unsigned int width, height;
         XWindowAttributes attr;
         XGetWindowAttributes(dpy, win, &attr);

+ 0 - 1083
demo/sdl2surface_rawfb/sdl2surface_rawfb.h

@@ -1,1083 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2016-2017 Patrick Rudolph <[email protected]>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
-
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
-*/
-/*
- * ==============================================================
- *
- *                              API
- *
- * ===============================================================
- */
-
- /* Adapted from nulear_rawfb.h for use with SDL_Surface by Martijn Versteegh*/
-#ifndef NK_SDLSURFACE_H_
-#define NK_SDLSURFACE_H_
-
-#include <SDL.h>
-#include <SDL_surface.h>
-
-struct sdlsurface_context *nk_sdlsurface_init(SDL_Surface *fb, float fontSize);
-void                  nk_sdlsurface_render(const struct sdlsurface_context *sdlsurface, const struct nk_color clear, const unsigned char enable_clear);
-void                  nk_sdlsurface_shutdown(struct sdlsurface_context *sdlsurface);
-
-#endif
-/*
- * ==============================================================
- *
- *                          IMPLEMENTATION
- *
- * ===============================================================
- */
-#ifdef NK_SDLSURFACE_IMPLEMENTATION
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-
-struct sdlsurface_context {
-    struct nk_context ctx;
-    struct nk_rect scissors;
-    struct SDL_Surface *fb;
-    struct SDL_Surface *font_tex;
-    struct nk_font_atlas atlas;
-};
-
-#ifndef MIN
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-#ifndef MAX
-#define MAX(a,b) ((a) < (b) ? (b) : (a))
-#endif
-
-static unsigned int
-nk_sdlsurface_color2int(const struct nk_color c, const SDL_PixelFormat *format)
-{
-    return SDL_MapRGBA(format, c.r, c.g, c.b, c.a);
-}
-
-static struct nk_color
-nk_sdlsurface_int2color(const unsigned int i, const SDL_PixelFormat *format)
-{
-    struct nk_color col = {0,0,0,0};
-
-    SDL_GetRGBA(i, format, &col.r, &col.g, &col.b, &col.a);
-
-    return col;
-}
-
-static void
-nk_sdlsurface_ctx_setpixel(const struct sdlsurface_context *sdlsurface,
-    const short x0, const short y0, const struct nk_color col)
-{
-    unsigned int c = nk_sdlsurface_color2int(col, sdlsurface->fb->format);
-    unsigned char *pixels = sdlsurface->fb->pixels;
-
-    pixels += y0 * sdlsurface->fb->pitch;
-
-    if (y0 < sdlsurface->scissors.h && y0 >= sdlsurface->scissors.y &&
-        x0 >= sdlsurface->scissors.x && x0 < sdlsurface->scissors.w) {
-
-        if (sdlsurface->fb->format->BytesPerPixel == 4) {
-            *((Uint32 *)pixels + x0) = c;
-        } else if (sdlsurface->fb->format->BytesPerPixel == 2) {
-            *((Uint16 *)pixels + x0) = c;
-        } else {
-            *((Uint8 *)pixels + x0) = c;
-        }
-    }
-}
-
-static void
-nk_sdlsurface_line_horizontal(const struct sdlsurface_context *sdlsurface,
-    const short x0, const short y, const short x1, const struct nk_color col)
-{
-    /* This function is called the most. Try to optimize it a bit...
-     * It does not check for scissors or image borders.
-     * The caller has to make sure it does no exceed bounds. */
-    unsigned int i, n;
-    unsigned char c[16 * 4];
-    unsigned char *pixels = sdlsurface->fb->pixels;
-    unsigned int bpp = sdlsurface->fb->format->BytesPerPixel;
-
-    pixels += (y * sdlsurface->fb->pitch) + (x0 * bpp);
-
-    n = (x1 - x0) * bpp;
-    if (bpp == 4) {
-        for (i = 0; i < sizeof(c) / bpp; i++)
-            ((Uint32 *)c)[i] = nk_sdlsurface_color2int(col, sdlsurface->fb->format);
-    } else if (bpp == 2) {
-        for (i = 0; i < sizeof(c) / bpp; i++)
-            ((Uint16 *)c)[i] = nk_sdlsurface_color2int(col, sdlsurface->fb->format);
-    } else {
-        for (i = 0; i < sizeof(c) / bpp; i++)
-            ((Uint8 *)c)[i] = nk_sdlsurface_color2int(col, sdlsurface->fb->format);
-    }
-
-    while (n > sizeof(c)) {
-        memcpy((void*)pixels, c, sizeof(c));
-        n -= sizeof(c); pixels += sizeof(c);
-    } for (i = 0; i < n; i++)
-        pixels[i] = c[i];
-}
-
-static void
-nk_sdlsurface_img_setpixel(const struct SDL_Surface *img,
-    const int x0, const int y0, const struct nk_color col)
-{
-    unsigned int c = nk_sdlsurface_color2int(col, img->format);
-    unsigned char *ptr;
-    NK_ASSERT(img);
-    if (y0 < img->h && y0 >= 0 && x0 >= 0 && x0 < img->w) {
-        ptr = (unsigned char *)img->pixels + (img->pitch * y0);
-
-        if (img->format == NK_FONT_ATLAS_ALPHA8) {
-            ptr[x0] = col.a;
-        } else if (img->format->BytesPerPixel == 4) {
-            ((Uint32 *)ptr)[x0] = c;
-        } else if (img->format->BytesPerPixel == 2) {
-            ((Uint16 *)ptr)[x0] = c;
-        } else {
-            ((Uint8 *)ptr)[x0] = c;
-        }
-    }
-}
-
-static struct nk_color
-nk_sdlsurface_img_getpixel(const struct SDL_Surface *img, const int x0, const int y0)
-{
-    struct nk_color col = {0, 0, 0, 0};
-    unsigned char *ptr;
-    unsigned int pixel;
-    NK_ASSERT(img);
-    if (y0 < img->h && y0 >= 0 && x0 >= 0 && x0 < img->w) {
-        ptr = (unsigned char *)img->pixels + (img->pitch * y0);
-
-        if (img->format == NK_FONT_ATLAS_ALPHA8) {
-            col.a = ptr[x0];
-            col.b = col.g = col.r = 0xff;
-        } else if (img->format->BytesPerPixel == 4) {
-            pixel = ((Uint32 *)ptr)[x0];
-            col = nk_sdlsurface_int2color(pixel, img->format);
-        } else if (img->format->BytesPerPixel == 2) {
-            pixel = ((Uint16 *)ptr)[x0];
-            col = nk_sdlsurface_int2color(pixel, img->format);
-        } else {
-            pixel = ((Uint8 *)ptr)[x0];
-            col = nk_sdlsurface_int2color(pixel, img->format);
-        }
-    } return col;
-}
-static void
-nk_sdlsurface_img_blendpixel(const struct SDL_Surface *img,
-    const int x0, const int y0, struct nk_color col)
-{
-    struct nk_color col2;
-    unsigned char inv_a;
-    if (col.a == 0)
-        return;
-
-    inv_a = 0xff - col.a;
-    col2 = nk_sdlsurface_img_getpixel(img, x0, y0);
-    col.r = (col.r * col.a + col2.r * inv_a) >> 8;
-    col.g = (col.g * col.a + col2.g * inv_a) >> 8;
-    col.b = (col.b * col.a + col2.b * inv_a) >> 8;
-    nk_sdlsurface_img_setpixel(img, x0, y0, col);
-}
-
-static void
-nk_sdlsurface_scissor(struct sdlsurface_context *sdlsurface,
-                 const float x,
-                 const float y,
-                 const float w,
-                 const float h)
-{
-    sdlsurface->scissors.x = MIN(MAX(x, 0), sdlsurface->fb->w);
-    sdlsurface->scissors.y = MIN(MAX(y, 0), sdlsurface->fb->h);
-    sdlsurface->scissors.w = MIN(MAX(w + x, 0), sdlsurface->fb->w);
-    sdlsurface->scissors.h = MIN(MAX(h + y, 0), sdlsurface->fb->h);
-}
-
-static void
-nk_sdlsurface_stroke_line(const struct sdlsurface_context *sdlsurface,
-    short x0, short y0, short x1, short y1,
-    const unsigned int line_thickness, const struct nk_color col)
-{
-    short tmp;
-    int dy, dx, stepx, stepy;
-
-    NK_UNUSED(line_thickness);
-
-    dy = y1 - y0;
-    dx = x1 - x0;
-
-    /* fast path */
-    if (dy == 0) {
-        if (dx == 0 || y0 >= sdlsurface->scissors.h || y0 < sdlsurface->scissors.y)
-            return;
-
-        if (dx < 0) {
-            /* swap x0 and x1 */
-            tmp = x1;
-            x1 = x0;
-            x0 = tmp;
-        }
-        x1 = MIN(sdlsurface->scissors.w, x1);
-        x0 = MIN(sdlsurface->scissors.w, x0);
-        x1 = MAX(sdlsurface->scissors.x, x1);
-        x0 = MAX(sdlsurface->scissors.x, x0);
-        nk_sdlsurface_line_horizontal(sdlsurface, x0, y0, x1, col);
-        return;
-    }
-    if (dy < 0) {
-        dy = -dy;
-        stepy = -1;
-    } else stepy = 1;
-
-    if (dx < 0) {
-        dx = -dx;
-        stepx = -1;
-    } else stepx = 1;
-
-    dy <<= 1;
-    dx <<= 1;
-
-    nk_sdlsurface_ctx_setpixel(sdlsurface, x0, y0, col);
-    if (dx > dy) {
-        int fraction = dy - (dx >> 1);
-        while (x0 != x1) {
-            if (fraction >= 0) {
-                y0 += stepy;
-                fraction -= dx;
-            }
-            x0 += stepx;
-            fraction += dy;
-            nk_sdlsurface_ctx_setpixel(sdlsurface, x0, y0, col);
-        }
-    } else {
-        int fraction = dx - (dy >> 1);
-        while (y0 != y1) {
-            if (fraction >= 0) {
-                x0 += stepx;
-                fraction -= dy;
-            }
-            y0 += stepy;
-            fraction += dx;
-            nk_sdlsurface_ctx_setpixel(sdlsurface, x0, y0, col);
-        }
-    }
-}
-
-static void
-nk_sdlsurface_fill_polygon(const struct sdlsurface_context *sdlsurface,
-    const struct nk_vec2i *pnts, int count, const struct nk_color col)
-{
-    int i = 0;
-    #define MAX_POINTS 64
-    int left = 10000, top = 10000, bottom = 0, right = 0;
-    int nodes, nodeX[MAX_POINTS], pixelX, pixelY, j, swap ;
-
-    if (count == 0) return;
-    if (count > MAX_POINTS)
-        count = MAX_POINTS;
-
-    /* Get polygon dimensions */
-    for (i = 0; i < count; i++) {
-        if (left > pnts[i].x)
-            left = pnts[i].x;
-        if (right < pnts[i].x)
-            right = pnts[i].x;
-        if (top > pnts[i].y)
-            top = pnts[i].y;
-        if (bottom < pnts[i].y)
-            bottom = pnts[i].y;
-    } bottom++; right++;
-
-    /* Polygon scanline algorithm released under public-domain by Darel Rex Finley, 2007 */
-    /*  Loop through the rows of the image. */
-    for (pixelY = top; pixelY < bottom; pixelY ++) {
-        nodes = 0; /*  Build a list of nodes. */
-        j = count - 1;
-        for (i = 0; i < count; i++) {
-            if (((pnts[i].y < pixelY) && (pnts[j].y >= pixelY)) ||
-                ((pnts[j].y < pixelY) && (pnts[i].y >= pixelY))) {
-                nodeX[nodes++]= (int)((float)pnts[i].x
-                     + ((float)pixelY - (float)pnts[i].y) / ((float)pnts[j].y - (float)pnts[i].y)
-                     * ((float)pnts[j].x - (float)pnts[i].x));
-            } j = i;
-        }
-
-        /*  Sort the nodes, via a simple “Bubble” sort. */
-        i = 0;
-        while (i < nodes - 1) {
-            if (nodeX[i] > nodeX[i+1]) {
-                swap = nodeX[i];
-                nodeX[i] = nodeX[i+1];
-                nodeX[i+1] = swap;
-                if (i) i--;
-            } else i++;
-        }
-        /*  Fill the pixels between node pairs. */
-        for (i = 0; i < nodes; i += 2) {
-            if (nodeX[i+0] >= right) break;
-            if (nodeX[i+1] > left) {
-                if (nodeX[i+0] < left) nodeX[i+0] = left ;
-                if (nodeX[i+1] > right) nodeX[i+1] = right;
-                for (pixelX = nodeX[i]; pixelX < nodeX[i + 1]; pixelX++)
-                    nk_sdlsurface_ctx_setpixel(sdlsurface, pixelX, pixelY, col);
-            }
-        }
-    }
-    #undef MAX_POINTS
-}
-
-static void
-nk_sdlsurface_stroke_arc(const struct sdlsurface_context *sdlsurface,
-    short x0, short y0, short w, short h, const short s,
-    const short line_thickness, const struct nk_color col)
-{
-    /* Bresenham's ellipses - modified to draw one quarter */
-    const int a2 = (w * w) / 4;
-    const int b2 = (h * h) / 4;
-    const int fa2 = 4 * a2, fb2 = 4 * b2;
-    int x, y, sigma;
-
-    NK_UNUSED(line_thickness);
-
-    if (s != 0 && s != 90 && s != 180 && s != 270) return;
-    if (w < 1 || h < 1) return;
-
-    /* Convert upper left to center */
-    h = (h + 1) / 2;
-    w = (w + 1) / 2;
-    x0 += w; y0 += h;
-
-    /* First half */
-    for (x = 0, y = h, sigma = 2*b2+a2*(1-2*h); b2*x <= a2*y; x++) {
-        if (s == 180)
-            nk_sdlsurface_ctx_setpixel(sdlsurface, x0 + x, y0 + y, col);
-        else if (s == 270)
-            nk_sdlsurface_ctx_setpixel(sdlsurface, x0 - x, y0 + y, col);
-        else if (s == 0)
-            nk_sdlsurface_ctx_setpixel(sdlsurface, x0 + x, y0 - y, col);
-        else if (s == 90)
-            nk_sdlsurface_ctx_setpixel(sdlsurface, x0 - x, y0 - y, col);
-        if (sigma >= 0) {
-            sigma += fa2 * (1 - y);
-            y--;
-        } sigma += b2 * ((4 * x) + 6);
-    }
-
-    /* Second half */
-    for (x = w, y = 0, sigma = 2*a2+b2*(1-2*w); a2*y <= b2*x; y++) {
-        if (s == 180)
-            nk_sdlsurface_ctx_setpixel(sdlsurface, x0 + x, y0 + y, col);
-        else if (s == 270)
-            nk_sdlsurface_ctx_setpixel(sdlsurface, x0 - x, y0 + y, col);
-        else if (s == 0)
-            nk_sdlsurface_ctx_setpixel(sdlsurface, x0 + x, y0 - y, col);
-        else if (s == 90)
-            nk_sdlsurface_ctx_setpixel(sdlsurface, x0 - x, y0 - y, col);
-        if (sigma >= 0) {
-            sigma += fb2 * (1 - x);
-            x--;
-        } sigma += a2 * ((4 * y) + 6);
-    }
-}
-
-static void
-nk_sdlsurface_fill_arc(const struct sdlsurface_context *sdlsurface, short x0, short y0,
-    short w, short h, const short s, const struct nk_color col)
-{
-    /* Bresenham's ellipses - modified to fill one quarter */
-    const int a2 = (w * w) / 4;
-    const int b2 = (h * h) / 4;
-    const int fa2 = 4 * a2, fb2 = 4 * b2;
-    int x, y, sigma;
-    struct nk_vec2i pnts[3];
-    if (w < 1 || h < 1) return;
-    if (s != 0 && s != 90 && s != 180 && s != 270)
-        return;
-
-    /* Convert upper left to center */
-    h = (h + 1) / 2;
-    w = (w + 1) / 2;
-    x0 += w;
-    y0 += h;
-
-    pnts[0].x = x0;
-    pnts[0].y = y0;
-    pnts[2].x = x0;
-    pnts[2].y = y0;
-
-    /* First half */
-    for (x = 0, y = h, sigma = 2*b2+a2*(1-2*h); b2*x <= a2*y; x++) {
-        if (s == 180) {
-            pnts[1].x = x0 + x; pnts[1].y = y0 + y;
-        } else if (s == 270) {
-            pnts[1].x = x0 - x; pnts[1].y = y0 + y;
-        } else if (s == 0) {
-            pnts[1].x = x0 + x; pnts[1].y = y0 - y;
-        } else if (s == 90) {
-            pnts[1].x = x0 - x; pnts[1].y = y0 - y;
-        }
-        nk_sdlsurface_fill_polygon(sdlsurface, pnts, 3, col);
-        pnts[2] = pnts[1];
-        if (sigma >= 0) {
-            sigma += fa2 * (1 - y);
-            y--;
-        } sigma += b2 * ((4 * x) + 6);
-    }
-
-    /* Second half */
-    for (x = w, y = 0, sigma = 2*a2+b2*(1-2*w); a2*y <= b2*x; y++) {
-        if (s == 180) {
-            pnts[1].x = x0 + x; pnts[1].y = y0 + y;
-        } else if (s == 270) {
-            pnts[1].x = x0 - x; pnts[1].y = y0 + y;
-        } else if (s == 0) {
-            pnts[1].x = x0 + x; pnts[1].y = y0 - y;
-        } else if (s == 90) {
-            pnts[1].x = x0 - x; pnts[1].y = y0 - y;
-        }
-        nk_sdlsurface_fill_polygon(sdlsurface, pnts, 3, col);
-        pnts[2] = pnts[1];
-        if (sigma >= 0) {
-            sigma += fb2 * (1 - x);
-            x--;
-        } sigma += a2 * ((4 * y) + 6);
-    }
-}
-
-static void
-nk_sdlsurface_stroke_rect(const struct sdlsurface_context *sdlsurface,
-    const short x, const short y, const short w, const short h,
-    const short r, const short line_thickness, const struct nk_color col)
-{
-    if (r == 0) {
-        nk_sdlsurface_stroke_line(sdlsurface, x, y, x + w, y, line_thickness, col);
-        nk_sdlsurface_stroke_line(sdlsurface, x, y + h, x + w, y + h, line_thickness, col);
-        nk_sdlsurface_stroke_line(sdlsurface, x, y, x, y + h, line_thickness, col);
-        nk_sdlsurface_stroke_line(sdlsurface, x + w, y, x + w, y + h, line_thickness, col);
-    } else {
-        const short xc = x + r;
-        const short yc = y + r;
-        const short wc = (short)(w - 2 * r);
-        const short hc = (short)(h - 2 * r);
-
-        nk_sdlsurface_stroke_line(sdlsurface, xc, y, xc + wc, y, line_thickness, col);
-        nk_sdlsurface_stroke_line(sdlsurface, x + w, yc, x + w, yc + hc, line_thickness, col);
-        nk_sdlsurface_stroke_line(sdlsurface, xc, y + h, xc + wc, y + h, line_thickness, col);
-        nk_sdlsurface_stroke_line(sdlsurface, x, yc, x, yc + hc, line_thickness, col);
-
-        nk_sdlsurface_stroke_arc(sdlsurface, xc + wc - r, y,
-                (unsigned)r*2, (unsigned)r*2, 0 , line_thickness, col);
-        nk_sdlsurface_stroke_arc(sdlsurface, x, y,
-                (unsigned)r*2, (unsigned)r*2, 90 , line_thickness, col);
-        nk_sdlsurface_stroke_arc(sdlsurface, x, yc + hc - r,
-                (unsigned)r*2, (unsigned)r*2, 270 , line_thickness, col);
-        nk_sdlsurface_stroke_arc(sdlsurface, xc + wc - r, yc + hc - r,
-                (unsigned)r*2, (unsigned)r*2, 180 , line_thickness, col);
-    }
-}
-
-static void
-nk_sdlsurface_fill_rect(const struct sdlsurface_context *sdlsurface,
-    const short x, const short y, const short w, const short h,
-    const short r, const struct nk_color col)
-{
-    int i;
-    if (r == 0) {
-        for (i = 0; i < h; i++)
-            nk_sdlsurface_stroke_line(sdlsurface, x, y + i, x + w, y + i, 1, col);
-    } else {
-        const short xc = x + r;
-        const short yc = y + r;
-        const short wc = (short)(w - 2 * r);
-        const short hc = (short)(h - 2 * r);
-
-        struct nk_vec2i 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;
-
-        nk_sdlsurface_fill_polygon(sdlsurface, pnts, 12, col);
-
-        nk_sdlsurface_fill_arc(sdlsurface, xc + wc - r, y,
-                (unsigned)r*2, (unsigned)r*2, 0 , col);
-        nk_sdlsurface_fill_arc(sdlsurface, x, y,
-                (unsigned)r*2, (unsigned)r*2, 90 , col);
-        nk_sdlsurface_fill_arc(sdlsurface, x, yc + hc - r,
-                (unsigned)r*2, (unsigned)r*2, 270 , col);
-        nk_sdlsurface_fill_arc(sdlsurface, xc + wc - r, yc + hc - r,
-                (unsigned)r*2, (unsigned)r*2, 180 , col);
-    }
-}
-
-NK_API void
-nk_sdlsurface_draw_rect_multi_color(const struct sdlsurface_context *sdlsurface,
-    const short x, const short y, const short w, const short h, struct nk_color tl,
-    struct nk_color tr, struct nk_color br, struct nk_color bl)
-{
-    int i, j;
-    struct nk_color *edge_buf;
-    struct nk_color *edge_t;
-    struct nk_color *edge_b;
-    struct nk_color *edge_l;
-    struct nk_color *edge_r;
-    struct nk_color pixel;
-
-    edge_buf = malloc(((2*w) + (2*h)) * sizeof(struct nk_color));
-    if (edge_buf == NULL)
-    return;
-
-    edge_t = edge_buf;
-    edge_b = edge_buf + w;
-    edge_l = edge_buf + (w*2);
-    edge_r = edge_buf + (w*2) + h;
-
-    /* Top and bottom edge gradients */
-    for (i=0; i<w; i++)
-    {
-    edge_t[i].r = (((((float)tr.r - tl.r)/(w-1))*i) + 0.5) + tl.r;
-    edge_t[i].g = (((((float)tr.g - tl.g)/(w-1))*i) + 0.5) + tl.g;
-    edge_t[i].b = (((((float)tr.b - tl.b)/(w-1))*i) + 0.5) + tl.b;
-    edge_t[i].a = (((((float)tr.a - tl.a)/(w-1))*i) + 0.5) + tl.a;
-
-    edge_b[i].r = (((((float)br.r - bl.r)/(w-1))*i) + 0.5) + bl.r;
-    edge_b[i].g = (((((float)br.g - bl.g)/(w-1))*i) + 0.5) + bl.g;
-    edge_b[i].b = (((((float)br.b - bl.b)/(w-1))*i) + 0.5) + bl.b;
-    edge_b[i].a = (((((float)br.a - bl.a)/(w-1))*i) + 0.5) + bl.a;
-    }
-
-    /* Left and right edge gradients */
-    for (i=0; i<h; i++)
-    {
-    edge_l[i].r = (((((float)bl.r - tl.r)/(h-1))*i) + 0.5) + tl.r;
-    edge_l[i].g = (((((float)bl.g - tl.g)/(h-1))*i) + 0.5) + tl.g;
-    edge_l[i].b = (((((float)bl.b - tl.b)/(h-1))*i) + 0.5) + tl.b;
-    edge_l[i].a = (((((float)bl.a - tl.a)/(h-1))*i) + 0.5) + tl.a;
-
-    edge_r[i].r = (((((float)br.r - tr.r)/(h-1))*i) + 0.5) + tr.r;
-    edge_r[i].g = (((((float)br.g - tr.g)/(h-1))*i) + 0.5) + tr.g;
-    edge_r[i].b = (((((float)br.b - tr.b)/(h-1))*i) + 0.5) + tr.b;
-    edge_r[i].a = (((((float)br.a - tr.a)/(h-1))*i) + 0.5) + tr.a;
-    }
-
-    for (i=0; i<h; i++) {
-    for (j=0; j<w; j++) {
-        if (i==0) {
-        nk_sdlsurface_img_blendpixel(sdlsurface->fb, x+j, y+i, edge_t[j]);
-        } else if (i==h-1) {
-        nk_sdlsurface_img_blendpixel(sdlsurface->fb, x+j, y+i, edge_b[j]);
-        } else {
-        if (j==0) {
-            nk_sdlsurface_img_blendpixel(sdlsurface->fb, x+j, y+i, edge_l[i]);
-        } else if (j==w-1) {
-            nk_sdlsurface_img_blendpixel(sdlsurface->fb, x+j, y+i, edge_r[i]);
-        } else {
-            pixel.r = (((((float)edge_r[i].r - edge_l[i].r)/(w-1))*j) + 0.5) + edge_l[i].r;
-            pixel.g = (((((float)edge_r[i].g - edge_l[i].g)/(w-1))*j) + 0.5) + edge_l[i].g;
-            pixel.b = (((((float)edge_r[i].b - edge_l[i].b)/(w-1))*j) + 0.5) + edge_l[i].b;
-            pixel.a = (((((float)edge_r[i].a - edge_l[i].a)/(w-1))*j) + 0.5) + edge_l[i].a;
-            nk_sdlsurface_img_blendpixel(sdlsurface->fb, x+j, y+i, pixel);
-        }
-        }
-    }
-    }
-
-    free(edge_buf);
-}
-
-static void
-nk_sdlsurface_fill_triangle(const struct sdlsurface_context *sdlsurface,
-    const short x0, const short y0, const short x1, const short y1,
-    const short x2, const short y2, const struct nk_color col)
-{
-    struct nk_vec2i pnts[3];
-    pnts[0].x = x0;
-    pnts[0].y = y0;
-    pnts[1].x = x1;
-    pnts[1].y = y1;
-    pnts[2].x = x2;
-    pnts[2].y = y2;
-    nk_sdlsurface_fill_polygon(sdlsurface, pnts, 3, col);
-}
-
-static void
-nk_sdlsurface_stroke_triangle(const struct sdlsurface_context *sdlsurface,
-    const short x0, const short y0, const short x1, const short y1,
-    const short x2, const short y2, const unsigned short line_thickness,
-    const struct nk_color col)
-{
-    nk_sdlsurface_stroke_line(sdlsurface, x0, y0, x1, y1, line_thickness, col);
-    nk_sdlsurface_stroke_line(sdlsurface, x1, y1, x2, y2, line_thickness, col);
-    nk_sdlsurface_stroke_line(sdlsurface, x2, y2, x0, y0, line_thickness, col);
-}
-
-static void
-nk_sdlsurface_stroke_polygon(const struct sdlsurface_context *sdlsurface,
-    const struct nk_vec2i *pnts, const int count,
-    const unsigned short line_thickness, const struct nk_color col)
-{
-    int i;
-    for (i = 1; i < count; ++i)
-        nk_sdlsurface_stroke_line(sdlsurface, pnts[i-1].x, pnts[i-1].y, pnts[i].x,
-                pnts[i].y, line_thickness, col);
-    nk_sdlsurface_stroke_line(sdlsurface, pnts[count-1].x, pnts[count-1].y,
-            pnts[0].x, pnts[0].y, line_thickness, col);
-}
-
-static void
-nk_sdlsurface_stroke_polyline(const struct sdlsurface_context *sdlsurface,
-    const struct nk_vec2i *pnts, const int count,
-    const unsigned short line_thickness, const struct nk_color col)
-{
-    int i;
-    for (i = 0; i < count-1; ++i)
-        nk_sdlsurface_stroke_line(sdlsurface, pnts[i].x, pnts[i].y,
-                 pnts[i+1].x, pnts[i+1].y, line_thickness, col);
-}
-
-static void
-nk_sdlsurface_fill_circle(const struct sdlsurface_context *sdlsurface,
-    short x0, short y0, short w, short h, const struct nk_color col)
-{
-    /* Bresenham's ellipses */
-    const int a2 = (w * w) / 4;
-    const int b2 = (h * h) / 4;
-    const int fa2 = 4 * a2, fb2 = 4 * b2;
-    int x, y, sigma;
-
-    /* Convert upper left to center */
-    h = (h + 1) / 2;
-    w = (w + 1) / 2;
-    x0 += w;
-    y0 += h;
-
-    /* First half */
-    for (x = 0, y = h, sigma = 2*b2+a2*(1-2*h); b2*x <= a2*y; x++) {
-        nk_sdlsurface_stroke_line(sdlsurface, x0 - x, y0 + y, x0 + x, y0 + y, 1, col);
-        nk_sdlsurface_stroke_line(sdlsurface, x0 - x, y0 - y, x0 + x, y0 - y, 1, col);
-        if (sigma >= 0) {
-            sigma += fa2 * (1 - y);
-            y--;
-        } sigma += b2 * ((4 * x) + 6);
-    }
-    /* Second half */
-    for (x = w, y = 0, sigma = 2*a2+b2*(1-2*w); a2*y <= b2*x; y++) {
-        nk_sdlsurface_stroke_line(sdlsurface, x0 - x, y0 + y, x0 + x, y0 + y, 1, col);
-        nk_sdlsurface_stroke_line(sdlsurface, x0 - x, y0 - y, x0 + x, y0 - y, 1, col);
-        if (sigma >= 0) {
-            sigma += fb2 * (1 - x);
-            x--;
-        } sigma += a2 * ((4 * y) + 6);
-    }
-}
-
-static void
-nk_sdlsurface_stroke_circle(const struct sdlsurface_context *sdlsurface,
-    short x0, short y0, short w, short h, const short line_thickness,
-    const struct nk_color col)
-{
-    /* Bresenham's ellipses */
-    const int a2 = (w * w) / 4;
-    const int b2 = (h * h) / 4;
-    const int fa2 = 4 * a2, fb2 = 4 * b2;
-    int x, y, sigma;
-
-    NK_UNUSED(line_thickness);
-
-    /* Convert upper left to center */
-    h = (h + 1) / 2;
-    w = (w + 1) / 2;
-    x0 += w;
-    y0 += h;
-
-    /* First half */
-    for (x = 0, y = h, sigma = 2*b2+a2*(1-2*h); b2*x <= a2*y; x++) {
-        nk_sdlsurface_ctx_setpixel(sdlsurface, x0 + x, y0 + y, col);
-        nk_sdlsurface_ctx_setpixel(sdlsurface, x0 - x, y0 + y, col);
-        nk_sdlsurface_ctx_setpixel(sdlsurface, x0 + x, y0 - y, col);
-        nk_sdlsurface_ctx_setpixel(sdlsurface, x0 - x, y0 - y, col);
-        if (sigma >= 0) {
-            sigma += fa2 * (1 - y);
-            y--;
-        } sigma += b2 * ((4 * x) + 6);
-    }
-    /* Second half */
-    for (x = w, y = 0, sigma = 2*a2+b2*(1-2*w); a2*y <= b2*x; y++) {
-        nk_sdlsurface_ctx_setpixel(sdlsurface, x0 + x, y0 + y, col);
-        nk_sdlsurface_ctx_setpixel(sdlsurface, x0 - x, y0 + y, col);
-        nk_sdlsurface_ctx_setpixel(sdlsurface, x0 + x, y0 - y, col);
-        nk_sdlsurface_ctx_setpixel(sdlsurface, x0 - x, y0 - y, col);
-        if (sigma >= 0) {
-            sigma += fb2 * (1 - x);
-            x--;
-        } sigma += a2 * ((4 * y) + 6);
-    }
-}
-
-static void
-nk_sdlsurface_stroke_curve(const struct sdlsurface_context *sdlsurface,
-    const struct nk_vec2i p1, const struct nk_vec2i p2,
-    const struct nk_vec2i p3, const struct nk_vec2i p4,
-    const unsigned int num_segments, const unsigned short line_thickness,
-    const struct nk_color col)
-{
-    unsigned int i_step, segments;
-    float t_step;
-    struct nk_vec2i last = p1;
-
-    segments = MAX(num_segments, 1);
-    t_step = 1.0f/(float)segments;
-    for (i_step = 1; i_step <= 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_sdlsurface_stroke_line(sdlsurface, last.x, last.y,
-                (short)x, (short)y, line_thickness,col);
-        last.x = (short)x; last.y = (short)y;
-    }
-}
-
-static void
-nk_sdlsurface_clear(const struct sdlsurface_context *sdlsurface, const struct nk_color col)
-{
-    nk_sdlsurface_fill_rect(sdlsurface, 0, 0, sdlsurface->fb->w, sdlsurface->fb->h, 0, col);
-}
-
-struct sdlsurface_context*
-nk_sdlsurface_init(SDL_Surface *fb, float fontSize)
-{
-    const void *tex;
-    int texh, texw;
-    struct sdlsurface_context *sdlsurface;
-
-    assert((fb->format->format == SDL_PIXELFORMAT_ARGB8888)
-               || (fb->format->format == SDL_PIXELFORMAT_RGBA8888));
-
-    sdlsurface = malloc(sizeof(struct sdlsurface_context));
-    if (!sdlsurface)
-        return NULL;
-
-    memset(sdlsurface, 0, sizeof(struct sdlsurface_context));
-
-    sdlsurface->fb = fb;
-
-    if (0 == nk_init_default(&sdlsurface->ctx, 0)) {
-    free(sdlsurface);
-    return NULL;
-    }
-
-    nk_font_atlas_init_default(&sdlsurface->atlas);
-    nk_font_atlas_begin(&sdlsurface->atlas);
-    sdlsurface->atlas.default_font = nk_font_atlas_add_default(&sdlsurface->atlas, fontSize, 0);
-    tex = nk_font_atlas_bake(&sdlsurface->atlas, &texw, &texh, NK_FONT_ATLAS_RGBA32);
-    if (!tex) {
-    free(sdlsurface);
-    return NULL;
-    }
-
-    sdlsurface->font_tex = SDL_CreateRGBSurface(0, texw, texh, 32, 0xff, 0xff00, 0xff0000, 0xff000000);
-
-    memcpy(sdlsurface->font_tex->pixels, tex, texw * texh * 4);
-
-    nk_font_atlas_end(&sdlsurface->atlas, nk_handle_ptr(NULL), NULL);
-    if (sdlsurface->atlas.default_font)
-        nk_style_set_font(&sdlsurface->ctx, &sdlsurface->atlas.default_font->handle);
-    nk_style_load_all_cursors(&sdlsurface->ctx, sdlsurface->atlas.cursors);
-    nk_sdlsurface_scissor(sdlsurface, 0, 0, sdlsurface->fb->w, sdlsurface->fb->h);
-
-    return sdlsurface;
-}
-
-static void
-nk_sdlsurface_stretch_image(const struct SDL_Surface *dst,
-    const struct SDL_Surface *src, const struct nk_rect *dst_rect,
-    const struct nk_rect *src_rect, const struct nk_rect *dst_scissors,
-    const struct nk_color *fg)
-{
-    short i, j;
-    struct nk_color col;
-    float xinc = src_rect->w / dst_rect->w;
-    float yinc = src_rect->h / dst_rect->h;
-    float xoff = src_rect->x, yoff = src_rect->y;
-
-    /* Simple nearest filtering rescaling */
-    /* TODO: use bilinear filter */
-    for (j = 0; j < (short)dst_rect->h; j++) {
-        for (i = 0; i < (short)dst_rect->w; i++) {
-            if (dst_scissors) {
-                if (i + (int)(dst_rect->x + 0.5f) < dst_scissors->x || i + (int)(dst_rect->x + 0.5f) >= dst_scissors->w)
-                    continue;
-                if (j + (int)(dst_rect->y + 0.5f) < dst_scissors->y || j + (int)(dst_rect->y + 0.5f) >= dst_scissors->h)
-                    continue;
-            }
-            col = nk_sdlsurface_img_getpixel(src, (int)xoff, (int) yoff);
-            if (col.r || col.g || col.b)
-            {
-                col.r = fg->r;
-                col.g = fg->g;
-                col.b = fg->b;
-            }
-            nk_sdlsurface_img_blendpixel(dst, i + (int)(dst_rect->x + 0.5f), j + (int)(dst_rect->y + 0.5f), col);
-            xoff += xinc;
-        }
-        xoff = src_rect->x;
-        yoff += yinc;
-    }
-}
-
-static void
-nk_sdlsurface_font_query_font_glyph(nk_handle handle, const float height,
-    struct nk_user_font_glyph *glyph, const nk_rune codepoint,
-    const 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);
-}
-
-NK_API void
-nk_sdlsurface_draw_text(const struct sdlsurface_context *sdlsurface,
-    const struct nk_user_font *font, const struct nk_rect rect,
-    const char *text, const int len, const float font_height,
-    const 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;
-    if (!len || !text) return;
-
-    x = 0;
-    glyph_len = nk_utf_decode(text, &unicode, len);
-    if (!glyph_len) return;
-
-    /* draw every glyph image */
-    while (text_len < len && glyph_len) {
-        struct nk_rect src_rect;
-        struct nk_rect dst_rect;
-        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);
-        nk_sdlsurface_font_query_font_glyph(font->userdata, font_height, &g, unicode,
-                    (next == NK_UTF_INVALID) ? '\0' : next);
-
-        /* calculate and draw glyph drawing rectangle and image */
-        char_width = g.xadvance;
-        src_rect.x = g.uv[0].x * sdlsurface->font_tex->w;
-        src_rect.y = g.uv[0].y * sdlsurface->font_tex->h;
-        src_rect.w = g.uv[1].x * sdlsurface->font_tex->w - g.uv[0].x * sdlsurface->font_tex->w;
-        src_rect.h = g.uv[1].y * sdlsurface->font_tex->h - g.uv[0].y * sdlsurface->font_tex->h;
-
-        dst_rect.x = x + g.offset.x + rect.x;
-        dst_rect.y = g.offset.y + rect.y;
-        dst_rect.w = ceil(g.width);
-        dst_rect.h = ceil(g.height);
-
-        /* Use software rescaling to blit glyph from font_text to framebuffer */
-        nk_sdlsurface_stretch_image(sdlsurface->fb, sdlsurface->font_tex, &dst_rect, &src_rect, &sdlsurface->scissors, &fg);
-
-        /* offset next glyph */
-        text_len += glyph_len;
-        x += char_width;
-        glyph_len = next_glyph_len;
-        unicode = next;
-    }
-}
-
-NK_API void
-nk_sdlsurface_drawimage(const struct sdlsurface_context *sdlsurface,
-    const int x, const int y, const int w, const int h,
-    const struct nk_image *img, const struct nk_color *col)
-{
-    struct nk_rect src_rect;
-    struct nk_rect dst_rect;
-
-    src_rect.x = img->region[0];
-    src_rect.y = img->region[1];
-    src_rect.w = img->region[2];
-    src_rect.h = img->region[3];
-
-    dst_rect.x = x;
-    dst_rect.y = y;
-    dst_rect.w = w;
-    dst_rect.h = h;
-    nk_sdlsurface_stretch_image(sdlsurface->fb, sdlsurface->font_tex, &dst_rect, &src_rect, &sdlsurface->scissors, col);
-}
-
-NK_API void
-nk_sdlsurface_shutdown(struct sdlsurface_context *sdlsurface)
-{
-    if (sdlsurface) {
-        SDL_FreeSurface(sdlsurface->font_tex);
-        nk_free(&sdlsurface->ctx);
-        memset(sdlsurface, 0, sizeof(struct sdlsurface_context));
-        free(sdlsurface);
-    }
-}
-
-
-NK_API void
-nk_sdlsurface_render(const struct sdlsurface_context *sdlsurface,
-                const struct nk_color clear,
-                const unsigned char enable_clear)
-{
-    const struct nk_command *cmd;
-    if (enable_clear)
-        nk_sdlsurface_clear(sdlsurface, clear);
-
-    nk_foreach(cmd, (struct nk_context*)&sdlsurface->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_sdlsurface_scissor((struct sdlsurface_context *)sdlsurface, 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_sdlsurface_stroke_line(sdlsurface, 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_sdlsurface_stroke_rect(sdlsurface, 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_sdlsurface_fill_rect(sdlsurface, 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_sdlsurface_stroke_circle(sdlsurface, 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_sdlsurface_fill_circle(sdlsurface, 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_sdlsurface_stroke_triangle(sdlsurface, 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_sdlsurface_fill_triangle(sdlsurface, 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_sdlsurface_stroke_polygon(sdlsurface, 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_sdlsurface_fill_polygon(sdlsurface, 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_sdlsurface_stroke_polyline(sdlsurface, 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_sdlsurface_draw_text(sdlsurface, t->font, nk_rect(t->x, t->y, t->w, t->h),
-                t->string, t->length, t->height, t->foreground);
-        } break;
-        case NK_COMMAND_CURVE: {
-            const struct nk_command_curve *q = (const struct nk_command_curve *)cmd;
-            nk_sdlsurface_stroke_curve(sdlsurface, q->begin, q->ctrl[0], q->ctrl[1],
-                q->end, 22, q->line_thickness, q->color);
-        } break;
-        case NK_COMMAND_RECT_MULTI_COLOR: {
-        const struct nk_command_rect_multi_color *q = (const struct nk_command_rect_multi_color *)cmd;
-        nk_sdlsurface_draw_rect_multi_color(sdlsurface, q->x, q->y, q->w, q->h, q->left, q->top, q->right, q->bottom);
-    } break;
-        case NK_COMMAND_IMAGE: {
-            const struct nk_command_image *q = (const struct nk_command_image *)cmd;
-            nk_sdlsurface_drawimage(sdlsurface, q->x, q->y, q->w, q->h, &q->img, &q->col);
-        } break;
-        case NK_COMMAND_ARC: {
-            assert(0 && "NK_COMMAND_ARC not implemented\n");
-        } break;
-        case NK_COMMAND_ARC_FILLED: {
-            assert(0 && "NK_COMMAND_ARC_FILLED not implemented\n");
-        } break;
-        default: break;
-        }
-    }
-    nk_clear((struct nk_context*)&sdlsurface->ctx);
-}
-#endif
-

+ 0 - 13
demo/sdl_opengl2/main.c

@@ -116,19 +116,6 @@ main(int argc, char *argv[])
     /*nk_style_load_all_cursors(ctx, atlas->cursors);*/
     /*nk_style_set_font(ctx, &roboto->handle)*/;}
 
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-    #endif
-    #endif
-
     bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
     while (running)
     {

+ 1 - 0
demo/sdl_opengl2/nuklear_sdl_gl2.h

@@ -20,6 +20,7 @@ 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);
 NK_API void                 nk_sdl_shutdown(void);
+NK_API void                 nk_sdl_handle_grab(void);
 
 #endif
 /*

+ 0 - 14
demo/sdl_opengl3/main.c

@@ -126,20 +126,6 @@ int main(int argc, char *argv[])
     /*nk_style_load_all_cursors(ctx, atlas->cursors);*/
     /*nk_style_set_font(ctx, &roboto->handle);*/}
 
-    /* style.c */
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-    #endif
-    #endif
-
     bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
     while (running)
     {

+ 1 - 0
demo/sdl_opengl3/nuklear_sdl_gl3.h

@@ -24,6 +24,7 @@ NK_API void                 nk_sdl_render(enum nk_anti_aliasing , int max_vertex
 NK_API void                 nk_sdl_shutdown(void);
 NK_API void                 nk_sdl_device_destroy(void);
 NK_API void                 nk_sdl_device_create(void);
+NK_API void                 nk_sdl_handle_grab(void);
 
 #endif
 

+ 0 - 14
demo/sdl_opengles2/main.c

@@ -209,20 +209,6 @@ int main(int argc, char* argv[])
     /*nk_style_load_all_cursors(ctx, atlas->cursors);*/
     /*nk_style_set_font(ctx, &roboto->handle)*/;}
 
-    /* style.c */
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-    #endif
-    #endif
-
 #if defined(__EMSCRIPTEN__)
     #include <emscripten.h>
     emscripten_set_main_loop_arg(MainLoop, (void*)ctx, 0, nk_true);

+ 1 - 0
demo/sdl_opengles2/nuklear_sdl_gles2.h

@@ -27,6 +27,7 @@ NK_API void                 nk_sdl_render(enum nk_anti_aliasing , int max_vertex
 NK_API void                 nk_sdl_shutdown(void);
 NK_API void                 nk_sdl_device_destroy(void);
 NK_API void                 nk_sdl_device_create(void);
+NK_API void                 nk_sdl_handle_grab(void);
 
 #endif
 

+ 1 - 13
demo/sdl_renderer/main.c

@@ -36,6 +36,7 @@
 /*#define INCLUDE_ALL */
 /*#define INCLUDE_STYLE */
 /*#define INCLUDE_CALCULATOR */
+/*#define INCLUDE_CANVAS */
 /*#define INCLUDE_OVERVIEW */
 /*#define INCLUDE_NODE_EDITOR */
 
@@ -154,19 +155,6 @@ main(int argc, char *argv[])
         nk_style_set_font(ctx, &font->handle);
     }
 
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-    #endif
-    #endif
-
     bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
     while (running)
     {

+ 5 - 1
demo/sdl_renderer/nuklear_sdl_renderer.h

@@ -11,13 +11,17 @@
 #ifndef NK_SDL_RENDERER_H_
 #define NK_SDL_RENDERER_H_
 
-#include <SDL2/SDL.h>
+#ifndef NK_SDL_RENDERER_SDL_H
+#define NK_SDL_RENDERER_SDL_H <SDL.h>
+#endif
+#include NK_SDL_RENDERER_SDL_H
 NK_API struct nk_context*   nk_sdl_init(SDL_Window *win, SDL_Renderer *renderer);
 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);
 NK_API void                 nk_sdl_shutdown(void);
+NK_API void                 nk_sdl_handle_grab(void);
 
 #if SDL_COMPILEDVERSION < SDL_VERSIONNUM(2, 0, 22)
 /* Metal API does not support cliprects with negative coordinates or large

+ 0 - 14
demo/sfml_opengl2/main.cpp

@@ -96,20 +96,6 @@ int main(void)
     /*nk_style_load_all_cursors(ctx, atlas->cursors);*/
     /*nk_style_set_font(ctx, &droid->handle);*/
 
-    /* style.c */
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-    #endif
-    #endif
-
     struct nk_colorf bg;
     bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
     while (win.isOpen())

+ 0 - 14
demo/sfml_opengl3/main.cpp

@@ -102,20 +102,6 @@ int main(void)
     /*nk_style_load_all_cursors(ctx, atlas->cursors);*/
     /*nk_style_set_font(ctx, &droid->handle);*/
 
-    /* style.c */
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-    #endif
-    #endif
-
     struct nk_colorf bg;
     bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
     while (win.isOpen())

+ 0 - 869
demo/wayland_rawfb/nuklear_raw_wayland.h

@@ -1,869 +0,0 @@
-#ifndef NK_RAW_WAYLAND_H_
-#define NK_RAW_WAYLAND_H_
-
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-
-#define WIDTH 800
-#define HEIGHT 600
-
-#ifndef MIN
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-#ifndef MAX
-#define MAX(a,b) ((a) < (b) ? (b) : (a))
-#endif
-
-typedef enum wayland_pixel_layout {
-    PIXEL_LAYOUT_XRGB_8888,
-    PIXEL_LAYOUT_RGBX_8888,
-} wayland_pl;
-
-struct wayland_img {
-    void *pixels;
-    int w, h, pitch;
-    wayland_pl pl;
-    enum nk_font_atlas_format format;
-};
-
-struct nk_wayland{
-    /*wayland vars*/
-    struct wl_display *display;
-    struct wl_compositor *compositor;
-    struct xdg_wm_base *xdg_wm_base;
-    struct wl_shm *wl_shm;
-    struct wl_seat* seat;
-    struct wl_callback *frame_callback;
-    struct wl_surface *surface;
-	struct xdg_surface *xdg_surface;
-	struct xdg_toplevel *xdg_toplevel;
-	struct wl_buffer *front_buffer;
-
-    
-    /*nuklear vars*/
-    struct nk_context ctx;
-    struct nk_rect scissors;
-    struct nk_font_atlas atlas;
-    struct wayland_img font_tex;
-	int32_t width, height;
-	int32_t *data;
-    int mouse_pointer_x;
-    int mouse_pointer_y;
-    uint8_t tex_scratch[512 * 512];
-    
-};
-
-static uint32_t nk_color_to_xrgb8888(struct nk_color col)
-{
-    return (col.a << 24) + (col.r << 16) + (col.g << 8) + col.b;
-}
-
-static struct nk_color nk_wayland_int2color(const unsigned int i, wayland_pl pl)
-{
-    struct nk_color col = {0,0,0,0};
-
-    switch (pl) {
-    case PIXEL_LAYOUT_RGBX_8888:
-        col.r = (i >> 24) & 0xff;
-        col.g = (i >> 16) & 0xff;
-        col.b = (i >> 8) & 0xff;
-        col.a = i & 0xff;
-        break;
-    case PIXEL_LAYOUT_XRGB_8888:
-        col.a = (i >> 24) & 0xff;
-        col.r = (i >> 16) & 0xff;
-        col.g = (i >> 8) & 0xff;
-        col.b = i & 0xff;
-        break;
-
-    default:
-        perror("nk_rawfb_int2color(): Unsupported pixel layout.\n");
-        break;
-    }
-    return col;
-}
-
-static unsigned int nk_wayland_color2int(const struct nk_color c, wayland_pl pl)
-{
-    unsigned int res = 0;
-
-    switch (pl) {
-    case PIXEL_LAYOUT_RGBX_8888:
-        res |= c.r << 24;
-        res |= c.g << 16;
-        res |= c.b << 8;
-        res |= c.a;
-        break;
-        
-    case PIXEL_LAYOUT_XRGB_8888:
-        res |= c.a << 24;
-        res |= c.r << 16;
-        res |= c.g << 8;
-        res |= c.b;
-        break;
-
-    default:
-        perror("nk_rawfb_color2int(): Unsupported pixel layout.\n");
-        break;
-    }
-    return (res);
-}
-
-static void nk_wayland_ctx_setpixel(const struct nk_wayland* win,
-    const short x0, const short y0, const struct nk_color col)
-{
-    uint32_t c = nk_color_to_xrgb8888(col);
-    uint32_t *pixels = (uint32_t *)win->data;
-    unsigned int *ptr;
-
-    pixels += (y0 * win->width);
-    ptr = (unsigned int *)pixels + x0;
-
-    if (y0 < win->scissors.h && y0 >= win->scissors.y && x0 >= win->scissors.x && x0 < win->scissors.w){
-        *ptr = c;
-    }else {
-        printf("out of bound! \n");
-    }
-}
-
-static void nk_wayland_fill_polygon(const struct nk_wayland* win, const struct nk_vec2i *pnts, int count, const struct nk_color col)
-{
-    int i = 0;
-    //#define MAX_POINTS 64
-    int left = 10000, top = 10000, bottom = 0, right = 0;
-    int nodes, nodeX[1024], pixelX, pixelY, j, swap ;
-
-    if (count == 0) return;
-    if (count > 1024)
-        count = 1024;
-
-    /* Get polygon dimensions */
-    for (i = 0; i < count; i++) {
-        if (left > pnts[i].x)
-            left = pnts[i].x;
-        if (right < pnts[i].x)
-            right = pnts[i].x;
-        if (top > pnts[i].y)
-            top = pnts[i].y;
-        if (bottom < pnts[i].y)
-            bottom = pnts[i].y;
-    } bottom++; right++;
-
-    /* Polygon scanline algorithm released under public-domain by Darel Rex Finley, 2007 */
-    /*  Loop through the rows of the image. */
-    for (pixelY = top; pixelY < bottom; pixelY ++) {
-        nodes = 0; /*  Build a list of nodes. */
-        j = count - 1;
-        for (i = 0; i < count; i++) {
-            if (((pnts[i].y < pixelY) && (pnts[j].y >= pixelY)) ||
-                ((pnts[j].y < pixelY) && (pnts[i].y >= pixelY))) {
-                nodeX[nodes++]= (int)((float)pnts[i].x
-                     + ((float)pixelY - (float)pnts[i].y) / ((float)pnts[j].y - (float)pnts[i].y)
-                     * ((float)pnts[j].x - (float)pnts[i].x));
-            } j = i;
-        }
-
-        /*  Sort the nodes, via a simple “Bubble” sort. */
-        i = 0;
-        while (i < nodes - 1) {
-            if (nodeX[i] > nodeX[i+1]) {
-                swap = nodeX[i];
-                nodeX[i] = nodeX[i+1];
-                nodeX[i+1] = swap;
-                if (i) i--;
-            } else i++;
-        }
-        /*  Fill the pixels between node pairs. */
-        for (i = 0; i < nodes; i += 2) {
-            if (nodeX[i+0] >= right) break;
-            if (nodeX[i+1] > left) {
-                if (nodeX[i+0] < left) nodeX[i+0] = left ;
-                if (nodeX[i+1] > right) nodeX[i+1] = right;
-                for (pixelX = nodeX[i]; pixelX < nodeX[i + 1]; pixelX++)
-                    nk_wayland_ctx_setpixel(win, pixelX, pixelY, col);
-            }
-        }
-    }
-}
-
-static void nk_wayland_fill_arc(const struct nk_wayland* win, short x0, short y0, short w, short h, const short s, const struct nk_color col)
-{
-    /* Bresenham's ellipses - modified to fill one quarter */
-    const int a2 = (w * w) / 4;
-    const int b2 = (h * h) / 4;
-    const int fa2 = 4 * a2, fb2 = 4 * b2;
-    int x, y, sigma;
-    struct nk_vec2i pnts[3];
-    if (w < 1 || h < 1) return;
-    if (s != 0 && s != 90 && s != 180 && s != 270)
-        return;
-
-    /* Convert upper left to center */
-    h = (h + 1) / 2;
-    w = (w + 1) / 2;
-    x0 += w;
-    y0 += h;
-
-    pnts[0].x = x0;
-    pnts[0].y = y0;
-    pnts[2].x = x0;
-    pnts[2].y = y0;
-
-    /* First half */
-    for (x = 0, y = h, sigma = 2*b2+a2*(1-2*h); b2*x <= a2*y; x++) {
-        if (s == 180) {
-            pnts[1].x = x0 + x; pnts[1].y = y0 + y;
-        } else if (s == 270) {
-            pnts[1].x = x0 - x; pnts[1].y = y0 + y;
-        } else if (s == 0) {
-            pnts[1].x = x0 + x; pnts[1].y = y0 - y;
-        } else if (s == 90) {
-            pnts[1].x = x0 - x; pnts[1].y = y0 - y;
-        }
-        nk_wayland_fill_polygon(win, pnts, 3, col);
-        pnts[2] = pnts[1];
-        if (sigma >= 0) {
-            sigma += fa2 * (1 - y);
-            y--;
-        } sigma += b2 * ((4 * x) + 6);
-    }
-
-    /* Second half */
-    for (x = w, y = 0, sigma = 2*a2+b2*(1-2*w); a2*y <= b2*x; y++) {
-        if (s == 180) {
-            pnts[1].x = x0 + x; pnts[1].y = y0 + y;
-        } else if (s == 270) {
-            pnts[1].x = x0 - x; pnts[1].y = y0 + y;
-        } else if (s == 0) {
-            pnts[1].x = x0 + x; pnts[1].y = y0 - y;
-        } else if (s == 90) {
-            pnts[1].x = x0 - x; pnts[1].y = y0 - y;
-        }
-        nk_wayland_fill_polygon(win, pnts, 3, col);
-        pnts[2] = pnts[1];
-        if (sigma >= 0) {
-            sigma += fb2 * (1 - x);
-            x--;
-        } sigma += a2 * ((4 * y) + 6);
-    }
-}
-
-static void nk_wayland_img_setpixel(const struct wayland_img *img, const int x0, const int y0, const struct nk_color col)
-{
-    unsigned int c = nk_wayland_color2int(col, img->pl);
-    unsigned char *ptr;
-    unsigned int *pixel;
-    NK_ASSERT(img);
-    if (y0 < img->h && y0 >= 0 && x0 >= 0 && x0 < img->w) {
-        ptr = (unsigned char *)img->pixels + (img->pitch * y0);
-	pixel = (unsigned int *)ptr;
-
-        if (img->format == NK_FONT_ATLAS_ALPHA8) {
-            ptr[x0] = col.a;
-        } else {
-	    pixel[x0] = c;
-        }
-    }
-}
-
-static struct nk_color nk_wayland_getpixel(const struct nk_wayland* win, const int x0, const int y0)
-{
-    struct nk_color col = {0, 0, 0, 0};
-    uint32_t *ptr;
-
-    if (y0 < win->height && y0 >= 0 && x0 >= 0 && x0 < win->width) {
-        ptr = (uint32_t *)win->data + (y0 * win->width);
-
-        col = nk_wayland_int2color(*ptr, PIXEL_LAYOUT_XRGB_8888);
-    } 
-    
-    return col;
-}
-
-static struct nk_color nk_wayland_img_getpixel(const struct wayland_img *img, const int x0, const int y0)
-{
-    struct nk_color col = {0, 0, 0, 0};
-    unsigned char *ptr;
-    unsigned int pixel;
-    NK_ASSERT(img);
-    if (y0 < img->h && y0 >= 0 && x0 >= 0 && x0 < img->w) {
-        ptr = (unsigned char *)img->pixels + (img->pitch * y0);
-
-        if (img->format == NK_FONT_ATLAS_ALPHA8) {
-            col.a = ptr[x0];
-            col.b = col.g = col.r = 0xff;
-        } else {
-            pixel = ((unsigned int *)ptr)[x0];
-            col = nk_wayland_int2color(pixel, img->pl);
-        }
-    } return col;
-}
-
-static void nk_wayland_blendpixel(const struct nk_wayland* win, const int x0, const int y0, struct nk_color col)
-{
-    struct nk_color col2;
-    unsigned char inv_a;
-    if (col.a == 0)
-        return;
-
-    inv_a = 0xff - col.a;
-    col2 = nk_wayland_getpixel(win, x0, y0);
-    col.r = (col.r * col.a + col2.r * inv_a) >> 8;
-    col.g = (col.g * col.a + col2.g * inv_a) >> 8;
-    col.b = (col.b * col.a + col2.b * inv_a) >> 8;
-    nk_wayland_ctx_setpixel(win, x0, y0, col);
-}
-
-static void nk_wayland_img_blendpixel(const struct wayland_img *img, const int x0, const int y0, struct nk_color col)
-{
-    struct nk_color col2;
-    unsigned char inv_a;
-    if (col.a == 0)
-        return;
-
-    inv_a = 0xff - col.a;
-    col2 = nk_wayland_img_getpixel(img, x0, y0);
-    col.r = (col.r * col.a + col2.r * inv_a) >> 8;
-    col.g = (col.g * col.a + col2.g * inv_a) >> 8;
-    col.b = (col.b * col.a + col2.b * inv_a) >> 8;
-    nk_wayland_img_setpixel(img, x0, y0, col);
-}
-
-static void nk_wayland_line_horizontal(const struct nk_wayland* win, const short x0, const short y, const short x1, const struct nk_color col)
-{
-    /* This function is called the most. Try to optimize it a bit...
-     * It does not check for scissors or image borders.
-     * The caller has to make sure it does no exceed bounds. */
-    unsigned int i, n;
-    unsigned int c[16];
-    unsigned char *pixels = (uint8_t*)win->data;
-    unsigned int *ptr;
-
-    pixels += (y * (win->width * 4));
-    ptr = (unsigned int *)pixels + x0;
-
-    n = x1 - x0;
-    for (i = 0; i < sizeof(c) / sizeof(c[0]); i++)
-        c[i] = nk_color_to_xrgb8888(col);
-
-    while (n > 16) {
-        memcpy((void *)ptr, c, sizeof(c));
-        n -= 16; ptr += 16;
-    } for (i = 0; i < n; i++)
-        ptr[i] = c[i];
-}
-
-
-static void nk_wayland_scissor(struct nk_wayland* win, const float x, const float y, const float w, const float h)
-{
-    win->scissors.x = MIN(MAX(x, 0), WIDTH);
-    win->scissors.y = MIN(MAX(y, 0), HEIGHT);
-    win->scissors.w = MIN(MAX(w + x, 0), WIDTH);
-    win->scissors.h = MIN(MAX(h + y, 0), HEIGHT);
-}
-
-static void nk_wayland_stroke_line(const struct nk_wayland* win, short x0, short y0, short x1, short y1, const unsigned int line_thickness, const struct nk_color col)
-{
-    short tmp;
-    int dy, dx, stepx, stepy;
-
-    NK_UNUSED(line_thickness);
-
-    dy = y1 - y0;
-    dx = x1 - x0;
-    
-    //printf("\n\n\n\n");
-    // fast path
-    if (dy == 0) {
-        if (dx == 0 || y0 >= win->scissors.h || y0 < win->scissors.y){
-            return;
-        }
-
-        if (dx < 0) {
-            // swap x0 and x1
-            tmp = x1;
-            x1 = x0;
-            x0 = tmp;
-        }
-        x1 = MIN(win->scissors.w, x1);
-        x0 = MIN(win->scissors.w, x0);
-        x1 = MAX(win->scissors.x, x1);
-        x0 = MAX(win->scissors.x, x0);
-        nk_wayland_line_horizontal(win, x0, y0, x1, col);
-        return;
-    }
-    if (dy < 0) {
-        dy = -dy;
-        stepy = -1;
-    } else stepy = 1;
-
-    if (dx < 0) {
-        dx = -dx;
-        stepx = -1;
-    } else stepx = 1;
-
-    dy <<= 1;
-    dx <<= 1;
-
-    nk_wayland_ctx_setpixel(win, x0, y0, col);
-    if (dx > dy) {
-        int fraction = dy - (dx >> 1);
-        while (x0 != x1) {
-            if (fraction >= 0) {
-                y0 += stepy;
-                fraction -= dx;
-            }
-            x0 += stepx;
-            fraction += dy;
-            nk_wayland_ctx_setpixel(win, x0, y0, col);
-        }
-    } else {
-        int fraction = dx - (dy >> 1);
-        while (y0 != y1) {
-            if (fraction >= 0) {
-                x0 += stepx;
-                fraction -= dy;
-            }
-            y0 += stepy;
-            fraction += dx;
-            nk_wayland_ctx_setpixel(win, x0, y0, col);
-        }
-    }
-}
-
-static void
-nk_wayland_fill_rect(const struct nk_wayland* win,
-    const short x, const short y, const short w, const short h,
-    const short r, const struct nk_color col)
-{
-    int i;
-    if (r == 0) {
-        for (i = 0; i < h; i++)
-            nk_wayland_stroke_line(win, x, y + i, x + w, y + i, 1, col);
-    } else {
-        const short xc = x + r;
-        const short yc = y + r;
-        const short wc = (short)(w - 2 * r);
-        const short hc = (short)(h - 2 * r);
-
-        struct nk_vec2i 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;
-
-        nk_wayland_fill_polygon(win, pnts, 12, col);
-
-        nk_wayland_fill_arc(win, xc + wc - r, y,
-                (unsigned)r*2, (unsigned)r*2, 0 , col);
-        nk_wayland_fill_arc(win, x, y,
-                (unsigned)r*2, (unsigned)r*2, 90 , col);
-        nk_wayland_fill_arc(win, x, yc + hc - r,
-                (unsigned)r*2, (unsigned)r*2, 270 , col);
-        nk_wayland_fill_arc(win, xc + wc - r, yc + hc - r,
-                (unsigned)r*2, (unsigned)r*2, 180 , col);
-    }
-}
-
-static void nk_wayland_stroke_arc(const struct nk_wayland* win,
-    short x0, short y0, short w, short h, const short s,
-    const short line_thickness, const struct nk_color col)
-{
-    /* Bresenham's ellipses - modified to draw one quarter */
-    const int a2 = (w * w) / 4;
-    const int b2 = (h * h) / 4;
-    const int fa2 = 4 * a2, fb2 = 4 * b2;
-    int x, y, sigma;
-
-    NK_UNUSED(line_thickness);
-
-    if (s != 0 && s != 90 && s != 180 && s != 270) return;
-    if (w < 1 || h < 1) return;
-
-    /* Convert upper left to center */
-    h = (h + 1) / 2;
-    w = (w + 1) / 2;
-    x0 += w; y0 += h;
-
-    /* First half */
-    for (x = 0, y = h, sigma = 2*b2+a2*(1-2*h); b2*x <= a2*y; x++) {
-        if (s == 180)
-            nk_wayland_ctx_setpixel(win, x0 + x, y0 + y, col);
-        else if (s == 270)
-            nk_wayland_ctx_setpixel(win, x0 - x, y0 + y, col);
-        else if (s == 0)
-            nk_wayland_ctx_setpixel(win, x0 + x, y0 - y, col);
-        else if (s == 90)
-            nk_wayland_ctx_setpixel(win, x0 - x, y0 - y, col);
-        if (sigma >= 0) {
-            sigma += fa2 * (1 - y);
-            y--;
-        } sigma += b2 * ((4 * x) + 6);
-    }
-
-    /* Second half */
-    for (x = w, y = 0, sigma = 2*a2+b2*(1-2*w); a2*y <= b2*x; y++) {
-        if (s == 180)
-            nk_wayland_ctx_setpixel(win, x0 + x, y0 + y, col);
-        else if (s == 270)
-            nk_wayland_ctx_setpixel(win, x0 - x, y0 + y, col);
-        else if (s == 0)
-            nk_wayland_ctx_setpixel(win, x0 + x, y0 - y, col);
-        else if (s == 90)
-            nk_wayland_ctx_setpixel(win, x0 - x, y0 - y, col);
-        if (sigma >= 0) {
-            sigma += fb2 * (1 - x);
-            x--;
-        } sigma += a2 * ((4 * y) + 6);
-    }
-}
-
-
-
-
-static void nk_wayland_stroke_rect(const struct nk_wayland* win,
-    const short x, const short y, const short w, const short h,
-    const short r, const short line_thickness, const struct nk_color col)
-{
-    if (r == 0) {
-        nk_wayland_stroke_line(win, x, y, x + w, y, line_thickness, col);
-        nk_wayland_stroke_line(win, x, y + h, x + w, y + h, line_thickness, col);
-        nk_wayland_stroke_line(win, x, y, x, y + h, line_thickness, col);
-        nk_wayland_stroke_line(win, x + w, y, x + w, y + h, line_thickness, col);
-    } else {
-        const short xc = x + r;
-        const short yc = y + r;
-        const short wc = (short)(w - 2 * r);
-        const short hc = (short)(h - 2 * r);
-
-        nk_wayland_stroke_line(win, xc, y, xc + wc, y, line_thickness, col);
-        nk_wayland_stroke_line(win, x + w, yc, x + w, yc + hc, line_thickness, col);
-        nk_wayland_stroke_line(win, xc, y + h, xc + wc, y + h, line_thickness, col);
-        nk_wayland_stroke_line(win, x, yc, x, yc + hc, line_thickness, col);
-
-        nk_wayland_stroke_arc(win, xc + wc - r, y,
-                (unsigned)r*2, (unsigned)r*2, 0 , line_thickness, col);
-        nk_wayland_stroke_arc(win, x, y,
-                (unsigned)r*2, (unsigned)r*2, 90 , line_thickness, col);
-        nk_wayland_stroke_arc(win, x, yc + hc - r,
-                (unsigned)r*2, (unsigned)r*2, 270 , line_thickness, col);
-        nk_wayland_stroke_arc(win, xc + wc - r, yc + hc - r,
-                (unsigned)r*2, (unsigned)r*2, 180 , line_thickness, col);
-    }
-}
-
-static void nk_wayland_fill_triangle(const struct nk_wayland *win,
-    const short x0, const short y0, const short x1, const short y1,
-    const short x2, const short y2, const struct nk_color col)
-{
-    struct nk_vec2i pnts[3];
-    pnts[0].x = x0;
-    pnts[0].y = y0;
-    pnts[1].x = x1;
-    pnts[1].y = y1;
-    pnts[2].x = x2;
-    pnts[2].y = y2;
-    nk_wayland_fill_polygon(win, pnts, 3, col);
-}
-
-static void nk_wayland_clear(const struct nk_wayland *win, const struct nk_color col)
-{
-    nk_wayland_fill_rect(win, 0, 0, win->width, win->height, 0, col);
-}
-
-static void nk_wayland_fill_circle(struct nk_wayland* win, short x0, short y0, short w, short h, const struct nk_color col)
-{
-    /* Bresenham's ellipses */
-    const int a2 = (w * w) / 4;
-    const int b2 = (h * h) / 4;
-    const int fa2 = 4 * a2, fb2 = 4 * b2;
-    int x, y, sigma;
-
-    /* Convert upper left to center */
-    h = (h + 1) / 2;
-    w = (w + 1) / 2;
-    x0 += w;
-    y0 += h;
-
-    /* First half */
-    for (x = 0, y = h, sigma = 2*b2+a2*(1-2*h); b2*x <= a2*y; x++) {
-        nk_wayland_stroke_line(win, x0 - x, y0 + y, x0 + x, y0 + y, 1, col);
-        nk_wayland_stroke_line(win, x0 - x, y0 - y, x0 + x, y0 - y, 1, col);
-        if (sigma >= 0) {
-            sigma += fa2 * (1 - y);
-            y--;
-        } sigma += b2 * ((4 * x) + 6);
-    }
-    /* Second half */
-    for (x = w, y = 0, sigma = 2*a2+b2*(1-2*w); a2*y <= b2*x; y++) {
-        nk_wayland_stroke_line(win, x0 - x, y0 + y, x0 + x, y0 + y, 1, col);
-        nk_wayland_stroke_line(win, x0 - x, y0 - y, x0 + x, y0 - y, 1, col);
-        if (sigma >= 0) {
-            sigma += fb2 * (1 - x);
-            x--;
-        } sigma += a2 * ((4 * y) + 6);
-    }
-}
-/**
- * Copy wayland_img into nk_wayland with scissor & stretch
- */ 
-static void nk_wayland_copy_image(const struct nk_wayland *win, const struct wayland_img *src, 
-    const struct nk_rect *dst_rect,
-    const struct nk_rect *src_rect, 
-    const struct nk_rect *dst_scissors,
-    const struct nk_color *fg)
-{
-    short i, j;
-    struct nk_color col;
-    float xinc = src_rect->w / dst_rect->w;
-    float yinc = src_rect->h / dst_rect->h;
-    float xoff = src_rect->x, yoff = src_rect->y;
-
-    // Simple nearest filtering rescaling 
-    // TODO: use bilinear filter 
-    for (j = 0; j < (short)dst_rect->h; j++) {
-        for (i = 0; i < (short)dst_rect->w; i++) {
-            if (dst_scissors) {
-                if (i + (int)(dst_rect->x + 0.5f) < dst_scissors->x || i + (int)(dst_rect->x + 0.5f) >= dst_scissors->w)
-                    continue;
-                if (j + (int)(dst_rect->y + 0.5f) < dst_scissors->y || j + (int)(dst_rect->y + 0.5f) >= dst_scissors->h)
-                    continue;
-            }
-            col = nk_wayland_img_getpixel(src, (int)xoff, (int) yoff);
-	    if (col.r || col.g || col.b)
-	    {
-		col.r = fg->r;
-		col.g = fg->g;
-		col.b = fg->b;
-	    }
-            nk_wayland_blendpixel(win, i + (int)(dst_rect->x + 0.5f), j + (int)(dst_rect->y + 0.5f), col);
-            xoff += xinc;
-        }
-        xoff = src_rect->x;
-        yoff += yinc;
-    }
-}
-
-static void nk_wayland_font_query_font_glyph(nk_handle handle, const float height, struct nk_user_font_glyph *glyph, const nk_rune codepoint, const 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);
-}
-
-void nk_wayland_draw_text(const struct nk_wayland *win, const struct nk_user_font *font, const struct nk_rect rect, const char *text, const int len, const float font_height, const 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;
-    if (!len || !text) return;
-
-    x = 0;
-    glyph_len = nk_utf_decode(text, &unicode, len);
-    if (!glyph_len) return;
-
-    // draw every glyph image 
-    while (text_len < len && glyph_len) {
-        struct nk_rect src_rect;
-        struct nk_rect dst_rect;
-        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);
-        nk_wayland_font_query_font_glyph(font->userdata, font_height, &g, unicode,
-                    (next == NK_UTF_INVALID) ? '\0' : next);
-
-        //calculate and draw glyph drawing rectangle and image 
-        char_width = g.xadvance;
-        src_rect.x = g.uv[0].x * win->font_tex.w;
-        src_rect.y = g.uv[0].y * win->font_tex.h;
-        src_rect.w = g.uv[1].x * win->font_tex.w - g.uv[0].x * win->font_tex.w;
-        src_rect.h = g.uv[1].y * win->font_tex.h - g.uv[0].y * win->font_tex.h;
-
-        dst_rect.x = x + g.offset.x + rect.x;
-        dst_rect.y = g.offset.y + rect.y;
-        dst_rect.w = ceilf(g.width);
-        dst_rect.h = ceilf(g.height);
-
-        // Use software rescaling to blit glyph from font_text to framebuffer 
-        nk_wayland_copy_image(win, &(win->font_tex), &dst_rect, &src_rect, &(win->scissors), &fg);
-
-        // offset next glyph 
-        text_len += glyph_len;
-        x += char_width;
-        glyph_len = next_glyph_len;
-        unicode = next;
-    }
-}
-
-static void nk_wayland_render(struct nk_wayland *win, const struct nk_color clear, const unsigned char enable_clear)
-{
-    const struct nk_command *cmd;
-    const struct nk_command_text *tx;
-    const struct nk_command_scissor *s;
-    const struct nk_command_rect_filled *rf;
-    const struct nk_command_rect *r;
-    const struct nk_command_circle_filled *c;
-    const struct nk_command_triangle_filled *t;
-    const struct nk_command_line *l;
-    const struct nk_command_polygon_filled *p;
-    
-    if (enable_clear)
-        nk_wayland_clear(win, clear);
-
-    nk_foreach(cmd, (struct nk_context*)&(win->ctx)) {
-        switch (cmd->type) {
-        case NK_COMMAND_NOP: 
-            //printf("NK_COMMAND_NOP \n");
-            break;
-            
-        case NK_COMMAND_SCISSOR:
-            s = (const struct nk_command_scissor*)cmd;
-            nk_wayland_scissor(win, s->x, s->y, s->w, s->h);
-            break;
-            
-        case NK_COMMAND_LINE:
-            l = (const struct nk_command_line *)cmd;
-            nk_wayland_stroke_line(win, l->begin.x, l->begin.y, l->end.x, l->end.y, l->line_thickness, l->color);
-            break;
-            
-        case NK_COMMAND_RECT:
-            r = (const struct nk_command_rect *)cmd;
-            nk_wayland_stroke_rect(win, r->x, r->y, r->w, r->h, (unsigned short)r->rounding, r->line_thickness, r->color);
-            break;
-        
-        case NK_COMMAND_RECT_FILLED:
-            rf = (const struct nk_command_rect_filled *)cmd;
-            nk_wayland_fill_rect(win, rf->x, rf->y, rf->w, rf->h, (unsigned short)rf->rounding, rf->color);
-            break;
-            
-        case NK_COMMAND_CIRCLE:
-          //  printf("NK_COMMAND_CIRCLE \n");
-            //const struct nk_command_circle *c = (const struct nk_command_circle *)cmd;
-            //nk_rawfb_stroke_circle(rawfb, c->x, c->y, c->w, c->h, c->line_thickness, c->color);
-            break;
-            
-        case NK_COMMAND_CIRCLE_FILLED:
-            c = (const struct nk_command_circle_filled *)cmd;
-            nk_wayland_fill_circle(win, c->x, c->y, c->w, c->h, c->color);
-            
-            //const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
-            //nk_rawfb_fill_circle(rawfb, c->x, c->y, c->w, c->h, c->color);
-            break;
-        
-        case NK_COMMAND_TRIANGLE:
-            //printf("NK_COMMAND_TRIANGLE \n");
-            //const struct nk_command_triangle*t = (const struct nk_command_triangle*)cmd;
-            //nk_rawfb_stroke_triangle(rawfb, 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:
-            t = (const struct nk_command_triangle_filled *)cmd;
-            nk_wayland_fill_triangle(win, 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:
-          //  printf("NK_COMMAND_POLYGON \n");
-            //const struct nk_command_polygon *p =(const struct nk_command_polygon*)cmd;
-            //nk_rawfb_stroke_polygon(rawfb, p->points, p->point_count, p->line_thickness,p->color);
-            break;
-        
-        case NK_COMMAND_POLYGON_FILLED:
-           // printf("NK_COMMAND_POLYGON_FILLED \n");
-            p = (const struct nk_command_polygon_filled *)cmd;
-            nk_wayland_fill_polygon(win, p->points, p->point_count, p->color);
-            break;
-        
-        case NK_COMMAND_POLYLINE:
-           // printf("NK_COMMAND_POLYLINE \n");
-            //const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd;
-            //nk_rawfb_stroke_polyline(rawfb, p->points, p->point_count, p->line_thickness, p->color);
-            break;
-        
-        case NK_COMMAND_TEXT:
-            tx = (const struct nk_command_text*)cmd;
-            nk_wayland_draw_text(win, tx->font, nk_rect(tx->x, tx->y, tx->w, tx->h), tx->string, tx->length, tx->height, tx->foreground);
-            break;
-        
-        case NK_COMMAND_CURVE:
-         //    printf("NK_COMMAND_CURVE \n");
-            //const struct nk_command_curve *q = (const struct nk_command_curve *)cmd;
-            //nk_rawfb_stroke_curve(rawfb, q->begin, q->ctrl[0], q->ctrl[1], q->end, 22, q->line_thickness, q->color);
-            break;
-        
-        case NK_COMMAND_RECT_MULTI_COLOR:
-          //  printf("NK_COMMAND_RECT_MULTI_COLOR \n");
-            //const struct nk_command_rect_multi_color *q = (const struct nk_command_rect_multi_color *)cmd;
-            //nk_rawfb_draw_rect_multi_color(rawfb, q->x, q->y, q->w, q->h, q->left, q->top, q->right, q->bottom);
-            break;
-            
-        case NK_COMMAND_IMAGE:
-            //printf("NK_COMMAND_IMAGE \n");
-           // const struct nk_command_image *q = (const struct nk_command_image *)cmd;
-           // nk_rawfb_drawimage(rawfb, q->x, q->y, q->w, q->h, &q->img, &q->col);
-            break;
-        
-        case NK_COMMAND_ARC:
-            printf("NK_COMMAND_ARC \n");
-            assert(0 && "NK_COMMAND_ARC not implemented\n");
-            break;
-            
-        case NK_COMMAND_ARC_FILLED:
-            printf("NK_COMMAND_ARC \n");
-            assert(0 && "NK_COMMAND_ARC_FILLED not implemented\n");
-            break;
-        
-        default: 
-            printf("unhandled OP: %d \n", cmd->type);
-            break;
-        }
-    } nk_clear(&(win->ctx));
-}
-
-#endif

+ 0 - 13
demo/x11/main.c

@@ -152,19 +152,6 @@ main(void)
     xw.font = nk_xfont_create(xw.dpy, "fixed");
     ctx = nk_xlib_init(xw.font, xw.dpy, xw.screen, xw.win, xw.width, xw.height);
 
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-    #endif
-    #endif
-
     while (running)
     {
         /* Input */

+ 0 - 13
demo/x11_opengl2/main.c

@@ -256,19 +256,6 @@ int main(void)
     /*nk_style_load_all_cursors(ctx, atlas->cursors);*/
     /*nk_style_set_font(ctx, &droid->handle);*/}
 
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-    #endif
-    #endif
-
     bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
     while (running)
     {

+ 0 - 13
demo/x11_opengl3/main.c

@@ -253,19 +253,6 @@ int main(void)
     /*nk_style_load_all_cursors(ctx, atlas->cursors);*/
     /*nk_style_set_font(ctx, &droid->handle);*/}
 
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-    #endif
-    #endif
-
     bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
     while (running)
     {

+ 0 - 13
demo/x11_xft/main.c

@@ -156,19 +156,6 @@ main(void)
 #endif
                     xw.width, xw.height);
 
-    #ifdef INCLUDE_STYLE
-    /* ease regression testing during Nuklear release process; not needed for anything else */
-    #ifdef STYLE_WHITE
-    set_style(ctx, THEME_WHITE);
-    #elif defined(STYLE_RED)
-    set_style(ctx, THEME_RED);
-    #elif defined(STYLE_BLUE)
-    set_style(ctx, THEME_BLUE);
-    #elif defined(STYLE_DARK)
-    set_style(ctx, THEME_DARK);
-    #endif
-    #endif
-
     while (running)
     {
         /* Input */

+ 24 - 0
demo/xcb_cairo/Makefile

@@ -0,0 +1,24 @@
+# Target
+BIN = demo
+CFLAGS += -std=c89 -pedantic -O2
+LDFLAGS += -lm
+SRC = ${wildcard *.c}
+OBJ = $(SRC:.c=.o)
+
+# Freetype
+CFLAGS += ${shell pkg-config --cflags freetype2}
+LDFLAGS += ${shell pkg-config --libs freetype2}
+
+# XCB
+CFLAGS += ${shell pkg-config --cflags xcb xcb-util xcb-keysyms}
+LDFLAGS += ${shell pkg-config --libs xcb xcb-util xcb-keysyms}
+
+# Cairo
+CFLAGS += ${shell pkg-config --cflags cairo}
+LDFLAGS += ${shell pkg-config --libs cairo}
+
+# Rules
+$(BIN):
+	@mkdir -p bin
+	rm -f bin/$(BIN) $(OBJS)
+	$(CC) $(SRC) $(CFLAGS) -D_POSIX_C_SOURCE=200809L -o bin/$(BIN) ${LDFLAGS}

+ 168 - 0
demo/xcb_cairo/main.c

@@ -0,0 +1,168 @@
+/* nuklear - v1.32.0 - public domain */
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <limits.h>
+#include <math.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <time.h>
+
+#define NK_INCLUDE_FIXED_TYPES
+#define NK_INCLUDE_STANDARD_IO
+#define NK_INCLUDE_STANDARD_VARARGS
+#define NK_INCLUDE_DEFAULT_ALLOCATOR
+#define NK_IMPLEMENTATION
+#include "../../nuklear.h"
+
+#define NK_XCB_CAIRO_IMPLEMENTATION
+#include "nuklear_xcb.h"
+
+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);
+}
+
+/* ===============================================================
+ *
+ *                          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 defines */
+
+/*#define INCLUDE_ALL */
+/*#define INCLUDE_STYLE */
+/*#define INCLUDE_CALCULATOR */
+/*#define INCLUDE_OVERVIEW */
+/*#define INCLUDE_NODE_EDITOR */
+/*#define INCLUDE_CANVAS */
+
+#ifdef INCLUDE_ALL
+  #define INCLUDE_STYLE
+  #define INCLUDE_CALCULATOR
+  #define INCLUDE_OVERVIEW
+  #define INCLUDE_NODE_EDITOR
+  #define INCLUDE_CANVAS
+#endif
+
+#ifdef INCLUDE_STYLE
+  #include "../common/style.c"
+#endif
+#ifdef INCLUDE_CALCULATOR
+  #include "../common/calculator.c"
+#endif
+#ifdef INCLUDE_OVERVIEW
+  #include "../common/overview.c"
+#endif
+#ifdef INCLUDE_NODE_EDITOR
+  #include "../common/node_editor.c"
+#endif
+#ifdef INCLUDE_CANVAS
+  #include "../common/canvas.c"
+#endif
+
+/* ===============================================================
+ *
+ *                          DEMO
+ *
+ * ===============================================================*/
+int
+main(void)
+{
+    struct nk_xcb_context *xcb_ctx;
+    struct nk_color background = nk_rgb(0, 0, 0);
+    struct nk_cairo_context *cairo_ctx;
+    struct nk_user_font *font;
+    struct nk_context* ctx;
+    int running = 1;
+    int events;
+
+    xcb_ctx = nk_xcb_init("Nuklear XCB/Cairo", 20, 20, 600, 800);
+    cairo_ctx = nk_cairo_init(&background, NULL, 0, nk_xcb_create_cairo_surface(xcb_ctx));
+    /*cairo_ctx = nk_cairo_init(&background, "../../extra_font/DroidSans.ttf", 0, nk_xcb_create_surface(xcb_ctx));*/
+    font = nk_cairo_default_font(cairo_ctx);
+    ctx = malloc(sizeof(struct nk_context));
+    nk_init_default(ctx, font);
+
+    #ifdef INCLUDE_STYLE
+    set_style(ctx, THEME_BLACK);
+    /*nk_style_push_float(ctx, &ctx->style.window.rounding, 20.0f);*/
+    /*set_style(ctx, THEME_WHITE);*/
+    /*set_style(ctx, THEME_RED);*/
+    /*set_style(ctx, THEME_BLUE);*/
+    /*set_style(ctx, THEME_DARK);*/
+    #endif
+
+    while (running)
+    {
+        /* Events */
+        events = nk_xcb_handle_event(xcb_ctx, ctx);
+        if (events & NK_XCB_EVENT_STOP) {
+            break;
+        }
+        if (events & NK_XCB_EVENT_PAINT) {
+            nk_cairo_damage(cairo_ctx);
+        }
+        if (events & NK_XCB_EVENT_RESIZED) {
+            nk_xcb_resize_cairo_surface(xcb_ctx, nk_cairo_surface(cairo_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_hidden(ctx, "Demo")) {
+            break;
+        }
+
+        /* -------------- EXAMPLES ---------------- */
+        #ifdef INCLUDE_CALCULATOR
+        calculator(ctx);
+        #endif
+        #ifdef INCLUDE_OVERVIEW
+        overview(ctx);
+        #endif
+        #ifdef INCLUDE_NODE_EDITOR
+        node_editor(ctx);
+        #endif
+        #ifdef INCLUDE_CANVAS
+        canvas(ctx);
+        #endif
+        /* ----------------------------------------- */
+
+        /* Render */
+        nk_cairo_render(cairo_ctx, ctx);
+        nk_xcb_render(xcb_ctx);
+        nk_clear(ctx);
+    }
+
+    nk_free(ctx);
+    free(ctx);
+    nk_cairo_free(cairo_ctx);
+    nk_xcb_free(xcb_ctx);
+
+    return EXIT_SUCCESS;
+}

+ 836 - 0
demo/xcb_cairo/nuklear_xcb.h

@@ -0,0 +1,836 @@
+/*****************************************************************************
+ *
+ * Nuklear XCB/Cairo Render Backend - v0.0.2
+ * Copyright 2021 Richard Gill
+ * 
+ * Grabbed and adapted from https://github.com/griebd/nuklear_xcb
+ * Copyright 2017 Adriano Grieb
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ ****************************************************************************/
+
+/*****************************************************************************
+ *
+ *                                API
+ *
+ ****************************************************************************/
+
+#ifndef NK_XCB_CAIRO_H
+#define NK_XCB_CAIRO_H
+
+struct nk_xcb_context;
+struct nk_cairo_context;
+
+/* With Xcb, we work mostly on events, so to do something only when
+ * needed it's good to know what kind of events pulled us from sleep
+ */
+enum nk_xcb_event_type {
+    NK_XCB_EVENT_PAINT      = 0x02,
+    NK_XCB_EVENT_RESIZED    = 0x04,
+    NK_XCB_EVENT_STOP       = 0x08
+};
+
+/* Xcb part: work on windows */
+NK_API struct nk_xcb_context *nk_xcb_init(const char *title, int pos_x, int pos_y, int width, int height);
+NK_API void nk_xcb_free(struct nk_xcb_context *xcb_ctx);
+
+NK_API int nk_xcb_handle_event(struct nk_xcb_context *xcb_ctx, struct nk_context *nk_ctx);
+NK_API void nk_xcb_render(struct nk_xcb_context *xcb_ctx);
+NK_API void nk_xcb_size(struct nk_xcb_context *xcb_ctx, int *width, int *height);
+
+/* TODO: copy/paste */
+
+/* Cairo part: work on painting */
+NK_API struct nk_cairo_context *nk_cairo_init(struct nk_color *bg, const char *font_file, double font_size, void *surface);
+NK_API void nk_cairo_free(struct nk_cairo_context *cairo_ctx);
+
+NK_API struct nk_user_font *nk_cairo_default_font(struct nk_cairo_context *cairo_ctx);
+NK_API void nk_cairo_damage(struct nk_cairo_context *cairo_ctx);
+NK_API int nk_cairo_render(struct nk_cairo_context *cairo_ctx, struct nk_context *ctx);
+
+/* Bridge between xcb and cairo (so it's possible to use them like legos) */
+NK_API void *nk_xcb_create_cairo_surface(struct nk_xcb_context *xcb_ctx);
+NK_API void nk_xcb_resize_cairo_surface(struct nk_xcb_context *xcb_ctx, void *surface);
+
+
+#endif /* NK_XCB_CAIRO_H */
+
+/*****************************************************************************
+ *
+ *                           IMPLEMENTATION
+ *
+ ****************************************************************************/
+
+#ifdef NK_XCB_CAIRO_IMPLEMENTATION
+
+#include <xcb/xcb.h>
+#include <xcb/xcb_util.h>
+#include <xcb/xcb_keysyms.h>
+#include <X11/keysym.h>
+#include <cairo/cairo-xcb.h>
+#include <cairo/cairo-ft.h>
+
+#if defined _XOPEN_SOURCE && _XOPEN_SOURCE >= 600 || \
+    defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L
+#include <time.h>
+#include <errno.h>
+#ifndef NK_XCB_FPS
+#define NK_XCB_FPS 30
+#endif /* NK_XCB_FPS */
+#define NK_XCB_NSEC 1000000000
+#define NK_XCB_MIN_FRAME_TIME (NK_XCB_NSEC / NK_XCB_FPS)
+#endif
+
+#include <math.h>
+#ifdef __USE_GNU
+#define NK_XCB_PI M_PIl
+#elif defined __USE_BSD || defined __USE_XOPEN
+#define NK_XCB_PI M_PI
+#else
+#define NK_XCB_PI acos(-1.0)
+#endif
+
+#define NK_XCB_TO_CAIRO(x) ((double) x / 255.0)
+#define NK_XCB_DEG_TO_RAD(x) ((double) x * NK_XCB_PI / 180.0)
+
+struct nk_cairo_context {
+    cairo_surface_t *surface;
+    cairo_t *cr;
+
+    struct nk_user_font *font;
+    struct nk_color *bg;
+
+    void *last_buffer;
+    nk_size buffer_size;
+    int repaint;
+};
+
+struct nk_xcb_context {
+    xcb_connection_t *conn;
+    int screennum;
+    xcb_window_t window;
+    xcb_key_symbols_t *key_symbols;
+#ifdef NK_XCB_MIN_FRAME_TIME
+    unsigned long last_render;
+#endif /* NK_XCB_MIN_FRAME_TIME */
+    int events;
+    xcb_intern_atom_reply_t* del_atom;
+    int width, height;
+};
+
+NK_API struct nk_xcb_context *nk_xcb_init(const char *title, int pos_x, int pos_y, int width, int height)
+{
+    int screenNum;
+    xcb_connection_t *conn;
+    xcb_screen_t *screen;
+    xcb_window_t window;
+    uint32_t values[1];
+    struct nk_xcb_context *xcb_ctx;
+    xcb_intern_atom_cookie_t cookie;
+    xcb_intern_atom_reply_t *reply, *del_atom;
+
+    conn = xcb_connect(NULL, &screenNum);
+    if (xcb_connection_has_error(conn)) {
+        xcb_disconnect(conn);
+        return NULL;
+    }
+    screen = xcb_aux_get_screen(conn, screenNum);
+
+    window = xcb_generate_id(conn);
+    values[0] = XCB_EVENT_MASK_KEY_PRESS
+        | XCB_EVENT_MASK_KEY_RELEASE
+        | XCB_EVENT_MASK_BUTTON_PRESS
+        | XCB_EVENT_MASK_BUTTON_RELEASE
+        | XCB_EVENT_MASK_POINTER_MOTION
+        | XCB_EVENT_MASK_BUTTON_1_MOTION
+        | XCB_EVENT_MASK_BUTTON_2_MOTION
+        | XCB_EVENT_MASK_BUTTON_3_MOTION
+        | XCB_EVENT_MASK_BUTTON_4_MOTION
+        | XCB_EVENT_MASK_BUTTON_5_MOTION
+        | XCB_EVENT_MASK_BUTTON_MOTION
+        | XCB_EVENT_MASK_KEYMAP_STATE
+        | XCB_EVENT_MASK_EXPOSURE
+        | XCB_EVENT_MASK_STRUCTURE_NOTIFY
+        ;
+    xcb_create_window(conn, XCB_COPY_FROM_PARENT, window, screen->root,
+            pos_x, pos_y, width, height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
+            XCB_COPY_FROM_PARENT, XCB_CW_EVENT_MASK, values);
+
+    cookie = xcb_intern_atom(conn, 1, 12, "WM_PROTOCOLS");
+    reply = xcb_intern_atom_reply(conn, cookie, 0);
+    cookie = xcb_intern_atom(conn, 0, 16, "WM_DELETE_WINDOW");
+    del_atom = xcb_intern_atom_reply(conn, cookie, 0);
+    xcb_change_property(conn, XCB_PROP_MODE_REPLACE, window, reply->atom, 4, 32, 1, &del_atom->atom);
+    free(reply);
+
+    xcb_map_window(conn, window);
+    xcb_flush(conn);
+
+    xcb_ctx = malloc(sizeof (struct nk_xcb_context));
+    xcb_ctx->conn = conn;
+    xcb_ctx->screennum = screenNum;
+    xcb_ctx->window = window;
+    xcb_ctx->key_symbols = xcb_key_symbols_alloc(xcb_ctx->conn);
+    xcb_ctx->del_atom = del_atom;
+    xcb_ctx->width = width;
+    xcb_ctx->height = height;
+
+    return xcb_ctx;
+}
+
+NK_API void nk_xcb_free(struct nk_xcb_context *xcb_ctx)
+{
+    free(xcb_ctx->del_atom);
+    xcb_key_symbols_free(xcb_ctx->key_symbols);
+    xcb_disconnect(xcb_ctx->conn);
+    free(xcb_ctx);
+}
+
+NK_API int nk_xcb_handle_event(struct nk_xcb_context *xcb_ctx, struct nk_context *nk_ctx)
+{
+    int events = 0;
+    xcb_generic_event_t *event;
+
+#ifdef NK_XCB_MIN_FRAME_TIME
+    struct timespec tp;
+
+    clock_gettime(CLOCK_MONOTONIC_COARSE, &tp);
+    xcb_ctx->last_render = tp.tv_sec * NK_XCB_NSEC + tp.tv_nsec;
+#endif /* NK_XCB_MIN_FRAME_TIME */
+
+    event = xcb_wait_for_event(xcb_ctx->conn);
+
+    nk_input_begin(nk_ctx);
+    do {
+        switch (XCB_EVENT_RESPONSE_TYPE(event)) {
+        case XCB_KEY_PRESS:
+        case XCB_KEY_RELEASE:
+            {
+                int press = (XCB_EVENT_RESPONSE_TYPE(event)) == XCB_KEY_PRESS;
+                xcb_key_press_event_t *kp = (xcb_key_press_event_t *)event;
+                xcb_keysym_t sym = xcb_key_symbols_get_keysym(xcb_ctx->key_symbols, kp->detail, kp->state);
+                switch (sym) {
+                case XK_Shift_L:
+                case XK_Shift_R:
+                    nk_input_key(nk_ctx, NK_KEY_SHIFT, press);
+                    break;
+                case XK_Control_L:
+                case XK_Control_R:
+                    nk_input_key(nk_ctx, NK_KEY_CTRL, press);
+                    break;
+                case XK_Delete:
+                    nk_input_key(nk_ctx, NK_KEY_DEL, press);
+                    break;
+                case XK_Return:
+                    nk_input_key(nk_ctx, NK_KEY_ENTER, press);
+                    break;
+                case XK_Tab:
+                    nk_input_key(nk_ctx, NK_KEY_TAB, press);
+                    break;
+                case XK_BackSpace:
+                    nk_input_key(nk_ctx, NK_KEY_BACKSPACE, press);
+                    break;
+                /* case NK_KEY_COPY */
+                /* case NK_KEY_CUT */
+                /* case NK_KEY_PASTE */
+                case XK_Up:
+                    nk_input_key(nk_ctx, NK_KEY_UP, press);
+                    break;
+                case XK_Down:
+                    nk_input_key(nk_ctx, NK_KEY_DOWN, press);
+                    break;
+                case XK_Left:
+                    nk_input_key(nk_ctx, NK_KEY_LEFT, press);
+                    break;
+                case XK_Right:
+                    nk_input_key(nk_ctx, NK_KEY_RIGHT, press);
+                    break;
+                /* NK_KEY_TEXT_INSERT_MODE, */
+                /* NK_KEY_TEXT_REPLACE_MODE, */
+                case XK_Escape:
+                    nk_input_key(nk_ctx, NK_KEY_TEXT_RESET_MODE, press);
+                    break;
+                /* NK_KEY_TEXT_LINE_START, */
+                /* NK_KEY_TEXT_LINE_END, */
+                case XK_Home:
+                    {
+                        nk_input_key(nk_ctx, NK_KEY_TEXT_START, press);
+                        nk_input_key(nk_ctx, NK_KEY_SCROLL_START, press);
+                    }
+                    break;
+                case XK_End:
+                    {
+                        nk_input_key(nk_ctx, NK_KEY_TEXT_END, press);
+                        nk_input_key(nk_ctx, NK_KEY_SCROLL_END, press);
+                    }
+                    break;
+                /* NK_KEY_TEXT_UNDO, */
+                /* NK_KEY_TEXT_REDO, */
+                /* NK_KEY_TEXT_SELECT_ALL, */
+                /* NK_KEY_TEXT_WORD_LEFT, */
+                /* NK_KEY_TEXT_WORD_RIGHT, */
+                case XK_Page_Down:
+                    nk_input_key(nk_ctx, NK_KEY_SCROLL_DOWN, press);
+                    break;
+                case XK_Page_Up:
+                    nk_input_key(nk_ctx, NK_KEY_SCROLL_UP, press);
+                    break;
+                default:
+                    if (press &&
+                            !xcb_is_keypad_key(sym) &&
+                            !xcb_is_private_keypad_key(sym) &&
+                            !xcb_is_cursor_key(sym) &&
+                            !xcb_is_pf_key(sym) &&
+                            !xcb_is_function_key(sym) &&
+                            !xcb_is_misc_function_key(sym) &&
+                            !xcb_is_modifier_key(sym)
+                            ) {
+                        nk_input_char(nk_ctx, sym);
+                    }
+                    else {
+                        printf("state: %x code: %x sum: %x\n", kp->state, kp->detail, sym);
+                    }
+                    break;
+                }
+            }
+            break;
+        case XCB_BUTTON_PRESS:
+        case XCB_BUTTON_RELEASE:
+            {
+                int press = (XCB_EVENT_RESPONSE_TYPE(event)) == XCB_BUTTON_PRESS;
+                xcb_button_press_event_t *bp = (xcb_button_press_event_t *)event;
+                switch (bp->detail) {
+                case XCB_BUTTON_INDEX_1:
+                    nk_input_button(nk_ctx, NK_BUTTON_LEFT, bp->event_x, bp->event_y, press);
+                    break;
+                case XCB_BUTTON_INDEX_2:
+                    nk_input_button(nk_ctx, NK_BUTTON_MIDDLE, bp->event_x, bp->event_y, press);
+                    break;
+                case XCB_BUTTON_INDEX_3:
+                    nk_input_button(nk_ctx, NK_BUTTON_RIGHT, bp->event_x, bp->event_y, press);
+                    break;
+                case XCB_BUTTON_INDEX_4:
+                    nk_input_scroll(nk_ctx, nk_vec2(0, 1.0f));
+                    break;
+                case XCB_BUTTON_INDEX_5:
+                    nk_input_scroll(nk_ctx, nk_vec2(0, -1.0f));
+                    break;
+                default: break;
+                }
+            }
+            break;
+        case XCB_MOTION_NOTIFY:
+            {
+                xcb_motion_notify_event_t *mn = (xcb_motion_notify_event_t *)event;
+                nk_input_motion(nk_ctx, mn->event_x, mn->event_y);
+            }
+            break;
+        case XCB_SELECTION_CLEAR:
+            {
+                printf("Unhandled event: %s\n", xcb_event_get_label(event->response_type));
+            }
+            break;
+        case XCB_SELECTION_REQUEST:
+            {
+                printf("Unhandled event: %s\n", xcb_event_get_label(event->response_type));
+            }
+            break;
+        case XCB_SELECTION_NOTIFY:
+            {
+                printf("Unhandled event: %s\n", xcb_event_get_label(event->response_type));
+            }
+            break;
+        case XCB_CONFIGURE_NOTIFY:
+            {
+                xcb_configure_notify_event_t *cn = (xcb_configure_notify_event_t *)event;
+                xcb_ctx->width = cn->width;
+                xcb_ctx->height = cn->height;
+                events |= NK_XCB_EVENT_RESIZED;
+            }
+            break;
+        case XCB_KEYMAP_NOTIFY:
+            xcb_refresh_keyboard_mapping(xcb_ctx->key_symbols, (xcb_mapping_notify_event_t *)event);
+            break;
+        case XCB_EXPOSE:
+        case XCB_REPARENT_NOTIFY:
+        case XCB_MAP_NOTIFY:
+            events |= NK_XCB_EVENT_PAINT;
+            break;
+        case XCB_CLIENT_MESSAGE:
+            {
+                xcb_client_message_event_t *cm = (xcb_client_message_event_t *)event;
+                if (cm->data.data32[0] == xcb_ctx->del_atom->atom)
+                {
+                    return NK_XCB_EVENT_STOP;
+                }
+            }
+            break;
+        default:
+            printf ("Unhandled event: %s\n", xcb_event_get_label(event->response_type));
+            break;
+        }
+        free(event);
+    }
+    while ((event = xcb_poll_for_event(xcb_ctx->conn)));
+    nk_input_end(nk_ctx);
+
+    return events;
+}
+
+NK_API void nk_xcb_render(struct nk_xcb_context *xcb_ctx)
+{
+    xcb_flush (xcb_ctx->conn);
+
+#ifdef NK_XCB_MIN_FRAME_TIME
+    {
+        struct timespec tp;
+        unsigned long spent;
+        clock_gettime(CLOCK_MONOTONIC_COARSE, &tp);
+        spent = tp.tv_sec * NK_XCB_NSEC + tp.tv_nsec - xcb_ctx->last_render;
+        if (NK_XCB_MIN_FRAME_TIME > spent) {
+            tp.tv_sec = 0;
+            tp.tv_nsec = NK_XCB_MIN_FRAME_TIME - spent;
+            while (clock_nanosleep(CLOCK_MONOTONIC, 0, &tp, &tp) == EINTR);
+        }
+    }
+#endif /* NK_XCB_MIN_FRAME_TIME */
+}
+
+NK_API void nk_xcb_size(struct nk_xcb_context *xcb_ctx, int *width, int *height)
+{
+    *width = xcb_ctx->width;
+    *height = xcb_ctx->height;
+}
+
+NK_API void *nk_xcb_create_cairo_surface(struct nk_xcb_context *xcb_ctx)
+{
+    xcb_screen_t *screen;
+    xcb_visualtype_t *visual;
+
+    screen = xcb_aux_get_screen(xcb_ctx->conn, xcb_ctx->screennum);
+    visual = xcb_aux_get_visualtype(xcb_ctx->conn, xcb_ctx->screennum, screen->root_visual);
+    return cairo_xcb_surface_create(xcb_ctx->conn, xcb_ctx->window, visual, xcb_ctx->width, xcb_ctx->height);
+}
+
+NK_API void nk_xcb_resize_cairo_surface(struct nk_xcb_context *xcb_ctx, void *surface)
+{
+    cairo_xcb_surface_set_size((cairo_surface_t *)surface, xcb_ctx->width, xcb_ctx->height);
+}
+
+
+
+#define NK_TO_CAIRO(x) ((double) x / 255.0)
+
+
+NK_INTERN float nk_cairo_text_width(nk_handle handle, float height __attribute__ ((__unused__)), const char *text, int len)
+{
+    cairo_scaled_font_t *font = handle.ptr;
+    cairo_glyph_t *glyphs = NULL;
+    int num_glyphs;
+    cairo_text_extents_t extents;
+
+    cairo_scaled_font_text_to_glyphs(font, 0, 0, text, len, &glyphs, &num_glyphs, NULL, NULL, NULL);
+    cairo_scaled_font_glyph_extents(font, glyphs, num_glyphs, &extents);
+    cairo_glyph_free(glyphs);
+
+    return extents.x_advance;
+}
+
+NK_API struct nk_cairo_context *nk_cairo_init(struct nk_color *bg, const char *font_file, double font_size, void *surf)
+{
+    cairo_surface_t *surface = surf;
+    struct nk_cairo_context *cairo_ctx;
+    cairo_t *cr;
+    cairo_font_extents_t extents;
+    cairo_scaled_font_t *default_font;
+    struct nk_user_font *font;
+
+    cr = cairo_create(surface);
+    font = malloc(sizeof (struct nk_user_font));
+    if (font_file != NULL) {
+        FT_Library library;
+        FT_Face face;
+        cairo_font_face_t *font_face;
+        static const cairo_user_data_key_t key;
+
+        FT_Init_FreeType(&library);
+        FT_New_Face(library, font_file, 0, &face);
+        font_face = cairo_ft_font_face_create_for_ft_face(face, 0);
+        cairo_font_face_set_user_data(font_face, &key, face, (cairo_destroy_func_t)FT_Done_Face);
+        cairo_set_font_face(cr, font_face);
+    }
+    if (font_size < 0.01) {
+        font_size = 11.0;
+    }
+    cairo_set_font_size(cr, font_size);
+    default_font = cairo_get_scaled_font(cr);
+    cairo_scaled_font_extents(default_font, &extents);
+    font->userdata.ptr = default_font;
+    font->height = extents.height;
+    font->width = nk_cairo_text_width;
+
+    cairo_ctx = malloc(sizeof(struct nk_cairo_context));
+    cairo_ctx->surface = (cairo_surface_t *)surface;
+    cairo_ctx->cr = cr;
+    cairo_ctx->font = font;
+    cairo_ctx->bg = bg;
+    cairo_ctx->last_buffer = NULL;
+    cairo_ctx->buffer_size = 0;
+    cairo_ctx->repaint = nk_false;
+
+    return cairo_ctx;
+}
+
+NK_API cairo_surface_t *nk_cairo_surface(struct nk_cairo_context *cairo_ctx)
+{
+    return cairo_ctx->surface;
+}
+
+NK_API struct nk_user_font *nk_cairo_default_font(struct nk_cairo_context *cairo_ctx)
+{
+    return cairo_ctx->font;
+}
+
+NK_API void nk_cairo_free(struct nk_cairo_context *cairo_ctx)
+{
+    free (cairo_ctx->last_buffer);
+    cairo_destroy(cairo_ctx->cr);
+    cairo_surface_destroy(cairo_ctx->surface);
+    free(cairo_ctx->font);
+    free(cairo_ctx);
+}
+
+NK_API void nk_cairo_damage(struct nk_cairo_context *cairo_ctx)
+{
+    cairo_ctx->repaint = nk_true;
+}
+
+NK_API int nk_cairo_render(struct nk_cairo_context *cairo_ctx, struct nk_context *nk_ctx)
+{
+    cairo_t *cr;
+    const struct nk_command *cmd = NULL;
+    void *cmds = nk_buffer_memory(&nk_ctx->memory);
+
+    if (cairo_ctx->buffer_size != nk_ctx->memory.allocated) {
+        cairo_ctx->buffer_size = nk_ctx->memory.allocated;
+        cairo_ctx->last_buffer = realloc(cairo_ctx->last_buffer, cairo_ctx->buffer_size);
+        memcpy(cairo_ctx->last_buffer, cmds, cairo_ctx->buffer_size);
+    }
+    else if (!memcmp(cmds, cairo_ctx->last_buffer, cairo_ctx->buffer_size)) {
+        if (!cairo_ctx->repaint) {
+            return nk_false;
+        }
+        cairo_ctx->repaint = nk_false;
+    }
+    else {
+        memcpy(cairo_ctx->last_buffer, cmds, cairo_ctx->buffer_size);
+    }
+
+    cr = cairo_ctx->cr;
+    cairo_push_group(cr);
+
+    cairo_set_source_rgb(cr, NK_TO_CAIRO(cairo_ctx->bg->r), NK_TO_CAIRO(cairo_ctx->bg->g), NK_TO_CAIRO(cairo_ctx->bg->b));
+    cairo_paint(cr);
+
+    nk_foreach(cmd, nk_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;
+                cairo_reset_clip(cr);
+                if (s->x >= 0) {
+                    cairo_rectangle(cr, s->x - 1, s->y - 1, s->w + 2, s->h + 2);
+                    cairo_clip(cr);
+                }
+            }
+            break;
+        case NK_COMMAND_LINE:
+            {
+                const struct nk_command_line *l = (const struct nk_command_line *)cmd;
+                cairo_set_source_rgba(cr, NK_TO_CAIRO(l->color.r), NK_TO_CAIRO(l->color.g), NK_TO_CAIRO(l->color.b), NK_TO_CAIRO(l->color.a));
+                cairo_set_line_width(cr, l->line_thickness);
+                cairo_move_to(cr, l->begin.x, l->begin.y);
+                cairo_line_to(cr, l->end.x, l->end.y);
+                cairo_stroke(cr);
+            }
+            break;
+        case NK_COMMAND_CURVE:
+            {
+                const struct nk_command_curve *q = (const struct nk_command_curve *)cmd;
+                cairo_set_source_rgba(cr, NK_TO_CAIRO(q->color.r), NK_TO_CAIRO(q->color.g), NK_TO_CAIRO(q->color.b), NK_TO_CAIRO(q->color.a));
+                cairo_set_line_width(cr, q->line_thickness);
+                cairo_move_to(cr, q->begin.x, q->begin.y);
+                cairo_curve_to(cr, q->ctrl[0].x, q->ctrl[0].y, q->ctrl[1].x, q->ctrl[1].y, q->end.x, q->end.y);
+                cairo_stroke(cr);
+            }
+            break;
+        case NK_COMMAND_RECT:
+            {
+                const struct nk_command_rect *r = (const struct nk_command_rect *)cmd;
+                cairo_set_source_rgba(cr, NK_TO_CAIRO(r->color.r), NK_TO_CAIRO(r->color.g), NK_TO_CAIRO(r->color.b), NK_TO_CAIRO(r->color.a));
+                cairo_set_line_width(cr, r->line_thickness);
+                if (r->rounding == 0) {
+                    cairo_rectangle(cr, r->x, r->y, r->w, r->h);
+                }
+                else {
+                    int xl = r->x + r->w - r->rounding;
+                    int xr = r->x + r->rounding;
+                    int yl = r->y + r->h - r->rounding;
+                    int yr = r->y + r->rounding;
+                    cairo_new_sub_path(cr);
+                    cairo_arc(cr, xl, yr, r->rounding, NK_XCB_DEG_TO_RAD(-90), NK_XCB_DEG_TO_RAD(0));
+                    cairo_arc(cr, xl, yl, r->rounding, NK_XCB_DEG_TO_RAD(0), NK_XCB_DEG_TO_RAD(90));
+                    cairo_arc(cr, xr, yl, r->rounding, NK_XCB_DEG_TO_RAD(90), NK_XCB_DEG_TO_RAD(180));
+                    cairo_arc(cr, xr, yr, r->rounding, NK_XCB_DEG_TO_RAD(180), NK_XCB_DEG_TO_RAD(270));
+                    cairo_close_path(cr);
+                }
+                cairo_stroke(cr);
+            }
+            break;
+        case NK_COMMAND_RECT_FILLED:
+            {
+                const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled *)cmd;
+                cairo_set_source_rgba(cr, NK_TO_CAIRO(r->color.r), NK_TO_CAIRO(r->color.g), NK_TO_CAIRO(r->color.b), NK_TO_CAIRO(r->color.a));
+                if (r->rounding == 0) {
+                    cairo_rectangle(cr, r->x, r->y, r->w, r->h);
+                } else {
+                    int xl = r->x + r->w - r->rounding;
+                    int xr = r->x + r->rounding;
+                    int yl = r->y + r->h - r->rounding;
+                    int yr = r->y + r->rounding;
+                    cairo_new_sub_path(cr);
+                    cairo_arc(cr, xl, yr, r->rounding, NK_XCB_DEG_TO_RAD(-90), NK_XCB_DEG_TO_RAD(0));
+                    cairo_arc(cr, xl, yl, r->rounding, NK_XCB_DEG_TO_RAD(0), NK_XCB_DEG_TO_RAD(90));
+                    cairo_arc(cr, xr, yl, r->rounding, NK_XCB_DEG_TO_RAD(90), NK_XCB_DEG_TO_RAD(180));
+                    cairo_arc(cr, xr, yr, r->rounding, NK_XCB_DEG_TO_RAD(180), NK_XCB_DEG_TO_RAD(270));
+                    cairo_close_path(cr);
+                }
+                cairo_fill(cr);
+            }
+            break;
+        case NK_COMMAND_RECT_MULTI_COLOR:
+            {
+                /* from https://github.com/taiwins/twidgets/blob/master/src/nk_wl_cairo.c */
+                const struct nk_command_rect_multi_color *r = (const struct nk_command_rect_multi_color *)cmd;
+                cairo_pattern_t *pat = cairo_pattern_create_mesh();
+                if (pat) {
+                    cairo_mesh_pattern_begin_patch(pat);
+                    cairo_mesh_pattern_move_to(pat, r->x, r->y);
+                    cairo_mesh_pattern_line_to(pat, r->x, r->y + r->h);
+                    cairo_mesh_pattern_line_to(pat, r->x + r->w, r->y + r->h);
+                    cairo_mesh_pattern_line_to(pat, r->x + r->w, r->y);
+                    cairo_mesh_pattern_set_corner_color_rgba(pat, 0, NK_TO_CAIRO(r->left.r), NK_TO_CAIRO(r->left.g), NK_TO_CAIRO(r->left.b), NK_TO_CAIRO(r->left.a));
+                    cairo_mesh_pattern_set_corner_color_rgba(pat, 1, NK_TO_CAIRO(r->bottom.r), NK_TO_CAIRO(r->bottom.g), NK_TO_CAIRO(r->bottom.b), NK_TO_CAIRO(r->bottom.a));
+                    cairo_mesh_pattern_set_corner_color_rgba(pat, 2, NK_TO_CAIRO(r->right.r), NK_TO_CAIRO(r->right.g), NK_TO_CAIRO(r->right.b), NK_TO_CAIRO(r->right.a));
+                    cairo_mesh_pattern_set_corner_color_rgba(pat, 3, NK_TO_CAIRO(r->top.r), NK_TO_CAIRO(r->top.g), NK_TO_CAIRO(r->top.b), NK_TO_CAIRO(r->top.a));
+                    cairo_mesh_pattern_end_patch(pat);
+
+                    cairo_rectangle(cr, r->x, r->y, r->w, r->h);
+                    cairo_set_source(cr, pat);
+                    cairo_fill(cr);
+                    cairo_pattern_destroy(pat);
+                }
+            }
+            break;
+        case NK_COMMAND_CIRCLE:
+            {
+                const struct nk_command_circle *c = (const struct nk_command_circle *)cmd;
+                cairo_set_source_rgba(cr, NK_TO_CAIRO(c->color.r), NK_TO_CAIRO(c->color.g), NK_TO_CAIRO(c->color.b), NK_TO_CAIRO(c->color.a));
+                cairo_set_line_width(cr, c->line_thickness);
+                cairo_save(cr);
+                cairo_translate(cr, c->x + c->w / 2.0, c->y + c->h / 2.0);
+                cairo_scale(cr, c->w / 2.0, c->h / 2.0);
+                cairo_arc(cr, 0, 0, 1, NK_XCB_DEG_TO_RAD(0), NK_XCB_DEG_TO_RAD(360));
+                cairo_restore(cr);
+                cairo_stroke(cr);
+            }
+            break;
+        case NK_COMMAND_CIRCLE_FILLED:
+            {
+                const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
+                cairo_set_source_rgba(cr, NK_TO_CAIRO(c->color.r), NK_TO_CAIRO(c->color.g), NK_TO_CAIRO(c->color.b), NK_TO_CAIRO(c->color.a));
+                cairo_save(cr);
+                cairo_translate(cr, c->x + c->w / 2.0, c->y + c->h / 2.0);
+                cairo_scale(cr, c->w / 2.0, c->h / 2.0);
+                cairo_arc(cr, 0, 0, 1, NK_XCB_DEG_TO_RAD(0), NK_XCB_DEG_TO_RAD(360));
+                cairo_restore(cr);
+                cairo_fill(cr);
+            }
+            break;
+        case NK_COMMAND_ARC:
+            {
+                const struct nk_command_arc *a = (const struct nk_command_arc*) cmd;
+                cairo_set_source_rgba(cr, NK_TO_CAIRO(a->color.r), NK_TO_CAIRO(a->color.g), NK_TO_CAIRO(a->color.b), NK_TO_CAIRO(a->color.a));
+                cairo_set_line_width(cr, a->line_thickness);
+                cairo_arc(cr, a->cx, a->cy, a->r, NK_XCB_DEG_TO_RAD(a->a[0]), NK_XCB_DEG_TO_RAD(a->a[1]));
+                cairo_stroke(cr);
+            }
+            break;
+        case NK_COMMAND_ARC_FILLED:
+            {
+                const struct nk_command_arc_filled *a = (const struct nk_command_arc_filled*)cmd;
+                cairo_set_source_rgba(cr, NK_TO_CAIRO(a->color.r), NK_TO_CAIRO(a->color.g), NK_TO_CAIRO(a->color.b), NK_TO_CAIRO(a->color.a));
+                cairo_arc(cr, a->cx, a->cy, a->r, NK_XCB_DEG_TO_RAD(a->a[0]), NK_XCB_DEG_TO_RAD(a->a[1]));
+                cairo_fill(cr);
+            }
+            break;
+        case NK_COMMAND_TRIANGLE:
+            {
+                const struct nk_command_triangle *t = (const struct nk_command_triangle *)cmd;
+                cairo_set_source_rgba(cr, NK_TO_CAIRO(t->color.r), NK_TO_CAIRO(t->color.g), NK_TO_CAIRO(t->color.b), NK_TO_CAIRO(t->color.a));
+                cairo_set_line_width(cr, t->line_thickness);
+                cairo_move_to(cr, t->a.x, t->a.y);
+                cairo_line_to(cr, t->b.x, t->b.y);
+                cairo_line_to(cr, t->c.x, t->c.y);
+                cairo_close_path(cr);
+                cairo_stroke(cr);
+            }
+            break;
+        case NK_COMMAND_TRIANGLE_FILLED:
+            {
+                const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled *)cmd;
+                cairo_set_source_rgba(cr, NK_TO_CAIRO(t->color.r), NK_TO_CAIRO(t->color.g), NK_TO_CAIRO(t->color.b), NK_TO_CAIRO(t->color.a));
+                cairo_move_to(cr, t->a.x, t->a.y);
+                cairo_line_to(cr, t->b.x, t->b.y);
+                cairo_line_to(cr, t->c.x, t->c.y);
+                cairo_close_path(cr);
+                cairo_fill(cr);
+            }
+            break;
+        case NK_COMMAND_POLYGON:
+            {
+                int i;
+                const struct nk_command_polygon *p = (const struct nk_command_polygon *)cmd;
+                cairo_set_source_rgba(cr, NK_TO_CAIRO(p->color.r), NK_TO_CAIRO(p->color.g), NK_TO_CAIRO(p->color.b), NK_TO_CAIRO(p->color.a));
+                cairo_set_line_width(cr, p->line_thickness);
+                cairo_move_to(cr, p->points[0].x, p->points[0].y);
+                for (i = 1; i < p->point_count; ++i) {
+                    cairo_line_to(cr, p->points[i].x, p->points[i].y);
+                }
+                cairo_close_path(cr);
+                cairo_stroke(cr);
+            }
+            break;
+        case NK_COMMAND_POLYGON_FILLED:
+            {
+                int i;
+                const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled *)cmd;
+                cairo_set_source_rgba (cr, NK_TO_CAIRO(p->color.r), NK_TO_CAIRO(p->color.g), NK_TO_CAIRO(p->color.b), NK_TO_CAIRO(p->color.a));
+                cairo_move_to(cr, p->points[0].x, p->points[0].y);
+                for (i = 1; i < p->point_count; ++i) {
+                    cairo_line_to(cr, p->points[i].x, p->points[i].y);
+                }
+                cairo_close_path(cr);
+                cairo_fill(cr);
+            }
+            break;
+        case NK_COMMAND_POLYLINE:
+            {
+                int i;
+                const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd;
+                cairo_set_source_rgba(cr, NK_TO_CAIRO(p->color.r), NK_TO_CAIRO(p->color.g), NK_TO_CAIRO(p->color.b), NK_TO_CAIRO(p->color.a));
+                cairo_set_line_width(cr, p->line_thickness);
+                cairo_move_to(cr, p->points[0].x, p->points[0].y);
+                for (i = 1; i < p->point_count; ++i) {
+                    cairo_line_to(cr, p->points[i].x, p->points[i].y);
+                }
+                cairo_stroke(cr);
+            }
+            break;
+        case NK_COMMAND_TEXT:
+            {
+                const struct nk_command_text *t = (const struct nk_command_text *)cmd;
+                cairo_glyph_t *glyphs = NULL;
+                int num_glyphs;
+                cairo_text_cluster_t *clusters = NULL;
+                int num_clusters;
+                cairo_text_cluster_flags_t cluster_flags;
+                cairo_font_extents_t extents;
+
+                cairo_set_source_rgba(cr, NK_TO_CAIRO(t->foreground.r), NK_TO_CAIRO(t->foreground.g), NK_TO_CAIRO(t->foreground.b), NK_TO_CAIRO(t->foreground.a));
+                cairo_scaled_font_extents(t->font->userdata.ptr, &extents);
+                cairo_scaled_font_text_to_glyphs(t->font->userdata.ptr,
+                        t->x, t->y + extents.ascent, t->string, t->length,
+                        &glyphs, &num_glyphs, &clusters, &num_clusters,
+                        &cluster_flags);
+                cairo_show_text_glyphs(cr, t->string, t->length, glyphs,
+                        num_glyphs, clusters, num_clusters,
+                        cluster_flags);
+                cairo_glyph_free(glyphs);
+                cairo_text_cluster_free(clusters);
+            }
+            break;
+        case NK_COMMAND_IMAGE:
+            {
+                /* from https://github.com/taiwins/twidgets/blob/master/src/nk_wl_cairo.c */
+                const struct nk_command_image *im = (const struct nk_command_image *)cmd;
+                cairo_surface_t *img_surf;
+                double sw = (double)im->w / (double)im->img.region[2];
+                double sh = (double)im->h / (double)im->img.region[3];
+                cairo_format_t format = CAIRO_FORMAT_ARGB32;
+                int stride = cairo_format_stride_for_width(format, im->img.w);
+
+                if (!im->img.handle.ptr) return;
+                img_surf = cairo_image_surface_create_for_data(im->img.handle.ptr, format, im->img.w, im->img.h, stride);
+                if (!img_surf) return;
+                cairo_save(cr);
+
+                cairo_rectangle(cr, im->x, im->y, im->w, im->h);
+                /* scale here, if after source set, the scale would not apply to source
+                 * surface
+                 */
+                cairo_scale(cr, sw, sh);
+                /* the coordinates system in cairo is not intuitive, scale, translate,
+                 * are applied to source. Refer to
+                 * "https://www.cairographics.org/FAQ/#paint_from_a_surface" for details
+                 * 
+                 * if you set source_origin to (0,0), it would be like source origin
+                 * aligned to dest origin, then if you draw a rectangle on (x, y, w, h).
+                 * it would clip out the (x, y, w, h) of the source on you dest as well.
+                 */
+                cairo_set_source_surface(cr, img_surf, im->x/sw - im->img.region[0], im->y/sh - im->img.region[1]);
+                cairo_fill(cr);
+
+                cairo_restore(cr);
+                cairo_surface_destroy(img_surf);
+            }
+            break;
+        case NK_COMMAND_CUSTOM:
+            {
+	            const struct nk_command_custom *cu = (const struct nk_command_custom *)cmd;
+                if (cu->callback) {
+                    cu->callback(cr, cu->x, cu->y, cu->w, cu->h, cu->callback_data);
+                }
+            }
+        default:
+            break;
+        }
+    }
+
+    cairo_pop_group_to_source(cr);
+    cairo_paint(cr);
+    cairo_surface_flush(cairo_ctx->surface);
+
+    return nk_true;
+}
+
+#endif /* NK_XCB_CAIRO_IMPLEMENTATION */

+ 43 - 22
nuklear.h

@@ -524,6 +524,10 @@ enum nk_symbol_type {
     NK_SYMBOL_TRIANGLE_RIGHT,
     NK_SYMBOL_PLUS,
     NK_SYMBOL_MINUS,
+    NK_SYMBOL_TRIANGLE_UP_OUTLINE,
+    NK_SYMBOL_TRIANGLE_DOWN_OUTLINE,
+    NK_SYMBOL_TRIANGLE_LEFT_OUTLINE,
+    NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE,
     NK_SYMBOL_MAX
 };
 /* =============================================================================
@@ -613,7 +617,7 @@ NK_API nk_bool nk_init_fixed(struct nk_context*, void *memory, nk_size size, con
 /// interface to nuklear. Can be useful for cases like monitoring memory consumption.
 ///
 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
-/// nk_bool nk_init(struct nk_context *ctx, struct nk_allocator *alloc, const struct nk_user_font *font);
+/// nk_bool nk_init(struct nk_context *ctx, const struct nk_allocator *alloc, const struct nk_user_font *font);
 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ///
 /// Parameter   | Description
@@ -624,7 +628,7 @@ NK_API nk_bool nk_init_fixed(struct nk_context*, void *memory, nk_size size, con
 ///
 /// Returns either `false(0)` on failure or `true(1)` on success.
 */
-NK_API nk_bool nk_init(struct nk_context*, struct nk_allocator*, const struct nk_user_font*);
+NK_API nk_bool nk_init(struct nk_context*, const struct nk_allocator*, const struct nk_user_font*);
 /*/// #### nk_init_custom
 /// Initializes a `nk_context` struct from two different either fixed or growing
 /// buffers. The first buffer is for allocating draw commands while the second buffer is
@@ -4132,8 +4136,8 @@ 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_init(struct nk_font_atlas*, const struct nk_allocator*);
+NK_API void nk_font_atlas_init_custom(struct nk_font_atlas*, const struct nk_allocator *persistent, const 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*);
@@ -4410,7 +4414,7 @@ NK_API nk_bool nk_filter_binary(const struct nk_text_edit*, nk_rune unicode);
 #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(struct nk_text_edit*, const 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);
@@ -5971,7 +5975,7 @@ NK_LIB struct nk_vec2 nk_text_calculate_text_bounds(const struct nk_user_font *f
 NK_LIB int nk_strfmt(char *buf, int buf_size, const char *fmt, va_list args);
 #endif
 #ifdef NK_INCLUDE_STANDARD_IO
-NK_LIB char *nk_file_load(const char* path, nk_size* siz, struct nk_allocator *alloc);
+NK_LIB char *nk_file_load(const char* path, nk_size* siz, const struct nk_allocator *alloc);
 #endif
 
 /* buffer */
@@ -6016,7 +6020,7 @@ NK_LIB struct nk_window *nk_find_window(struct nk_context *ctx, nk_hash hash, co
 NK_LIB void nk_insert_window(struct nk_context *ctx, struct nk_window *win, enum nk_window_insert_location loc);
 
 /* pool */
-NK_LIB void nk_pool_init(struct nk_pool *pool, struct nk_allocator *alloc, unsigned int capacity);
+NK_LIB void nk_pool_init(struct nk_pool *pool, const struct nk_allocator *alloc, unsigned int capacity);
 NK_LIB void nk_pool_free(struct nk_pool *pool);
 NK_LIB void nk_pool_init_fixed(struct nk_pool *pool, void *memory, nk_size size);
 NK_LIB struct nk_page_element *nk_pool_alloc(struct nk_pool *pool);
@@ -7493,7 +7497,7 @@ nk_murmur_hash(const void * key, int len, nk_hash seed)
 }
 #ifdef NK_INCLUDE_STANDARD_IO
 NK_LIB char*
-nk_file_load(const char* path, nk_size* siz, struct nk_allocator *alloc)
+nk_file_load(const char* path, nk_size* siz, const struct nk_allocator *alloc)
 {
     char *buf;
     FILE *fd;
@@ -16682,7 +16686,7 @@ nk_font_baker_memory(nk_size *temp, int *glyph_count,
     *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)
+nk_font_baker(void *memory, int glyph_count, int count, const struct nk_allocator *alloc)
 {
     struct nk_font_baker *baker;
     if (!memory) return 0;
@@ -16699,7 +16703,7 @@ 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)
+    const struct nk_allocator *alloc)
 {
     NK_STORAGE const nk_size max_height = 1024 * 32;
     const struct nk_font_config *config_iter, *it;
@@ -16728,7 +16732,7 @@ nk_font_bake_pack(struct nk_font_baker *baker,
         it = config_iter;
         do {
             struct stbtt_fontinfo *font_info = &baker->build[i++].info;
-            font_info->userdata = alloc;
+            font_info->userdata = (void*)alloc;
 
             if (!stbtt_InitFont(font_info, (const unsigned char*)it->ttf_blob, stbtt_GetFontOffsetForIndex((const unsigned char*)it->ttf_blob, 0)))
                 return nk_false;
@@ -16736,7 +16740,7 @@ nk_font_bake_pack(struct nk_font_baker *baker,
     }
     *height = 0;
     *width = (total_glyph_count > 1000) ? 1024 : 512;
-    stbtt_PackBegin(&baker->spc, 0, (int)*width, (int)max_height, 0, 1, alloc);
+    stbtt_PackBegin(&baker->spc, 0, (int)*width, (int)max_height, 0, 1, (void*)alloc);
     {
         int input_i = 0;
         int range_n = 0;
@@ -17429,7 +17433,7 @@ nk_font_atlas_init_default(struct nk_font_atlas *atlas)
 }
 #endif
 NK_API void
-nk_font_atlas_init(struct nk_font_atlas *atlas, struct nk_allocator *alloc)
+nk_font_atlas_init(struct nk_font_atlas *atlas, const struct nk_allocator *alloc)
 {
     NK_ASSERT(atlas);
     NK_ASSERT(alloc);
@@ -17440,7 +17444,7 @@ nk_font_atlas_init(struct nk_font_atlas *atlas, struct nk_allocator *alloc)
 }
 NK_API void
 nk_font_atlas_init_custom(struct nk_font_atlas *atlas,
-    struct nk_allocator *permanent, struct nk_allocator *temporary)
+    const struct nk_allocator *permanent, const struct nk_allocator *temporary)
 {
     NK_ASSERT(atlas);
     NK_ASSERT(permanent);
@@ -19098,7 +19102,7 @@ nk_init_custom(struct nk_context *ctx, struct nk_buffer *cmds,
     return 1;
 }
 NK_API nk_bool
-nk_init(struct nk_context *ctx, struct nk_allocator *alloc,
+nk_init(struct nk_context *ctx, const struct nk_allocator *alloc,
     const struct nk_user_font *font)
 {
     NK_ASSERT(alloc);
@@ -19387,7 +19391,7 @@ nk__next(struct nk_context *ctx, const struct nk_command *cmd)
  *
  * ===============================================================*/
 NK_LIB void
-nk_pool_init(struct nk_pool *pool, struct nk_allocator *alloc,
+nk_pool_init(struct nk_pool *pool, const struct nk_allocator *alloc,
     unsigned int capacity)
 {
     NK_ASSERT(capacity >= 1);
@@ -19910,7 +19914,7 @@ nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type pan
                 nk_draw_nine_slice(out, body, &style->window.fixed_background.data.slice, nk_white);
                 break;
             case NK_STYLE_ITEM_COLOR:
-                nk_fill_rect(out, body, 0, style->window.fixed_background.data.color);
+                nk_fill_rect(out, body, style->window.rounding, style->window.fixed_background.data.color);
                 break;
         }
     }
@@ -20106,7 +20110,7 @@ nk_panel_end(struct nk_context *ctx)
                 : (window->bounds.y + window->bounds.h));
         struct nk_rect b = window->bounds;
         b.h = padding_y - window->bounds.y;
-        nk_stroke_rect(out, b, 0, layout->border, border_color);
+        nk_stroke_rect(out, b, style->window.rounding, layout->border, border_color);
     }
 
     /* scaler */
@@ -24087,6 +24091,19 @@ nk_draw_symbol(struct nk_command_buffer *out, enum nk_symbol_type type,
         nk_fill_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y,
             points[2].x, points[2].y, foreground);
     } break;
+    case NK_SYMBOL_TRIANGLE_UP_OUTLINE:
+    case NK_SYMBOL_TRIANGLE_DOWN_OUTLINE:
+    case NK_SYMBOL_TRIANGLE_LEFT_OUTLINE:
+    case NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE: {
+        enum nk_heading heading;
+        struct nk_vec2 points[3];
+        heading = (type == NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE) ? NK_RIGHT :
+            (type == NK_SYMBOL_TRIANGLE_LEFT_OUTLINE) ? NK_LEFT:
+            (type == NK_SYMBOL_TRIANGLE_UP_OUTLINE) ? NK_UP: NK_DOWN;
+        nk_triangle_from_direction(points, content, 0, 0, heading);
+        nk_stroke_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y,
+            points[2].x, points[2].y, border_width, foreground);
+    } break;
     default:
     case NK_SYMBOL_NONE:
     case NK_SYMBOL_MAX: break;
@@ -27211,7 +27228,7 @@ nk_textedit_init_fixed(struct nk_text_edit *state, void *memory, nk_size size)
     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_textedit_init(struct nk_text_edit *state, const struct nk_allocator *alloc, nk_size size)
 {
     NK_ASSERT(state);
     NK_ASSERT(alloc);
@@ -28187,7 +28204,9 @@ nk_draw_property(struct nk_command_buffer *out, const struct nk_style_property *
 
     /* draw label */
     text.padding = nk_vec2(0,0);
-    nk_widget_text(out, *label, name, len, &text, NK_TEXT_CENTERED, font);
+    if (name && name[0] != '#') {
+        nk_widget_text(out, *label, name, len, &text, NK_TEXT_CENTERED, font);
+    }
 }
 NK_LIB void
 nk_do_property(nk_flags *ws,
@@ -28205,7 +28224,7 @@ nk_do_property(nk_flags *ws,
         nk_filter_float
     };
     nk_bool active, old;
-    int num_len = 0, name_len;
+    int num_len = 0, name_len = 0;
     char string[NK_MAX_NUMBER_BUFFER];
     float size;
 
@@ -28225,7 +28244,9 @@ nk_do_property(nk_flags *ws,
     left.y = property.y + style->border + property.h/2.0f - left.h/2;
 
     /* text label */
-    name_len = nk_strlen(name);
+    if (name && name[0] != '#') {
+        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;

+ 9 - 5
src/nuklear.h

@@ -302,6 +302,10 @@ enum nk_symbol_type {
     NK_SYMBOL_TRIANGLE_RIGHT,
     NK_SYMBOL_PLUS,
     NK_SYMBOL_MINUS,
+    NK_SYMBOL_TRIANGLE_UP_OUTLINE,
+    NK_SYMBOL_TRIANGLE_DOWN_OUTLINE,
+    NK_SYMBOL_TRIANGLE_LEFT_OUTLINE,
+    NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE,
     NK_SYMBOL_MAX
 };
 /* =============================================================================
@@ -391,7 +395,7 @@ NK_API nk_bool nk_init_fixed(struct nk_context*, void *memory, nk_size size, con
 /// interface to nuklear. Can be useful for cases like monitoring memory consumption.
 ///
 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
-/// nk_bool nk_init(struct nk_context *ctx, struct nk_allocator *alloc, const struct nk_user_font *font);
+/// nk_bool nk_init(struct nk_context *ctx, const struct nk_allocator *alloc, const struct nk_user_font *font);
 /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ///
 /// Parameter   | Description
@@ -402,7 +406,7 @@ NK_API nk_bool nk_init_fixed(struct nk_context*, void *memory, nk_size size, con
 ///
 /// Returns either `false(0)` on failure or `true(1)` on success.
 */
-NK_API nk_bool nk_init(struct nk_context*, struct nk_allocator*, const struct nk_user_font*);
+NK_API nk_bool nk_init(struct nk_context*, const struct nk_allocator*, const struct nk_user_font*);
 /*/// #### nk_init_custom
 /// Initializes a `nk_context` struct from two different either fixed or growing
 /// buffers. The first buffer is for allocating draw commands while the second buffer is
@@ -3910,8 +3914,8 @@ 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_init(struct nk_font_atlas*, const struct nk_allocator*);
+NK_API void nk_font_atlas_init_custom(struct nk_font_atlas*, const struct nk_allocator *persistent, const 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*);
@@ -4188,7 +4192,7 @@ NK_API nk_bool nk_filter_binary(const struct nk_text_edit*, nk_rune unicode);
 #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(struct nk_text_edit*, const 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);

+ 13 - 0
src/nuklear_button.c

@@ -54,6 +54,19 @@ nk_draw_symbol(struct nk_command_buffer *out, enum nk_symbol_type type,
         nk_fill_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y,
             points[2].x, points[2].y, foreground);
     } break;
+    case NK_SYMBOL_TRIANGLE_UP_OUTLINE:
+    case NK_SYMBOL_TRIANGLE_DOWN_OUTLINE:
+    case NK_SYMBOL_TRIANGLE_LEFT_OUTLINE:
+    case NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE: {
+        enum nk_heading heading;
+        struct nk_vec2 points[3];
+        heading = (type == NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE) ? NK_RIGHT :
+            (type == NK_SYMBOL_TRIANGLE_LEFT_OUTLINE) ? NK_LEFT:
+            (type == NK_SYMBOL_TRIANGLE_UP_OUTLINE) ? NK_UP: NK_DOWN;
+        nk_triangle_from_direction(points, content, 0, 0, heading);
+        nk_stroke_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y,
+            points[2].x, points[2].y, border_width, foreground);
+    } break;
     default:
     case NK_SYMBOL_NONE:
     case NK_SYMBOL_MAX: break;

+ 1 - 1
src/nuklear_context.c

@@ -63,7 +63,7 @@ nk_init_custom(struct nk_context *ctx, struct nk_buffer *cmds,
     return 1;
 }
 NK_API nk_bool
-nk_init(struct nk_context *ctx, struct nk_allocator *alloc,
+nk_init(struct nk_context *ctx, const struct nk_allocator *alloc,
     const struct nk_user_font *font)
 {
     NK_ASSERT(alloc);

+ 6 - 6
src/nuklear_font.c

@@ -146,7 +146,7 @@ nk_font_baker_memory(nk_size *temp, int *glyph_count,
     *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)
+nk_font_baker(void *memory, int glyph_count, int count, const struct nk_allocator *alloc)
 {
     struct nk_font_baker *baker;
     if (!memory) return 0;
@@ -163,7 +163,7 @@ 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)
+    const struct nk_allocator *alloc)
 {
     NK_STORAGE const nk_size max_height = 1024 * 32;
     const struct nk_font_config *config_iter, *it;
@@ -192,7 +192,7 @@ nk_font_bake_pack(struct nk_font_baker *baker,
         it = config_iter;
         do {
             struct stbtt_fontinfo *font_info = &baker->build[i++].info;
-            font_info->userdata = alloc;
+            font_info->userdata = (void*)alloc;
 
             if (!stbtt_InitFont(font_info, (const unsigned char*)it->ttf_blob, stbtt_GetFontOffsetForIndex((const unsigned char*)it->ttf_blob, 0)))
                 return nk_false;
@@ -200,7 +200,7 @@ nk_font_bake_pack(struct nk_font_baker *baker,
     }
     *height = 0;
     *width = (total_glyph_count > 1000) ? 1024 : 512;
-    stbtt_PackBegin(&baker->spc, 0, (int)*width, (int)max_height, 0, 1, alloc);
+    stbtt_PackBegin(&baker->spc, 0, (int)*width, (int)max_height, 0, 1, (void*)alloc);
     {
         int input_i = 0;
         int range_n = 0;
@@ -893,7 +893,7 @@ nk_font_atlas_init_default(struct nk_font_atlas *atlas)
 }
 #endif
 NK_API void
-nk_font_atlas_init(struct nk_font_atlas *atlas, struct nk_allocator *alloc)
+nk_font_atlas_init(struct nk_font_atlas *atlas, const struct nk_allocator *alloc)
 {
     NK_ASSERT(atlas);
     NK_ASSERT(alloc);
@@ -904,7 +904,7 @@ nk_font_atlas_init(struct nk_font_atlas *atlas, struct nk_allocator *alloc)
 }
 NK_API void
 nk_font_atlas_init_custom(struct nk_font_atlas *atlas,
-    struct nk_allocator *permanent, struct nk_allocator *temporary)
+    const struct nk_allocator *permanent, const struct nk_allocator *temporary)
 {
     NK_ASSERT(atlas);
     NK_ASSERT(permanent);

+ 2 - 2
src/nuklear_internal.h

@@ -138,7 +138,7 @@ NK_LIB struct nk_vec2 nk_text_calculate_text_bounds(const struct nk_user_font *f
 NK_LIB int nk_strfmt(char *buf, int buf_size, const char *fmt, va_list args);
 #endif
 #ifdef NK_INCLUDE_STANDARD_IO
-NK_LIB char *nk_file_load(const char* path, nk_size* siz, struct nk_allocator *alloc);
+NK_LIB char *nk_file_load(const char* path, nk_size* siz, const struct nk_allocator *alloc);
 #endif
 
 /* buffer */
@@ -183,7 +183,7 @@ NK_LIB struct nk_window *nk_find_window(struct nk_context *ctx, nk_hash hash, co
 NK_LIB void nk_insert_window(struct nk_context *ctx, struct nk_window *win, enum nk_window_insert_location loc);
 
 /* pool */
-NK_LIB void nk_pool_init(struct nk_pool *pool, struct nk_allocator *alloc, unsigned int capacity);
+NK_LIB void nk_pool_init(struct nk_pool *pool, const struct nk_allocator *alloc, unsigned int capacity);
 NK_LIB void nk_pool_free(struct nk_pool *pool);
 NK_LIB void nk_pool_init_fixed(struct nk_pool *pool, void *memory, nk_size size);
 NK_LIB struct nk_page_element *nk_pool_alloc(struct nk_pool *pool);

+ 2 - 2
src/nuklear_panel.c

@@ -309,7 +309,7 @@ nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type pan
                 nk_draw_nine_slice(out, body, &style->window.fixed_background.data.slice, nk_white);
                 break;
             case NK_STYLE_ITEM_COLOR:
-                nk_fill_rect(out, body, 0, style->window.fixed_background.data.color);
+                nk_fill_rect(out, body, style->window.rounding, style->window.fixed_background.data.color);
                 break;
         }
     }
@@ -505,7 +505,7 @@ nk_panel_end(struct nk_context *ctx)
                 : (window->bounds.y + window->bounds.h));
         struct nk_rect b = window->bounds;
         b.h = padding_y - window->bounds.y;
-        nk_stroke_rect(out, b, 0, layout->border, border_color);
+        nk_stroke_rect(out, b, style->window.rounding, layout->border, border_color);
     }
 
     /* scaler */

+ 1 - 1
src/nuklear_pool.c

@@ -7,7 +7,7 @@
  *
  * ===============================================================*/
 NK_LIB void
-nk_pool_init(struct nk_pool *pool, struct nk_allocator *alloc,
+nk_pool_init(struct nk_pool *pool, const struct nk_allocator *alloc,
     unsigned int capacity)
 {
     NK_ASSERT(capacity >= 1);

+ 7 - 3
src/nuklear_property.c

@@ -106,7 +106,9 @@ nk_draw_property(struct nk_command_buffer *out, const struct nk_style_property *
 
     /* draw label */
     text.padding = nk_vec2(0,0);
-    nk_widget_text(out, *label, name, len, &text, NK_TEXT_CENTERED, font);
+    if (name && name[0] != '#') {
+        nk_widget_text(out, *label, name, len, &text, NK_TEXT_CENTERED, font);
+    }
 }
 NK_LIB void
 nk_do_property(nk_flags *ws,
@@ -124,7 +126,7 @@ nk_do_property(nk_flags *ws,
         nk_filter_float
     };
     nk_bool active, old;
-    int num_len = 0, name_len;
+    int num_len = 0, name_len = 0;
     char string[NK_MAX_NUMBER_BUFFER];
     float size;
 
@@ -144,7 +146,9 @@ nk_do_property(nk_flags *ws,
     left.y = property.y + style->border + property.h/2.0f - left.h/2;
 
     /* text label */
-    name_len = nk_strlen(name);
+    if (name && name[0] != '#') {
+        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;

+ 1 - 1
src/nuklear_text_editor.c

@@ -992,7 +992,7 @@ nk_textedit_init_fixed(struct nk_text_edit *state, void *memory, nk_size size)
     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_textedit_init(struct nk_text_edit *state, const struct nk_allocator *alloc, nk_size size)
 {
     NK_ASSERT(state);
     NK_ASSERT(alloc);

+ 1 - 1
src/nuklear_util.c

@@ -984,7 +984,7 @@ nk_murmur_hash(const void * key, int len, nk_hash seed)
 }
 #ifdef NK_INCLUDE_STANDARD_IO
 NK_LIB char*
-nk_file_load(const char* path, nk_size* siz, struct nk_allocator *alloc)
+nk_file_load(const char* path, nk_size* siz, const struct nk_allocator *alloc)
 {
     char *buf;
     FILE *fd;