219 #ifndef NK_SINGLE_FILE
220 #define NK_SINGLE_FILE
228 #ifndef NK_NUKLEAR_H_
229 #define NK_NUKLEAR_H_
242 #define NK_UNDEFINED (-1.0f)
243 #define NK_UTF_INVALID 0xFFFD
244 #define NK_UTF_SIZE 4
246 #define NK_INPUT_MAX 16
248 #ifndef NK_MAX_NUMBER_BUFFER
249 #define NK_MAX_NUMBER_BUFFER 64
251 #ifndef NK_SCROLLBAR_HIDING_TIMEOUT
252 #define NK_SCROLLBAR_HIDING_TIMEOUT 4.0f
264 #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199409L))
265 #define NK_API static inline
266 #elif defined(__cplusplus)
267 #define NK_API static inline
269 #define NK_API static
272 #define NK_API extern
276 #ifdef NK_SINGLE_FILE
277 #define NK_LIB static
279 #define NK_LIB extern
283 #define NK_INTERN static
284 #define NK_STORAGE static
285 #define NK_GLOBAL static
287 #define NK_FLAG(x) (1 << (x))
288 #define NK_STRINGIFY(x) #x
289 #define NK_MACRO_STRINGIFY(x) NK_STRINGIFY(x)
290 #define NK_STRING_JOIN_IMMEDIATE(arg1, arg2) arg1 ## arg2
291 #define NK_STRING_JOIN_DELAY(arg1, arg2) NK_STRING_JOIN_IMMEDIATE(arg1, arg2)
292 #define NK_STRING_JOIN(arg1, arg2) NK_STRING_JOIN_DELAY(arg1, arg2)
295 #define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__COUNTER__)
297 #define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__LINE__)
300 #ifndef NK_STATIC_ASSERT
301 #define NK_STATIC_ASSERT(exp) typedef char NK_UNIQUE_NAME(_dummy_array)[(exp)?1:-1]
306 #define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__COUNTER__)
308 #define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__LINE__)
312 #define NK_MIN(a,b) ((a) < (b) ? (a) : (b))
313 #define NK_MAX(a,b) ((a) < (b) ? (b) : (a))
314 #define NK_CLAMP(i,v,x) (NK_MAX(NK_MIN(v,x), i))
316 #ifdef NK_INCLUDE_STANDARD_VARARGS
318 #if defined(_MSC_VER) && (_MSC_VER >= 1600)
320 #define NK_PRINTF_FORMAT_STRING _Printf_format_string_
322 #define NK_PRINTF_FORMAT_STRING
324 #if defined(__GNUC__)
325 #define NK_PRINTF_VARARG_FUNC(fmtargnumber) __attribute__((format(__printf__, fmtargnumber, fmtargnumber+1)))
326 #define NK_PRINTF_VALIST_FUNC(fmtargnumber) __attribute__((format(__printf__, fmtargnumber, 0)))
328 #define NK_PRINTF_VARARG_FUNC(fmtargnumber)
329 #define NK_PRINTF_VALIST_FUNC(fmtargnumber)
340 #ifdef NK_INCLUDE_FIXED_TYPES
342 #define NK_INT8 int8_t
343 #define NK_UINT8 uint8_t
344 #define NK_INT16 int16_t
345 #define NK_UINT16 uint16_t
346 #define NK_INT32 int32_t
347 #define NK_UINT32 uint32_t
348 #define NK_SIZE_TYPE uintptr_t
349 #define NK_POINTER_TYPE uintptr_t
352 #define NK_INT8 signed char
355 #define NK_UINT8 unsigned char
358 #define NK_INT16 signed short
361 #define NK_UINT16 unsigned short
364 #if defined(_MSC_VER)
365 #define NK_INT32 __int32
367 #define NK_INT32 signed int
371 #if defined(_MSC_VER)
372 #define NK_UINT32 unsigned __int32
374 #define NK_UINT32 unsigned int
378 #if defined(_WIN64) && defined(_MSC_VER)
379 #define NK_SIZE_TYPE unsigned __int64
380 #elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
381 #define NK_SIZE_TYPE unsigned __int32
382 #elif defined(__GNUC__) || defined(__clang__)
383 #if defined(__x86_64__) || defined(__ppc64__) || defined(__PPC64__) || defined(__aarch64__)
384 #define NK_SIZE_TYPE unsigned long
386 #define NK_SIZE_TYPE unsigned int
389 #define NK_SIZE_TYPE unsigned long
392 #ifndef NK_POINTER_TYPE
393 #if defined(_WIN64) && defined(_MSC_VER)
394 #define NK_POINTER_TYPE unsigned __int64
395 #elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
396 #define NK_POINTER_TYPE unsigned __int32
397 #elif defined(__GNUC__) || defined(__clang__)
398 #if defined(__x86_64__) || defined(__ppc64__) || defined(__PPC64__) || defined(__aarch64__)
399 #define NK_POINTER_TYPE unsigned long
401 #define NK_POINTER_TYPE unsigned int
404 #define NK_POINTER_TYPE unsigned long
410 #ifdef NK_INCLUDE_STANDARD_BOOL
418 typedef NK_INT8 nk_char;
419 typedef NK_UINT8 nk_uchar;
420 typedef NK_UINT8 nk_byte;
421 typedef NK_INT16 nk_short;
422 typedef NK_UINT16 nk_ushort;
423 typedef NK_INT32 nk_int;
424 typedef NK_UINT32 nk_uint;
425 typedef NK_SIZE_TYPE nk_size;
426 typedef NK_POINTER_TYPE nk_ptr;
429 typedef nk_uint nk_hash;
430 typedef nk_uint nk_flags;
431 typedef nk_uint nk_rune;
436 NK_STATIC_ASSERT(
sizeof(nk_short) == 2);
437 NK_STATIC_ASSERT(
sizeof(nk_ushort) == 2);
438 NK_STATIC_ASSERT(
sizeof(nk_uint) == 4);
439 NK_STATIC_ASSERT(
sizeof(nk_int) == 4);
440 NK_STATIC_ASSERT(
sizeof(nk_byte) == 1);
441 NK_STATIC_ASSERT(
sizeof(nk_flags) >= 4);
442 NK_STATIC_ASSERT(
sizeof(nk_rune) >= 4);
443 NK_STATIC_ASSERT(
sizeof(nk_size) >=
sizeof(
void*));
444 NK_STATIC_ASSERT(
sizeof(nk_ptr) >=
sizeof(
void*));
445 #ifdef NK_INCLUDE_STANDARD_BOOL
446 NK_STATIC_ASSERT(
sizeof(nk_bool) ==
sizeof(
bool));
448 NK_STATIC_ASSERT(
sizeof(nk_bool) >= 2);
459 struct nk_draw_command;
467 struct nk_draw_vertex_layout_element;
471 struct nk_style_slide;
482 enum {nk_false, nk_true};
496 enum nk_heading {NK_UP, NK_RIGHT, NK_DOWN, NK_LEFT};
497 enum nk_button_behavior {NK_BUTTON_DEFAULT, NK_BUTTON_REPEATER};
498 enum nk_modify {NK_FIXED = nk_false, NK_MODIFIABLE = nk_true};
499 enum nk_orientation {NK_VERTICAL, NK_HORIZONTAL};
500 enum nk_collapse_states {NK_MINIMIZED = nk_false, NK_MAXIMIZED = nk_true};
501 enum nk_show_states {NK_HIDDEN = nk_false, NK_SHOWN = nk_true};
502 enum nk_chart_type {NK_CHART_LINES, NK_CHART_COLUMN, NK_CHART_MAX};
503 enum nk_chart_event {NK_CHART_HOVERING = 0x01, NK_CHART_CLICKED = 0x02};
504 enum nk_color_format {NK_RGB, NK_RGBA};
505 enum nk_popup_type {NK_POPUP_STATIC, NK_POPUP_DYNAMIC};
506 enum nk_layout_format {NK_DYNAMIC, NK_STATIC};
507 enum nk_tree_type {NK_TREE_NODE, NK_TREE_TAB};
509 typedef void*(*nk_plugin_alloc)(
nk_handle,
void *old, nk_size);
510 typedef void (*nk_plugin_free)(
nk_handle,
void *old);
511 typedef nk_bool(*nk_plugin_filter)(
const struct nk_text_edit*, nk_rune unicode);
513 typedef void(*nk_plugin_copy)(
nk_handle,
const char*,
int len);
517 nk_plugin_alloc alloc;
520 enum nk_symbol_type {
523 NK_SYMBOL_UNDERSCORE,
524 NK_SYMBOL_CIRCLE_SOLID,
525 NK_SYMBOL_CIRCLE_OUTLINE,
526 NK_SYMBOL_RECT_SOLID,
527 NK_SYMBOL_RECT_OUTLINE,
528 NK_SYMBOL_TRIANGLE_UP,
529 NK_SYMBOL_TRIANGLE_DOWN,
530 NK_SYMBOL_TRIANGLE_LEFT,
531 NK_SYMBOL_TRIANGLE_RIGHT,
534 NK_SYMBOL_TRIANGLE_UP_OUTLINE,
535 NK_SYMBOL_TRIANGLE_DOWN_OUTLINE,
536 NK_SYMBOL_TRIANGLE_LEFT_OUTLINE,
537 NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE,
580 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
666 #ifdef NK_INCLUDE_COMMAND_USERDATA
762 NK_KEY_TEXT_INSERT_MODE,
763 NK_KEY_TEXT_REPLACE_MODE,
764 NK_KEY_TEXT_RESET_MODE,
765 NK_KEY_TEXT_LINE_START,
766 NK_KEY_TEXT_LINE_END,
771 NK_KEY_TEXT_SELECT_ALL,
772 NK_KEY_TEXT_WORD_LEFT,
773 NK_KEY_TEXT_WORD_RIGHT,
1131 enum nk_anti_aliasing {NK_ANTI_ALIASING_OFF, NK_ANTI_ALIASING_ON};
1132 enum nk_convert_result {
1133 NK_CONVERT_SUCCESS = 0,
1134 NK_CONVERT_INVALID_PARAM = 1,
1135 NK_CONVERT_COMMAND_BUFFER_FULL = NK_FLAG(1),
1136 NK_CONVERT_VERTEX_BUFFER_FULL = NK_FLAG(2),
1137 NK_CONVERT_ELEMENT_BUFFER_FULL = NK_FLAG(3)
1145 enum nk_anti_aliasing
line_AA;
1187 #define nk_foreach(c, ctx) for((c) = nk__begin(ctx); (c) != 0; (c) = nk__next(ctx,c))
1189 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
1227 NK_API
const struct nk_draw_command* nk__draw_begin(
const struct nk_context*,
const struct nk_buffer*);
1238 NK_API
const struct nk_draw_command* nk__draw_end(
const struct nk_context*,
const struct nk_buffer*);
1251 NK_API
const struct nk_draw_command* nk__draw_next(
const struct nk_draw_command*,
const struct nk_buffer*,
const struct nk_context*);
1262 #define nk_draw_foreach(cmd,ctx, b) for((cmd)=nk__draw_begin(ctx, b); (cmd)!=0; (cmd)=nk__draw_next(cmd, b, ctx))
1409 enum nk_panel_flags {
1410 NK_WINDOW_BORDER = NK_FLAG(0),
1411 NK_WINDOW_MOVABLE = NK_FLAG(1),
1412 NK_WINDOW_SCALABLE = NK_FLAG(2),
1413 NK_WINDOW_CLOSABLE = NK_FLAG(3),
1414 NK_WINDOW_MINIMIZABLE = NK_FLAG(4),
1415 NK_WINDOW_NO_SCROLLBAR = NK_FLAG(5),
1416 NK_WINDOW_TITLE = NK_FLAG(6),
1417 NK_WINDOW_SCROLL_AUTO_HIDE = NK_FLAG(7),
1418 NK_WINDOW_BACKGROUND = NK_FLAG(8),
1419 NK_WINDOW_SCALE_LEFT = NK_FLAG(9),
1420 NK_WINDOW_NO_INPUT = NK_FLAG(10)
2184 enum nk_widget_align {
2185 NK_WIDGET_ALIGN_LEFT = 0x01,
2186 NK_WIDGET_ALIGN_CENTERED = 0x02,
2187 NK_WIDGET_ALIGN_RIGHT = 0x04,
2188 NK_WIDGET_ALIGN_TOP = 0x08,
2189 NK_WIDGET_ALIGN_MIDDLE = 0x10,
2190 NK_WIDGET_ALIGN_BOTTOM = 0x20
2192 enum nk_widget_alignment {
2193 NK_WIDGET_LEFT = NK_WIDGET_ALIGN_MIDDLE|NK_WIDGET_ALIGN_LEFT,
2194 NK_WIDGET_CENTERED = NK_WIDGET_ALIGN_MIDDLE|NK_WIDGET_ALIGN_CENTERED,
2195 NK_WIDGET_RIGHT = NK_WIDGET_ALIGN_MIDDLE|NK_WIDGET_ALIGN_RIGHT
2738 #define nk_tree_push(ctx, type, title, state) nk_tree_push_hashed(ctx, type, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),__LINE__)
2753 #define nk_tree_push_id(ctx, type, title, state, id) nk_tree_push_hashed(ctx, type, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),id)
2770 NK_API nk_bool
nk_tree_push_hashed(
struct nk_context*,
enum nk_tree_type,
const char *title,
enum nk_collapse_states initial_state,
const char *hash,
int len,
int seed);
2790 #define nk_tree_image_push(ctx, type, img, title, state) nk_tree_image_push_hashed(ctx, type, img, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),__LINE__)
2807 #define nk_tree_image_push_id(ctx, type, img, title, state, id) nk_tree_image_push_hashed(ctx, type, img, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),id)
2874 #define nk_tree_element_push(ctx, type, title, state, sel) nk_tree_element_push_hashed(ctx, type, title, state, sel, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),__LINE__)
2875 #define nk_tree_element_push_id(ctx, type, title, state, sel, id) nk_tree_element_push_hashed(ctx, type, title, state, sel, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),id)
2876 NK_API nk_bool nk_tree_element_push_hashed(
struct nk_context*,
enum nk_tree_type,
const char *title,
enum nk_collapse_states initial_state, nk_bool *selected,
const char *hash,
int len,
int seed);
2877 NK_API nk_bool nk_tree_element_image_push_hashed(
struct nk_context*,
enum nk_tree_type,
struct nk_image,
const char *title,
enum nk_collapse_states initial_state, nk_bool *selected,
const char *hash,
int len,
int seed);
2878 NK_API
void nk_tree_element_pop(
struct nk_context*);
2887 int begin, end, count;
2891 nk_uint *scroll_pointer;
2892 nk_uint scroll_value;
2894 NK_API nk_bool nk_list_view_begin(
struct nk_context*,
struct nk_list_view *out,
const char *
id, nk_flags,
int row_height,
int row_count);
2908 NK_WIDGET_STATE_MODIFIED = NK_FLAG(1),
2909 NK_WIDGET_STATE_INACTIVE = NK_FLAG(2),
2922 NK_API
float nk_widget_width(
const struct nk_context*);
2923 NK_API
float nk_widget_height(
const struct nk_context*);
2924 NK_API nk_bool nk_widget_is_hovered(
const struct nk_context*);
2925 NK_API nk_bool nk_widget_is_mouse_clicked(
const struct nk_context*,
enum nk_buttons);
2926 NK_API nk_bool nk_widget_has_mouse_click_down(
const struct nk_context*,
enum nk_buttons, nk_bool down);
2927 NK_API
void nk_spacing(
struct nk_context*,
int cols);
2928 NK_API
void nk_widget_disable_begin(
struct nk_context* ctx);
2929 NK_API
void nk_widget_disable_end(
struct nk_context* ctx);
2935 enum nk_text_align {
2936 NK_TEXT_ALIGN_LEFT = 0x01,
2937 NK_TEXT_ALIGN_CENTERED = 0x02,
2938 NK_TEXT_ALIGN_RIGHT = 0x04,
2939 NK_TEXT_ALIGN_TOP = 0x08,
2940 NK_TEXT_ALIGN_MIDDLE = 0x10,
2941 NK_TEXT_ALIGN_BOTTOM = 0x20
2943 enum nk_text_alignment {
2944 NK_TEXT_LEFT = NK_TEXT_ALIGN_MIDDLE|NK_TEXT_ALIGN_LEFT,
2945 NK_TEXT_CENTERED = NK_TEXT_ALIGN_MIDDLE|NK_TEXT_ALIGN_CENTERED,
2946 NK_TEXT_RIGHT = NK_TEXT_ALIGN_MIDDLE|NK_TEXT_ALIGN_RIGHT
2948 NK_API
void nk_text(
struct nk_context*,
const char*,
int, nk_flags);
2949 NK_API
void nk_text_colored(
struct nk_context*,
const char*,
int, nk_flags,
struct nk_color);
2950 NK_API
void nk_text_wrap(
struct nk_context*,
const char*,
int);
2951 NK_API
void nk_text_wrap_colored(
struct nk_context*,
const char*,
int,
struct nk_color);
2952 NK_API
void nk_label(
struct nk_context*,
const char*, nk_flags align);
2953 NK_API
void nk_label_colored(
struct nk_context*,
const char*, nk_flags align,
struct nk_color);
2954 NK_API
void nk_label_wrap(
struct nk_context*,
const char*);
2958 #ifdef NK_INCLUDE_STANDARD_VARARGS
2959 NK_API
void nk_labelf(
struct nk_context*, nk_flags, NK_PRINTF_FORMAT_STRING
const char*, ...) NK_PRINTF_VARARG_FUNC(3);
2960 NK_API
void nk_labelf_colored(struct
nk_context*, nk_flags, struct
nk_color, NK_PRINTF_FORMAT_STRING const
char*,...) NK_PRINTF_VARARG_FUNC(4);
2961 NK_API
void nk_labelf_wrap(struct
nk_context*, NK_PRINTF_FORMAT_STRING const
char*,...) NK_PRINTF_VARARG_FUNC(2);
2962 NK_API
void nk_labelf_colored_wrap(struct
nk_context*, struct
nk_color, NK_PRINTF_FORMAT_STRING const
char*,...) NK_PRINTF_VARARG_FUNC(3);
2963 NK_API
void nk_labelfv(struct
nk_context*, nk_flags, NK_PRINTF_FORMAT_STRING const
char*, va_list) NK_PRINTF_VALIST_FUNC(3);
2964 NK_API
void nk_labelfv_colored(struct
nk_context*, nk_flags, struct
nk_color, NK_PRINTF_FORMAT_STRING const
char*, va_list) NK_PRINTF_VALIST_FUNC(4);
2965 NK_API
void nk_labelfv_wrap(struct
nk_context*, NK_PRINTF_FORMAT_STRING const
char*, va_list) NK_PRINTF_VALIST_FUNC(2);
2966 NK_API
void nk_labelfv_colored_wrap(struct
nk_context*, struct
nk_color, NK_PRINTF_FORMAT_STRING const
char*, va_list) NK_PRINTF_VALIST_FUNC(3);
2967 NK_API
void nk_value_bool(struct
nk_context*, const
char *prefix,
int);
2968 NK_API
void nk_value_int(struct
nk_context*, const
char *prefix,
int);
2969 NK_API
void nk_value_uint(struct
nk_context*, const
char *prefix,
unsigned int);
2970 NK_API
void nk_value_float(struct
nk_context*, const
char *prefix,
float);
2971 NK_API
void nk_value_color_byte(struct
nk_context*, const
char *prefix, struct
nk_color);
2972 NK_API
void nk_value_color_float(struct
nk_context*, const
char *prefix, struct
nk_color);
2973 NK_API
void nk_value_color_hex(struct
nk_context*, const
char *prefix, struct
nk_color);
2980 NK_API nk_bool nk_button_text(
struct nk_context*,
const char *title,
int len);
2981 NK_API nk_bool nk_button_label(
struct nk_context*,
const char *title);
2983 NK_API nk_bool nk_button_symbol(
struct nk_context*,
enum nk_symbol_type);
2985 NK_API nk_bool nk_button_symbol_label(
struct nk_context*,
enum nk_symbol_type,
const char*, nk_flags text_alignment);
2986 NK_API nk_bool nk_button_symbol_text(
struct nk_context*,
enum nk_symbol_type,
const char*,
int, nk_flags alignment);
2987 NK_API nk_bool nk_button_image_label(
struct nk_context*,
struct nk_image img,
const char*, nk_flags text_alignment);
2988 NK_API nk_bool nk_button_image_text(
struct nk_context*,
struct nk_image img,
const char*,
int, nk_flags alignment);
2993 NK_API nk_bool nk_button_symbol_text_styled(
struct nk_context*,
const struct nk_style_button*,
enum nk_symbol_type,
const char*,
int, nk_flags alignment);
2994 NK_API nk_bool nk_button_symbol_label_styled(
struct nk_context *ctx,
const struct nk_style_button *style,
enum nk_symbol_type symbol,
const char *title, nk_flags align);
2997 NK_API
void nk_button_set_behavior(
struct nk_context*,
enum nk_button_behavior);
2998 NK_API nk_bool nk_button_push_behavior(
struct nk_context*,
enum nk_button_behavior);
2999 NK_API nk_bool nk_button_pop_behavior(
struct nk_context*);
3005 NK_API nk_bool nk_check_label(
struct nk_context*,
const char*, nk_bool active);
3006 NK_API nk_bool nk_check_text(
struct nk_context*,
const char*,
int, nk_bool active);
3007 NK_API nk_bool nk_check_text_align(
struct nk_context*,
const char*,
int, nk_bool active, nk_flags widget_alignment, nk_flags text_alignment);
3008 NK_API
unsigned nk_check_flags_label(
struct nk_context*,
const char*,
unsigned int flags,
unsigned int value);
3009 NK_API
unsigned nk_check_flags_text(
struct nk_context*,
const char*,
int,
unsigned int flags,
unsigned int value);
3010 NK_API nk_bool nk_checkbox_label(
struct nk_context*,
const char*, nk_bool *active);
3011 NK_API nk_bool nk_checkbox_label_align(
struct nk_context *ctx,
const char *label, nk_bool *active, nk_flags widget_alignment, nk_flags text_alignment);
3012 NK_API nk_bool nk_checkbox_text(
struct nk_context*,
const char*,
int, nk_bool *active);
3013 NK_API nk_bool nk_checkbox_text_align(
struct nk_context *ctx,
const char *text,
int len, nk_bool *active, nk_flags widget_alignment, nk_flags text_alignment);
3014 NK_API nk_bool nk_checkbox_flags_label(
struct nk_context*,
const char*,
unsigned int *flags,
unsigned int value);
3015 NK_API nk_bool nk_checkbox_flags_text(
struct nk_context*,
const char*,
int,
unsigned int *flags,
unsigned int value);
3021 NK_API nk_bool nk_radio_label(
struct nk_context*,
const char*, nk_bool *active);
3022 NK_API nk_bool nk_radio_label_align(
struct nk_context *ctx,
const char *label, nk_bool *active, nk_flags widget_alignment, nk_flags text_alignment);
3023 NK_API nk_bool nk_radio_text(
struct nk_context*,
const char*,
int, nk_bool *active);
3024 NK_API nk_bool nk_radio_text_align(
struct nk_context *ctx,
const char *text,
int len, nk_bool *active, nk_flags widget_alignment, nk_flags text_alignment);
3025 NK_API nk_bool nk_option_label(
struct nk_context*,
const char*, nk_bool active);
3026 NK_API nk_bool nk_option_label_align(
struct nk_context *ctx,
const char *label, nk_bool active, nk_flags widget_alignment, nk_flags text_alignment);
3027 NK_API nk_bool nk_option_text(
struct nk_context*,
const char*,
int, nk_bool active);
3028 NK_API nk_bool nk_option_text_align(
struct nk_context *ctx,
const char *text,
int len, nk_bool is_active, nk_flags widget_alignment, nk_flags text_alignment);
3034 NK_API nk_bool nk_selectable_label(
struct nk_context*,
const char*, nk_flags align, nk_bool *value);
3035 NK_API nk_bool nk_selectable_text(
struct nk_context*,
const char*,
int, nk_flags align, nk_bool *value);
3036 NK_API nk_bool nk_selectable_image_label(
struct nk_context*,
struct nk_image,
const char*, nk_flags align, nk_bool *value);
3037 NK_API nk_bool nk_selectable_image_text(
struct nk_context*,
struct nk_image,
const char*,
int, nk_flags align, nk_bool *value);
3038 NK_API nk_bool nk_selectable_symbol_label(
struct nk_context*,
enum nk_symbol_type,
const char*, nk_flags align, nk_bool *value);
3039 NK_API nk_bool nk_selectable_symbol_text(
struct nk_context*,
enum nk_symbol_type,
const char*,
int, nk_flags align, nk_bool *value);
3041 NK_API nk_bool nk_select_label(
struct nk_context*,
const char*, nk_flags align, nk_bool value);
3042 NK_API nk_bool nk_select_text(
struct nk_context*,
const char*,
int, nk_flags align, nk_bool value);
3043 NK_API nk_bool nk_select_image_label(
struct nk_context*,
struct nk_image,
const char*, nk_flags align, nk_bool value);
3044 NK_API nk_bool nk_select_image_text(
struct nk_context*,
struct nk_image,
const char*,
int, nk_flags align, nk_bool value);
3045 NK_API nk_bool nk_select_symbol_label(
struct nk_context*,
enum nk_symbol_type,
const char*, nk_flags align, nk_bool value);
3046 NK_API nk_bool nk_select_symbol_text(
struct nk_context*,
enum nk_symbol_type,
const char*,
int, nk_flags align, nk_bool value);
3053 NK_API
float nk_slide_float(
struct nk_context*,
float min,
float val,
float max,
float step);
3054 NK_API
int nk_slide_int(
struct nk_context*,
int min,
int val,
int max,
int step);
3055 NK_API nk_bool nk_slider_float(
struct nk_context*,
float min,
float *val,
float max,
float step);
3056 NK_API nk_bool nk_slider_int(
struct nk_context*,
int min,
int *val,
int max,
int step);
3063 NK_API nk_bool nk_knob_float(
struct nk_context*,
float min,
float *val,
float max,
float step,
enum nk_heading zero_direction,
float dead_zone_degrees);
3064 NK_API nk_bool nk_knob_int(
struct nk_context*,
int min,
int *val,
int max,
int step,
enum nk_heading zero_direction,
float dead_zone_degrees);
3071 NK_API nk_bool nk_progress(
struct nk_context*, nk_size *cur, nk_size max, nk_bool modifyable);
3072 NK_API nk_size nk_prog(
struct nk_context*, nk_size cur, nk_size max, nk_bool modifyable);
3080 NK_API nk_bool nk_color_pick(
struct nk_context*,
struct nk_colorf*,
enum nk_color_format);
3172 NK_API
void nk_property_int(
struct nk_context*,
const char *name,
int min,
int *val,
int max,
int step,
float inc_per_pixel);
3250 NK_API
float nk_propertyf(
struct nk_context*,
const char *name,
float min,
float val,
float max,
float step,
float inc_per_pixel);
3271 NK_API
double nk_propertyd(
struct nk_context*,
const char *name,
double min,
double val,
double max,
double step,
float inc_per_pixel);
3278 enum nk_edit_flags {
3279 NK_EDIT_DEFAULT = 0,
3280 NK_EDIT_READ_ONLY = NK_FLAG(0),
3281 NK_EDIT_AUTO_SELECT = NK_FLAG(1),
3282 NK_EDIT_SIG_ENTER = NK_FLAG(2),
3283 NK_EDIT_ALLOW_TAB = NK_FLAG(3),
3284 NK_EDIT_NO_CURSOR = NK_FLAG(4),
3285 NK_EDIT_SELECTABLE = NK_FLAG(5),
3286 NK_EDIT_CLIPBOARD = NK_FLAG(6),
3287 NK_EDIT_CTRL_ENTER_NEWLINE = NK_FLAG(7),
3288 NK_EDIT_NO_HORIZONTAL_SCROLL = NK_FLAG(8),
3289 NK_EDIT_ALWAYS_INSERT_MODE = NK_FLAG(9),
3290 NK_EDIT_MULTILINE = NK_FLAG(10),
3291 NK_EDIT_GOTO_END_ON_ACTIVATE = NK_FLAG(11)
3293 enum nk_edit_types {
3294 NK_EDIT_SIMPLE = NK_EDIT_ALWAYS_INSERT_MODE,
3295 NK_EDIT_FIELD = NK_EDIT_SIMPLE|NK_EDIT_SELECTABLE|NK_EDIT_CLIPBOARD,
3296 NK_EDIT_BOX = NK_EDIT_ALWAYS_INSERT_MODE| NK_EDIT_SELECTABLE| NK_EDIT_MULTILINE|NK_EDIT_ALLOW_TAB|NK_EDIT_CLIPBOARD,
3297 NK_EDIT_EDITOR = NK_EDIT_SELECTABLE|NK_EDIT_MULTILINE|NK_EDIT_ALLOW_TAB| NK_EDIT_CLIPBOARD
3300 NK_EDIT_ACTIVE = NK_FLAG(0),
3306 NK_API nk_flags nk_edit_string(
struct nk_context*, nk_flags,
char *buffer,
int *len,
int max, nk_plugin_filter);
3307 NK_API nk_flags nk_edit_string_zero_terminated(
struct nk_context*, nk_flags,
char *buffer,
int max, nk_plugin_filter);
3309 NK_API
void nk_edit_focus(
struct nk_context*, nk_flags flags);
3310 NK_API
void nk_edit_unfocus(
struct nk_context*);
3316 NK_API nk_bool nk_chart_begin(
struct nk_context*,
enum nk_chart_type,
int num,
float min,
float max);
3317 NK_API nk_bool nk_chart_begin_colored(
struct nk_context*,
enum nk_chart_type,
struct nk_color,
struct nk_color active,
int num,
float min,
float max);
3318 NK_API
void nk_chart_add_slot(
struct nk_context *ctx,
const enum nk_chart_type,
int count,
float min_value,
float max_value);
3319 NK_API
void nk_chart_add_slot_colored(
struct nk_context *ctx,
const enum nk_chart_type,
struct nk_color,
struct nk_color active,
int count,
float min_value,
float max_value);
3320 NK_API nk_flags nk_chart_push(
struct nk_context*,
float);
3321 NK_API nk_flags nk_chart_push_slot(
struct nk_context*,
float,
int);
3322 NK_API
void nk_chart_end(
struct nk_context*);
3323 NK_API
void nk_plot(
struct nk_context*,
enum nk_chart_type,
const float *values,
int count,
int offset);
3324 NK_API
void nk_plot_function(
struct nk_context*,
enum nk_chart_type,
void *userdata,
float(*value_getter)(
void* user,
int index),
int count,
int offset);
3330 NK_API nk_bool nk_popup_begin(
struct nk_context*,
enum nk_popup_type,
const char*, nk_flags,
struct nk_rect bounds);
3331 NK_API
void nk_popup_close(
struct nk_context*);
3332 NK_API
void nk_popup_end(
struct nk_context*);
3333 NK_API
void nk_popup_get_scroll(
const struct nk_context*, nk_uint *offset_x, nk_uint *offset_y);
3334 NK_API
void nk_popup_set_scroll(
struct nk_context*, nk_uint offset_x, nk_uint offset_y);
3340 NK_API
int nk_combo(
struct nk_context*,
const char *
const *items,
int count,
int selected,
int item_height,
struct nk_vec2 size);
3341 NK_API
int nk_combo_separator(
struct nk_context*,
const char *items_separated_by_separator,
int separator,
int selected,
int count,
int item_height,
struct nk_vec2 size);
3342 NK_API
int nk_combo_string(
struct nk_context*,
const char *items_separated_by_zeros,
int selected,
int count,
int item_height,
struct nk_vec2 size);
3343 NK_API
int nk_combo_callback(
struct nk_context*,
void(*item_getter)(
void*,
int,
const char**),
void *userdata,
int selected,
int count,
int item_height,
struct nk_vec2 size);
3344 NK_API
void nk_combobox(
struct nk_context*,
const char *
const *items,
int count,
int *selected,
int item_height,
struct nk_vec2 size);
3345 NK_API
void nk_combobox_string(
struct nk_context*,
const char *items_separated_by_zeros,
int *selected,
int count,
int item_height,
struct nk_vec2 size);
3346 NK_API
void nk_combobox_separator(
struct nk_context*,
const char *items_separated_by_separator,
int separator,
int *selected,
int count,
int item_height,
struct nk_vec2 size);
3347 NK_API
void nk_combobox_callback(
struct nk_context*,
void(*item_getter)(
void*,
int,
const char**),
void*,
int *selected,
int count,
int item_height,
struct nk_vec2 size);
3353 NK_API nk_bool nk_combo_begin_text(
struct nk_context*,
const char *selected,
int,
struct nk_vec2 size);
3354 NK_API nk_bool nk_combo_begin_label(
struct nk_context*,
const char *selected,
struct nk_vec2 size);
3356 NK_API nk_bool nk_combo_begin_symbol(
struct nk_context*,
enum nk_symbol_type,
struct nk_vec2 size);
3357 NK_API nk_bool nk_combo_begin_symbol_label(
struct nk_context*,
const char *selected,
enum nk_symbol_type,
struct nk_vec2 size);
3358 NK_API nk_bool nk_combo_begin_symbol_text(
struct nk_context*,
const char *selected,
int,
enum nk_symbol_type,
struct nk_vec2 size);
3360 NK_API nk_bool nk_combo_begin_image_label(
struct nk_context*,
const char *selected,
struct nk_image,
struct nk_vec2 size);
3361 NK_API nk_bool nk_combo_begin_image_text(
struct nk_context*,
const char *selected,
int,
struct nk_image,
struct nk_vec2 size);
3362 NK_API nk_bool nk_combo_item_label(
struct nk_context*,
const char*, nk_flags alignment);
3363 NK_API nk_bool nk_combo_item_text(
struct nk_context*,
const char*,
int, nk_flags alignment);
3364 NK_API nk_bool nk_combo_item_image_label(
struct nk_context*,
struct nk_image,
const char*, nk_flags alignment);
3365 NK_API nk_bool nk_combo_item_image_text(
struct nk_context*,
struct nk_image,
const char*,
int,nk_flags alignment);
3366 NK_API nk_bool nk_combo_item_symbol_label(
struct nk_context*,
enum nk_symbol_type,
const char*, nk_flags alignment);
3367 NK_API nk_bool nk_combo_item_symbol_text(
struct nk_context*,
enum nk_symbol_type,
const char*,
int, nk_flags alignment);
3368 NK_API
void nk_combo_close(
struct nk_context*);
3369 NK_API
void nk_combo_end(
struct nk_context*);
3376 NK_API nk_bool nk_contextual_item_text(
struct nk_context*,
const char*,
int,nk_flags align);
3377 NK_API nk_bool nk_contextual_item_label(
struct nk_context*,
const char*, nk_flags align);
3378 NK_API nk_bool nk_contextual_item_image_label(
struct nk_context*,
struct nk_image,
const char*, nk_flags alignment);
3379 NK_API nk_bool nk_contextual_item_image_text(
struct nk_context*,
struct nk_image,
const char*,
int len, nk_flags alignment);
3380 NK_API nk_bool nk_contextual_item_symbol_label(
struct nk_context*,
enum nk_symbol_type,
const char*, nk_flags alignment);
3381 NK_API nk_bool nk_contextual_item_symbol_text(
struct nk_context*,
enum nk_symbol_type,
const char*,
int, nk_flags alignment);
3382 NK_API
void nk_contextual_close(
struct nk_context*);
3383 NK_API
void nk_contextual_end(
struct nk_context*);
3389 NK_API
void nk_tooltip(
struct nk_context*,
const char*);
3390 #ifdef NK_INCLUDE_STANDARD_VARARGS
3391 NK_API
void nk_tooltipf(
struct nk_context*, NK_PRINTF_FORMAT_STRING
const char*, ...) NK_PRINTF_VARARG_FUNC(2);
3392 NK_API
void nk_tooltipfv(struct
nk_context*, NK_PRINTF_FORMAT_STRING const
char*, va_list) NK_PRINTF_VALIST_FUNC(2);
3394 NK_API nk_bool nk_tooltip_begin(
struct nk_context*,
float width);
3395 NK_API
void nk_tooltip_end(
struct nk_context*);
3401 NK_API
void nk_menubar_begin(
struct nk_context*);
3402 NK_API
void nk_menubar_end(
struct nk_context*);
3403 NK_API nk_bool nk_menu_begin_text(
struct nk_context*,
const char* title,
int title_len, nk_flags align,
struct nk_vec2 size);
3404 NK_API nk_bool nk_menu_begin_label(
struct nk_context*,
const char*, nk_flags align,
struct nk_vec2 size);
3406 NK_API nk_bool nk_menu_begin_image_text(
struct nk_context*,
const char*,
int,nk_flags align,
struct nk_image,
struct nk_vec2 size);
3407 NK_API nk_bool nk_menu_begin_image_label(
struct nk_context*,
const char*, nk_flags align,
struct nk_image,
struct nk_vec2 size);
3408 NK_API nk_bool nk_menu_begin_symbol(
struct nk_context*,
const char*,
enum nk_symbol_type,
struct nk_vec2 size);
3409 NK_API nk_bool nk_menu_begin_symbol_text(
struct nk_context*,
const char*,
int,nk_flags align,
enum nk_symbol_type,
struct nk_vec2 size);
3410 NK_API nk_bool nk_menu_begin_symbol_label(
struct nk_context*,
const char*, nk_flags align,
enum nk_symbol_type,
struct nk_vec2 size);
3411 NK_API nk_bool nk_menu_item_text(
struct nk_context*,
const char*,
int,nk_flags align);
3412 NK_API nk_bool nk_menu_item_label(
struct nk_context*,
const char*, nk_flags alignment);
3413 NK_API nk_bool nk_menu_item_image_label(
struct nk_context*,
struct nk_image,
const char*, nk_flags alignment);
3414 NK_API nk_bool nk_menu_item_image_text(
struct nk_context*,
struct nk_image,
const char*,
int len, nk_flags alignment);
3415 NK_API nk_bool nk_menu_item_symbol_text(
struct nk_context*,
enum nk_symbol_type,
const char*,
int, nk_flags alignment);
3416 NK_API nk_bool nk_menu_item_symbol_label(
struct nk_context*,
enum nk_symbol_type,
const char*, nk_flags alignment);
3417 NK_API
void nk_menu_close(
struct nk_context*);
3425 #define NK_WIDGET_DISABLED_FACTOR 0.5f
3427 enum nk_style_colors {
3433 NK_COLOR_BUTTON_HOVER,
3434 NK_COLOR_BUTTON_ACTIVE,
3436 NK_COLOR_TOGGLE_HOVER,
3437 NK_COLOR_TOGGLE_CURSOR,
3439 NK_COLOR_SELECT_ACTIVE,
3441 NK_COLOR_SLIDER_CURSOR,
3442 NK_COLOR_SLIDER_CURSOR_HOVER,
3443 NK_COLOR_SLIDER_CURSOR_ACTIVE,
3446 NK_COLOR_EDIT_CURSOR,
3449 NK_COLOR_CHART_COLOR,
3450 NK_COLOR_CHART_COLOR_HIGHLIGHT,
3452 NK_COLOR_SCROLLBAR_CURSOR,
3453 NK_COLOR_SCROLLBAR_CURSOR_HOVER,
3454 NK_COLOR_SCROLLBAR_CURSOR_ACTIVE,
3455 NK_COLOR_TAB_HEADER,
3457 NK_COLOR_KNOB_CURSOR,
3458 NK_COLOR_KNOB_CURSOR_HOVER,
3459 NK_COLOR_KNOB_CURSOR_ACTIVE,
3462 enum nk_style_cursor {
3466 NK_CURSOR_RESIZE_VERTICAL,
3467 NK_CURSOR_RESIZE_HORIZONTAL,
3468 NK_CURSOR_RESIZE_TOP_LEFT_DOWN_RIGHT,
3469 NK_CURSOR_RESIZE_TOP_RIGHT_DOWN_LEFT,
3472 NK_API
void nk_style_default(
struct nk_context*);
3474 NK_API
void nk_style_load_cursor(
struct nk_context*,
enum nk_style_cursor,
const struct nk_cursor*);
3476 NK_API
const char* nk_style_get_color_by_name(
enum nk_style_colors);
3478 NK_API nk_bool nk_style_set_cursor(
struct nk_context*,
enum nk_style_cursor);
3479 NK_API
void nk_style_show_cursor(
struct nk_context*);
3480 NK_API
void nk_style_hide_cursor(
struct nk_context*);
3483 NK_API nk_bool nk_style_push_float(
struct nk_context*,
float*,
float);
3486 NK_API nk_bool nk_style_push_flags(
struct nk_context*, nk_flags*, nk_flags);
3489 NK_API nk_bool nk_style_pop_font(
struct nk_context*);
3490 NK_API nk_bool nk_style_pop_float(
struct nk_context*);
3491 NK_API nk_bool nk_style_pop_vec2(
struct nk_context*);
3492 NK_API nk_bool nk_style_pop_style_item(
struct nk_context*);
3493 NK_API nk_bool nk_style_pop_flags(
struct nk_context*);
3494 NK_API nk_bool nk_style_pop_color(
struct nk_context*);
3500 NK_API
struct nk_color nk_rgb(int r, int g, int b);
3501 NK_API
struct nk_color nk_rgb_iv(const int *rgb);
3502 NK_API
struct nk_color nk_rgb_bv(const nk_byte* rgb);
3503 NK_API
struct nk_color nk_rgb_f(float r, float g, float b);
3504 NK_API
struct nk_color nk_rgb_fv(const float *rgb);
3506 NK_API
struct nk_color nk_rgb_hex(const char *rgb);
3509 NK_API
struct nk_color nk_rgba(int r, int g, int b, int a);
3510 NK_API
struct nk_color nk_rgba_u32(nk_uint);
3511 NK_API
struct nk_color nk_rgba_iv(const int *rgba);
3512 NK_API
struct nk_color nk_rgba_bv(const nk_byte *rgba);
3513 NK_API
struct nk_color nk_rgba_f(float r, float g, float b, float a);
3514 NK_API
struct nk_color nk_rgba_fv(const float *rgba);
3516 NK_API
struct nk_color nk_rgba_hex(const char *rgb);
3518 NK_API
struct nk_colorf nk_hsva_colorf(float h, float s, float v, float a);
3519 NK_API
struct nk_colorf nk_hsva_colorfv(const float *c);
3520 NK_API
void nk_colorf_hsva_f(
float *out_h,
float *out_s,
float *out_v,
float *out_a,
struct nk_colorf in);
3521 NK_API
void nk_colorf_hsva_fv(
float *hsva,
struct nk_colorf in);
3523 NK_API
struct nk_color nk_hsv(int h, int s, int v);
3524 NK_API
struct nk_color nk_hsv_iv(const int *hsv);
3525 NK_API
struct nk_color nk_hsv_bv(const nk_byte *hsv);
3526 NK_API
struct nk_color nk_hsv_f(float h, float s, float v);
3527 NK_API
struct nk_color nk_hsv_fv(const float *hsv);
3529 NK_API
struct nk_color nk_hsva(int h, int s, int v, int a);
3530 NK_API
struct nk_color nk_hsva_iv(const int *hsva);
3531 NK_API
struct nk_color nk_hsva_bv(const nk_byte *hsva);
3532 NK_API
struct nk_color nk_hsva_f(float h, float s, float v, float a);
3533 NK_API
struct nk_color nk_hsva_fv(const float *hsva);
3536 NK_API
void nk_color_f(
float *r,
float *g,
float *b,
float *a,
struct nk_color);
3537 NK_API
void nk_color_fv(
float *rgba_out,
struct nk_color);
3539 NK_API
void nk_color_d(
double *r,
double *g,
double *b,
double *a,
struct nk_color);
3540 NK_API
void nk_color_dv(
double *rgba_out,
struct nk_color);
3542 NK_API nk_uint nk_color_u32(
struct nk_color);
3543 NK_API
void nk_color_hex_rgba(
char *output,
struct nk_color);
3544 NK_API
void nk_color_hex_rgb(
char *output,
struct nk_color);
3546 NK_API
void nk_color_hsv_i(
int *out_h,
int *out_s,
int *out_v,
struct nk_color);
3547 NK_API
void nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v,
struct nk_color);
3548 NK_API
void nk_color_hsv_iv(
int *hsv_out,
struct nk_color);
3549 NK_API
void nk_color_hsv_bv(nk_byte *hsv_out,
struct nk_color);
3550 NK_API
void nk_color_hsv_f(
float *out_h,
float *out_s,
float *out_v,
struct nk_color);
3551 NK_API
void nk_color_hsv_fv(
float *hsv_out,
struct nk_color);
3553 NK_API
void nk_color_hsva_i(
int *h,
int *s,
int *v,
int *a,
struct nk_color);
3554 NK_API
void nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a,
struct nk_color);
3555 NK_API
void nk_color_hsva_iv(
int *hsva_out,
struct nk_color);
3556 NK_API
void nk_color_hsva_bv(nk_byte *hsva_out,
struct nk_color);
3557 NK_API
void nk_color_hsva_f(
float *out_h,
float *out_s,
float *out_v,
float *out_a,
struct nk_color);
3558 NK_API
void nk_color_hsva_fv(
float *hsva_out,
struct nk_color);
3567 NK_API
struct nk_image nk_image_ptr(void*);
3568 NK_API
struct nk_image nk_image_id(int);
3569 NK_API nk_bool nk_image_is_subimage(
const struct nk_image* img);
3570 NK_API
struct nk_image nk_subimage_ptr(void*, nk_ushort w, nk_ushort h,
struct nk_rect sub_region);
3571 NK_API
struct nk_image nk_subimage_id(int, nk_ushort w, nk_ushort h, struct
nk_rect sub_region);
3578 NK_API
struct nk_nine_slice nk_nine_slice_handle(
nk_handle, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b);
3579 NK_API
struct nk_nine_slice nk_nine_slice_ptr(void*, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b);
3580 NK_API
struct nk_nine_slice nk_nine_slice_id(int, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b);
3581 NK_API
int nk_nine_slice_is_sub9slice(
const struct nk_nine_slice* img);
3582 NK_API
struct nk_nine_slice nk_sub9slice_ptr(void*, nk_ushort w, nk_ushort h,
struct nk_rect sub_region, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b);
3583 NK_API
struct nk_nine_slice nk_sub9slice_id(int, nk_ushort w, nk_ushort h, struct
nk_rect sub_region, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b);
3584 NK_API
struct nk_nine_slice nk_sub9slice_handle(
nk_handle, nk_ushort w, nk_ushort h, struct
nk_rect sub_region, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b);
3590 NK_API nk_hash nk_murmur_hash(
const void *key,
int len, nk_hash seed);
3591 NK_API
void nk_triangle_from_direction(
struct nk_vec2 *result,
struct nk_rect r,
float pad_x,
float pad_y,
enum nk_heading);
3595 NK_API
struct nk_vec2 nk_vec2v(const float *xy);
3596 NK_API
struct nk_vec2 nk_vec2iv(const int *xy);
3598 NK_API
struct nk_rect nk_get_null_rect(void);
3599 NK_API
struct nk_rect nk_rect(float x, float y, float w, float h);
3602 NK_API
struct nk_rect nk_rectv(const float *xywh);
3603 NK_API
struct nk_rect nk_rectiv(const int *xywh);
3611 NK_API
int nk_strlen(
const char *str);
3612 NK_API
int nk_stricmp(
const char *s1,
const char *s2);
3613 NK_API
int nk_stricmpn(
const char *s1,
const char *s2,
int n);
3614 NK_API
int nk_strtoi(
const char *str,
char **endptr);
3615 NK_API
float nk_strtof(
const char *str,
char **endptr);
3617 #define NK_STRTOD nk_strtod
3618 NK_API
double nk_strtod(
const char *str,
char **endptr);
3620 NK_API
int nk_strfilter(
const char *text,
const char *regexp);
3621 NK_API
int nk_strmatch_fuzzy_string(
char const *str,
char const *pattern,
int *out_score);
3622 NK_API
int nk_strmatch_fuzzy_text(
const char *txt,
int txt_len,
const char *pattern,
int *out_score);
3628 NK_API
int nk_utf_decode(
const char*, nk_rune*,
int);
3629 NK_API
int nk_utf_encode(nk_rune,
char*,
int);
3630 NK_API
int nk_utf_len(
const char*,
int byte_len);
3631 NK_API
const char* nk_utf_at(
const char *buffer,
int length,
int index, nk_rune *unicode,
int *len);
3789 struct nk_user_font_glyph;
3790 typedef float(*nk_text_width_f)(
nk_handle,
float h,
const char*,
int len);
3791 typedef void(*nk_query_font_glyph_f)(
nk_handle handle,
float font_height,
3792 struct nk_user_font_glyph *glyph,
3793 nk_rune codepoint, nk_rune next_codepoint);
3795 #if defined(NK_INCLUDE_VERTEX_BUFFER_OUTPUT) || defined(NK_INCLUDE_SOFTWARE_FONT)
3796 struct nk_user_font_glyph {
3799 float width, height;
3808 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
3809 nk_query_font_glyph_f query;
3814 #ifdef NK_INCLUDE_FONT_BAKING
3815 enum nk_font_coord_type {
3821 struct nk_baked_font {
3825 nk_rune glyph_offset;
3826 nk_rune glyph_count;
3827 const nk_rune *ranges;
3830 struct nk_font_config {
3831 struct nk_font_config *next;
3835 unsigned char ttf_data_owned_by_atlas;
3836 unsigned char merge_mode;
3837 unsigned char pixel_snap;
3838 unsigned char oversample_v, oversample_h;
3839 unsigned char padding[3];
3842 enum nk_font_coord_type coord_type;
3844 const nk_rune *range;
3845 struct nk_baked_font *font;
3846 nk_rune fallback_glyph;
3847 struct nk_font_config *n;
3848 struct nk_font_config *p;
3851 struct nk_font_glyph {
3854 float x0, y0, x1, y1, w, h;
3855 float u0, v0, u1, v1;
3859 struct nk_font *next;
3861 struct nk_baked_font info;
3863 struct nk_font_glyph *glyphs;
3864 const struct nk_font_glyph *fallback;
3865 nk_rune fallback_codepoint;
3867 struct nk_font_config *config;
3870 enum nk_font_atlas_format {
3871 NK_FONT_ATLAS_ALPHA8,
3872 NK_FONT_ATLAS_RGBA32
3875 struct nk_font_atlas {
3884 struct nk_cursor cursors[NK_CURSOR_COUNT];
3887 struct nk_font_glyph *glyphs;
3888 struct nk_font *default_font;
3889 struct nk_font *fonts;
3890 struct nk_font_config *config;
3895 NK_API
const nk_rune *nk_font_default_glyph_ranges(
void);
3896 NK_API
const nk_rune *nk_font_chinese_glyph_ranges(
void);
3897 NK_API
const nk_rune *nk_font_cyrillic_glyph_ranges(
void);
3898 NK_API
const nk_rune *nk_font_korean_glyph_ranges(
void);
3900 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
3901 NK_API
void nk_font_atlas_init_default(
struct nk_font_atlas*);
3903 NK_API
void nk_font_atlas_init(
struct nk_font_atlas*,
const struct nk_allocator*);
3904 NK_API
void nk_font_atlas_init_custom(
struct nk_font_atlas*,
const struct nk_allocator *persistent,
const struct nk_allocator *
transient);
3905 NK_API
void nk_font_atlas_begin(
struct nk_font_atlas*);
3906 NK_API
struct nk_font_config nk_font_config(float pixel_height);
3907 NK_API
struct nk_font *nk_font_atlas_add(
struct nk_font_atlas*,
const struct nk_font_config*);
3908 #ifdef NK_INCLUDE_DEFAULT_FONT
3909 NK_API
struct nk_font* nk_font_atlas_add_default(
struct nk_font_atlas*,
float height,
const struct nk_font_config*);
3911 NK_API
struct nk_font* nk_font_atlas_add_from_memory(
struct nk_font_atlas *atlas,
void *memory, nk_size size,
float height,
const struct nk_font_config *config);
3912 #ifdef NK_INCLUDE_STANDARD_IO
3913 NK_API
struct nk_font* nk_font_atlas_add_from_file(
struct nk_font_atlas *atlas,
const char *file_path,
float height,
const struct nk_font_config*);
3915 NK_API
struct nk_font *nk_font_atlas_add_compressed(
struct nk_font_atlas*,
void *memory, nk_size size,
float height,
const struct nk_font_config*);
3916 NK_API
struct nk_font* nk_font_atlas_add_compressed_base85(
struct nk_font_atlas*,
const char *data,
float height,
const struct nk_font_config *config);
3917 NK_API
const void* nk_font_atlas_bake(
struct nk_font_atlas*,
int *width,
int *height,
enum nk_font_atlas_format);
3919 NK_API
const struct nk_font_glyph* nk_font_find_glyph(
const struct nk_font*, nk_rune unicode);
3920 NK_API
void nk_font_atlas_cleanup(
struct nk_font_atlas *atlas);
3921 NK_API
void nk_font_atlas_clear(
struct nk_font_atlas*);
3970 enum nk_allocation_type {
3975 enum nk_buffer_allocation_type {
3990 enum nk_allocation_type
type;
3999 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4000 NK_API
void nk_buffer_init_default(
struct nk_buffer*);
4003 NK_API
void nk_buffer_init_fixed(
struct nk_buffer*,
void *memory, nk_size size);
4005 NK_API
void nk_buffer_push(
struct nk_buffer*,
enum nk_buffer_allocation_type type,
const void *memory, nk_size size, nk_size align);
4006 NK_API
void nk_buffer_mark(
struct nk_buffer*,
enum nk_buffer_allocation_type type);
4007 NK_API
void nk_buffer_reset(
struct nk_buffer*,
enum nk_buffer_allocation_type type);
4008 NK_API
void nk_buffer_clear(
struct nk_buffer*);
4009 NK_API
void nk_buffer_free(
struct nk_buffer*);
4010 NK_API
void *nk_buffer_memory(
struct nk_buffer*);
4011 NK_API
const void *nk_buffer_memory_const(
const struct nk_buffer*);
4012 NK_API nk_size nk_buffer_total(
const struct nk_buffer*);
4029 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4030 NK_API
void nk_str_init_default(
struct nk_str*);
4034 NK_API
void nk_str_clear(
struct nk_str*);
4035 NK_API
void nk_str_free(
struct nk_str*);
4037 NK_API
int nk_str_append_text_char(
struct nk_str*,
const char*,
int);
4038 NK_API
int nk_str_append_str_char(
struct nk_str*,
const char*);
4039 NK_API
int nk_str_append_text_utf8(
struct nk_str*,
const char*,
int);
4040 NK_API
int nk_str_append_str_utf8(
struct nk_str*,
const char*);
4041 NK_API
int nk_str_append_text_runes(
struct nk_str*,
const nk_rune*,
int);
4042 NK_API
int nk_str_append_str_runes(
struct nk_str*,
const nk_rune*);
4044 NK_API
int nk_str_insert_at_char(
struct nk_str*,
int pos,
const char*,
int);
4045 NK_API
int nk_str_insert_at_rune(
struct nk_str*,
int pos,
const char*,
int);
4047 NK_API
int nk_str_insert_text_char(
struct nk_str*,
int pos,
const char*,
int);
4048 NK_API
int nk_str_insert_str_char(
struct nk_str*,
int pos,
const char*);
4049 NK_API
int nk_str_insert_text_utf8(
struct nk_str*,
int pos,
const char*,
int);
4050 NK_API
int nk_str_insert_str_utf8(
struct nk_str*,
int pos,
const char*);
4051 NK_API
int nk_str_insert_text_runes(
struct nk_str*,
int pos,
const nk_rune*,
int);
4052 NK_API
int nk_str_insert_str_runes(
struct nk_str*,
int pos,
const nk_rune*);
4054 NK_API
void nk_str_remove_chars(
struct nk_str*,
int len);
4055 NK_API
void nk_str_remove_runes(
struct nk_str *str,
int len);
4056 NK_API
void nk_str_delete_chars(
struct nk_str*,
int pos,
int len);
4057 NK_API
void nk_str_delete_runes(
struct nk_str*,
int pos,
int len);
4059 NK_API
char *nk_str_at_char(
struct nk_str*,
int pos);
4060 NK_API
char *nk_str_at_rune(
struct nk_str*,
int pos, nk_rune *unicode,
int *len);
4061 NK_API nk_rune nk_str_rune_at(
const struct nk_str*,
int pos);
4062 NK_API
const char *nk_str_at_char_const(
const struct nk_str*,
int pos);
4063 NK_API
const char *nk_str_at_const(
const struct nk_str*,
int pos, nk_rune *unicode,
int *len);
4065 NK_API
char *nk_str_get(
struct nk_str*);
4066 NK_API
const char *nk_str_get_const(
const struct nk_str*);
4067 NK_API
int nk_str_len(
const struct nk_str*);
4068 NK_API
int nk_str_len_char(
const struct nk_str*);
4101 #ifndef NK_TEXTEDIT_UNDOSTATECOUNT
4102 #define NK_TEXTEDIT_UNDOSTATECOUNT 99
4105 #ifndef NK_TEXTEDIT_UNDOCHARCOUNT
4106 #define NK_TEXTEDIT_UNDOCHARCOUNT 999
4112 nk_plugin_paste paste;
4113 nk_plugin_copy copy;
4118 short insert_length;
4119 short delete_length;
4125 nk_rune undo_char[NK_TEXTEDIT_UNDOCHARCOUNT];
4128 short undo_char_point;
4129 short redo_char_point;
4132 enum nk_text_edit_type {
4133 NK_TEXT_EDIT_SINGLE_LINE,
4134 NK_TEXT_EDIT_MULTI_LINE
4137 enum nk_text_edit_mode {
4138 NK_TEXT_EDIT_MODE_VIEW,
4139 NK_TEXT_EDIT_MODE_INSERT,
4140 NK_TEXT_EDIT_MODE_REPLACE
4146 nk_plugin_filter filter;
4153 unsigned char cursor_at_end_of_line;
4154 unsigned char initialized;
4155 unsigned char has_preferred_x;
4156 unsigned char single_line;
4157 unsigned char active;
4158 unsigned char padding1;
4165 NK_API nk_bool nk_filter_ascii(
const struct nk_text_edit*, nk_rune unicode);
4166 NK_API nk_bool nk_filter_float(
const struct nk_text_edit*, nk_rune unicode);
4167 NK_API nk_bool nk_filter_decimal(
const struct nk_text_edit*, nk_rune unicode);
4168 NK_API nk_bool nk_filter_hex(
const struct nk_text_edit*, nk_rune unicode);
4169 NK_API nk_bool nk_filter_oct(
const struct nk_text_edit*, nk_rune unicode);
4170 NK_API nk_bool nk_filter_binary(
const struct nk_text_edit*, nk_rune unicode);
4173 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4174 NK_API
void nk_textedit_init_default(
struct nk_text_edit*);
4177 NK_API
void nk_textedit_init_fixed(
struct nk_text_edit*,
void *memory, nk_size size);
4179 NK_API
void nk_textedit_text(
struct nk_text_edit*,
const char*,
int total_len);
4180 NK_API
void nk_textedit_delete(
struct nk_text_edit*,
int where,
int len);
4181 NK_API
void nk_textedit_delete_selection(
struct nk_text_edit*);
4182 NK_API
void nk_textedit_select_all(
struct nk_text_edit*);
4184 NK_API nk_bool nk_textedit_paste(
struct nk_text_edit*,
char const*,
int len);
4242 enum nk_command_type {
4248 NK_COMMAND_RECT_FILLED,
4249 NK_COMMAND_RECT_MULTI_COLOR,
4251 NK_COMMAND_CIRCLE_FILLED,
4253 NK_COMMAND_ARC_FILLED,
4254 NK_COMMAND_TRIANGLE,
4255 NK_COMMAND_TRIANGLE_FILLED,
4257 NK_COMMAND_POLYGON_FILLED,
4258 NK_COMMAND_POLYLINE,
4266 enum nk_command_type type;
4268 #ifdef NK_INCLUDE_COMMAND_USERDATA
4276 unsigned short w, h;
4281 unsigned short line_thickness;
4289 unsigned short line_thickness;
4298 unsigned short rounding;
4299 unsigned short line_thickness;
4301 unsigned short w, h;
4307 unsigned short rounding;
4309 unsigned short w, h;
4316 unsigned short w, h;
4325 unsigned short line_thickness;
4343 unsigned short line_thickness;
4344 unsigned short w, h;
4351 unsigned short w, h;
4359 unsigned short line_thickness;
4375 unsigned short line_thickness;
4376 unsigned short point_count;
4383 unsigned short point_count;
4390 unsigned short line_thickness;
4391 unsigned short point_count;
4398 unsigned short w, h;
4403 typedef void (*nk_command_custom_callback)(
void *canvas,
short x,
short y,
4404 unsigned short w,
unsigned short h,
nk_handle callback_data);
4408 unsigned short w, h;
4410 nk_command_custom_callback callback;
4419 unsigned short w, h;
4425 enum nk_command_clipping {
4426 NK_CLIPPING_OFF = nk_false,
4427 NK_CLIPPING_ON = nk_true
4435 nk_size begin, end, last;
4440 NK_API
void nk_stroke_curve(
struct nk_command_buffer*,
float,
float,
float,
float,
float,
float,
float,
float,
float line_thickness,
struct nk_color);
4443 NK_API
void nk_stroke_arc(
struct nk_command_buffer*,
float cx,
float cy,
float radius,
float a_min,
float a_max,
float line_thickness,
struct nk_color);
4444 NK_API
void nk_stroke_triangle(
struct nk_command_buffer*,
float,
float,
float,
float,
float,
float,
float line_thichness,
struct nk_color);
4445 NK_API
void nk_stroke_polyline(
struct nk_command_buffer*,
const float *points,
int point_count,
float line_thickness,
struct nk_color col);
4446 NK_API
void nk_stroke_polygon(
struct nk_command_buffer*,
const float *points,
int point_count,
float line_thickness,
struct nk_color);
4452 NK_API
void nk_fill_arc(
struct nk_command_buffer*,
float cx,
float cy,
float radius,
float a_min,
float a_max,
struct nk_color);
4453 NK_API
void nk_fill_triangle(
struct nk_command_buffer*,
float x0,
float y0,
float x1,
float y1,
float x2,
float y2,
struct nk_color);
4470 unsigned int clicked;
4476 #ifdef NK_BUTTON_TRIGGER_ON_RELEASE
4483 unsigned char grabbed;
4484 unsigned char ungrab;
4489 unsigned int clicked;
4492 struct nk_key keys[NK_KEY_MAX];
4493 char text[NK_INPUT_MAX];
4502 NK_API nk_bool nk_input_has_mouse_click(
const struct nk_input*,
enum nk_buttons);
4503 NK_API nk_bool nk_input_has_mouse_click_in_rect(
const struct nk_input*,
enum nk_buttons,
struct nk_rect);
4504 NK_API nk_bool nk_input_has_mouse_click_in_button_rect(
const struct nk_input*,
enum nk_buttons,
struct nk_rect);
4505 NK_API nk_bool nk_input_has_mouse_click_down_in_rect(
const struct nk_input*,
enum nk_buttons,
struct nk_rect, nk_bool down);
4506 NK_API nk_bool nk_input_is_mouse_click_in_rect(
const struct nk_input*,
enum nk_buttons,
struct nk_rect);
4507 NK_API nk_bool nk_input_is_mouse_click_down_in_rect(
const struct nk_input *i,
enum nk_buttons
id,
struct nk_rect b, nk_bool down);
4508 NK_API nk_bool nk_input_any_mouse_click_in_rect(
const struct nk_input*,
struct nk_rect);
4509 NK_API nk_bool nk_input_is_mouse_prev_hovering_rect(
const struct nk_input*,
struct nk_rect);
4510 NK_API nk_bool nk_input_is_mouse_hovering_rect(
const struct nk_input*,
struct nk_rect);
4511 NK_API nk_bool nk_input_mouse_clicked(
const struct nk_input*,
enum nk_buttons,
struct nk_rect);
4512 NK_API nk_bool nk_input_is_mouse_down(
const struct nk_input*,
enum nk_buttons);
4513 NK_API nk_bool nk_input_is_mouse_pressed(
const struct nk_input*,
enum nk_buttons);
4514 NK_API nk_bool nk_input_is_mouse_released(
const struct nk_input*,
enum nk_buttons);
4515 NK_API nk_bool nk_input_is_key_pressed(
const struct nk_input*,
enum nk_keys);
4516 NK_API nk_bool nk_input_is_key_released(
const struct nk_input*,
enum nk_keys);
4517 NK_API nk_bool nk_input_is_key_down(
const struct nk_input*,
enum nk_keys);
4524 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
4541 #ifdef NK_UINT_DRAW_INDEX
4542 typedef nk_uint nk_draw_index;
4544 typedef nk_ushort nk_draw_index;
4546 enum nk_draw_list_stroke {
4547 NK_STROKE_OPEN = nk_false,
4548 NK_STROKE_CLOSED = nk_true
4551 enum nk_draw_vertex_layout_attribute {
4555 NK_VERTEX_ATTRIBUTE_COUNT
4558 enum nk_draw_vertex_layout_format {
4568 NK_FORMAT_COLOR_BEGIN,
4569 NK_FORMAT_R8G8B8 = NK_FORMAT_COLOR_BEGIN,
4570 NK_FORMAT_R16G15B16,
4571 NK_FORMAT_R32G32B32,
4575 NK_FORMAT_R16G15B16A16,
4576 NK_FORMAT_R32G32B32A32,
4577 NK_FORMAT_R32G32B32A32_FLOAT,
4578 NK_FORMAT_R32G32B32A32_DOUBLE,
4582 NK_FORMAT_COLOR_END = NK_FORMAT_RGBA32,
4586 #define NK_VERTEX_LAYOUT_END NK_VERTEX_ATTRIBUTE_COUNT,NK_FORMAT_COUNT,0
4587 struct nk_draw_vertex_layout_element {
4588 enum nk_draw_vertex_layout_attribute attribute;
4589 enum nk_draw_vertex_layout_format format;
4593 struct nk_draw_command {
4594 unsigned int elem_count;
4597 #ifdef NK_INCLUDE_COMMAND_USERDATA
4602 struct nk_draw_list {
4604 struct nk_vec2 circle_vtx[12];
4611 unsigned int element_count;
4612 unsigned int vertex_count;
4613 unsigned int cmd_count;
4616 unsigned int path_count;
4617 unsigned int path_offset;
4619 enum nk_anti_aliasing line_AA;
4620 enum nk_anti_aliasing shape_AA;
4622 #ifdef NK_INCLUDE_COMMAND_USERDATA
4628 NK_API
void nk_draw_list_init(
struct nk_draw_list*);
4629 NK_API
void nk_draw_list_setup(
struct nk_draw_list*,
const struct nk_convert_config*,
struct nk_buffer *cmds,
struct nk_buffer *vertices,
struct nk_buffer *elements,
enum nk_anti_aliasing line_aa,
enum nk_anti_aliasing shape_aa);
4632 #define nk_draw_list_foreach(cmd, can, b) for((cmd)=nk__draw_list_begin(can, b); (cmd)!=0; (cmd)=nk__draw_list_next(cmd, b, can))
4633 NK_API
const struct nk_draw_command* nk__draw_list_begin(
const struct nk_draw_list*,
const struct nk_buffer*);
4634 NK_API
const struct nk_draw_command* nk__draw_list_next(
const struct nk_draw_command*,
const struct nk_buffer*,
const struct nk_draw_list*);
4635 NK_API
const struct nk_draw_command* nk__draw_list_end(
const struct nk_draw_list*,
const struct nk_buffer*);
4638 NK_API
void nk_draw_list_path_clear(
struct nk_draw_list*);
4639 NK_API
void nk_draw_list_path_line_to(
struct nk_draw_list*,
struct nk_vec2 pos);
4640 NK_API
void nk_draw_list_path_arc_to_fast(
struct nk_draw_list*,
struct nk_vec2 center,
float radius,
int a_min,
int a_max);
4641 NK_API
void nk_draw_list_path_arc_to(
struct nk_draw_list*,
struct nk_vec2 center,
float radius,
float a_min,
float a_max,
unsigned int segments);
4642 NK_API
void nk_draw_list_path_rect_to(
struct nk_draw_list*,
struct nk_vec2 a,
struct nk_vec2 b,
float rounding);
4643 NK_API
void nk_draw_list_path_curve_to(
struct nk_draw_list*,
struct nk_vec2 p2,
struct nk_vec2 p3,
struct nk_vec2 p4,
unsigned int num_segments);
4644 NK_API
void nk_draw_list_path_fill(
struct nk_draw_list*,
struct nk_color);
4645 NK_API
void nk_draw_list_path_stroke(
struct nk_draw_list*,
struct nk_color,
enum nk_draw_list_stroke closed,
float thickness);
4648 NK_API
void nk_draw_list_stroke_line(
struct nk_draw_list*,
struct nk_vec2 a,
struct nk_vec2 b,
struct nk_color,
float thickness);
4649 NK_API
void nk_draw_list_stroke_rect(
struct nk_draw_list*,
struct nk_rect rect,
struct nk_color,
float rounding,
float thickness);
4650 NK_API
void nk_draw_list_stroke_triangle(
struct nk_draw_list*,
struct nk_vec2 a,
struct nk_vec2 b,
struct nk_vec2 c,
struct nk_color,
float thickness);
4651 NK_API
void nk_draw_list_stroke_circle(
struct nk_draw_list*,
struct nk_vec2 center,
float radius,
struct nk_color,
unsigned int segs,
float thickness);
4652 NK_API
void nk_draw_list_stroke_curve(
struct nk_draw_list*,
struct nk_vec2 p0,
struct nk_vec2 cp0,
struct nk_vec2 cp1,
struct nk_vec2 p1,
struct nk_color,
unsigned int segments,
float thickness);
4653 NK_API
void nk_draw_list_stroke_poly_line(
struct nk_draw_list*,
const struct nk_vec2 *pnts,
const unsigned int cnt,
struct nk_color,
enum nk_draw_list_stroke,
float thickness,
enum nk_anti_aliasing);
4656 NK_API
void nk_draw_list_fill_rect(
struct nk_draw_list*,
struct nk_rect rect,
struct nk_color,
float rounding);
4659 NK_API
void nk_draw_list_fill_circle(
struct nk_draw_list*,
struct nk_vec2 center,
float radius,
struct nk_color col,
unsigned int segs);
4660 NK_API
void nk_draw_list_fill_poly_convex(
struct nk_draw_list*,
const struct nk_vec2 *points,
const unsigned int count,
struct nk_color,
enum nk_anti_aliasing);
4663 NK_API
void nk_draw_list_add_image(
struct nk_draw_list*,
struct nk_image texture,
struct nk_rect rect,
struct nk_color);
4664 NK_API
void nk_draw_list_add_text(
struct nk_draw_list*,
const struct nk_user_font*,
struct nk_rect,
const char *text,
int len,
float font_height,
struct nk_color);
4665 #ifdef NK_INCLUDE_COMMAND_USERDATA
4666 NK_API
void nk_draw_list_push_userdata(
struct nk_draw_list*,
nk_handle userdata);
4676 enum nk_style_item_type {
4677 NK_STYLE_ITEM_COLOR,
4678 NK_STYLE_ITEM_IMAGE,
4679 NK_STYLE_ITEM_NINE_SLICE
4689 enum nk_style_item_type type;
4697 float disabled_factor;
4706 float color_factor_background;
4713 nk_flags text_alignment;
4714 float color_factor_text;
4722 float disabled_factor;
4746 nk_flags text_alignment;
4754 float disabled_factor;
4779 struct nk_color text_normal_active;
4781 struct nk_color text_pressed_active;
4783 nk_flags text_alignment;
4791 float disabled_factor;
4825 float disabled_factor;
4831 enum nk_symbol_type inc_symbol;
4832 enum nk_symbol_type dec_symbol;
4865 float disabled_factor;
4884 struct nk_color cursor_border_color;
4889 float cursor_border;
4890 float cursor_rounding;
4893 float disabled_factor;
4912 struct nk_color cursor_border_color;
4917 float border_cursor;
4918 float rounding_cursor;
4921 float disabled_factor;
4927 enum nk_symbol_type inc_symbol;
4928 enum nk_symbol_type dec_symbol;
4947 struct nk_color cursor_text_normal;
4958 struct nk_color selected_text_normal;
4959 struct nk_color selected_text_hover;
4965 struct nk_vec2 scrollbar_size;
4969 float disabled_factor;
4985 enum nk_symbol_type sym_left;
4986 enum nk_symbol_type sym_right;
4993 float disabled_factor;
5017 float disabled_factor;
5018 nk_bool show_markers;
5040 enum nk_symbol_type sym_normal;
5041 enum nk_symbol_type sym_hover;
5042 enum nk_symbol_type sym_active;
5047 struct nk_vec2 content_padding;
5048 struct nk_vec2 button_padding;
5051 float disabled_factor;
5065 enum nk_symbol_type sym_minimize;
5066 enum nk_symbol_type sym_maximize;
5075 float disabled_factor;
5078 enum nk_style_header_align {
5091 enum nk_symbol_type close_symbol;
5092 enum nk_symbol_type minimize_symbol;
5093 enum nk_symbol_type maximize_symbol;
5101 enum nk_style_header_align align;
5113 struct nk_color popup_border_color;
5114 struct nk_color combo_border_color;
5115 struct nk_color contextual_border_color;
5117 struct nk_color group_border_color;
5118 struct nk_color tooltip_border_color;
5123 float contextual_border;
5126 float tooltip_border;
5128 float min_row_height_padding;
5132 struct nk_vec2 scrollbar_size;
5139 struct nk_vec2 contextual_padding;
5141 struct nk_vec2 tooltip_padding;
5146 const struct nk_cursor *cursors[NK_CURSOR_COUNT];
5179 #ifndef NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS
5180 #define NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS 16
5182 #ifndef NK_CHART_MAX_SLOT
5183 #define NK_CHART_MAX_SLOT 4
5186 enum nk_panel_type {
5188 NK_PANEL_WINDOW = NK_FLAG(0),
5189 NK_PANEL_GROUP = NK_FLAG(1),
5190 NK_PANEL_POPUP = NK_FLAG(2),
5191 NK_PANEL_CONTEXTUAL = NK_FLAG(4),
5192 NK_PANEL_COMBO = NK_FLAG(5),
5193 NK_PANEL_MENU = NK_FLAG(6),
5194 NK_PANEL_TOOLTIP = NK_FLAG(7)
5197 NK_PANEL_SET_NONBLOCK = NK_PANEL_CONTEXTUAL|NK_PANEL_COMBO|NK_PANEL_MENU|NK_PANEL_TOOLTIP,
5198 NK_PANEL_SET_POPUP = NK_PANEL_SET_NONBLOCK|NK_PANEL_POPUP,
5199 NK_PANEL_SET_SUB = NK_PANEL_SET_POPUP|NK_PANEL_GROUP
5203 enum nk_chart_type type;
5206 float min, max, range;
5210 nk_bool show_markers;
5219 enum nk_panel_row_layout_type {
5220 NK_LAYOUT_DYNAMIC_FIXED = 0,
5221 NK_LAYOUT_DYNAMIC_ROW,
5222 NK_LAYOUT_DYNAMIC_FREE,
5224 NK_LAYOUT_STATIC_FIXED,
5225 NK_LAYOUT_STATIC_ROW,
5226 NK_LAYOUT_STATIC_FREE,
5232 enum nk_panel_row_layout_type type;
5244 float templates[NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS];
5261 enum nk_panel_type type;
5266 float at_x, at_y, max_x;
5267 float footer_height;
5268 float header_height;
5270 unsigned int has_scrolling;
5282 #ifndef NK_WINDOW_MAX_NAME
5283 #define NK_WINDOW_MAX_NAME 64
5288 NK_WINDOW_PRIVATE = NK_FLAG(11),
5300 enum nk_panel_type type;
5304 unsigned combo_count;
5305 unsigned con_count, con_old;
5306 unsigned active_con;
5320 unsigned char single_line;
5325 char buffer[NK_MAX_NUMBER_BUFFER];
5339 char name_string[NK_WINDOW_MAX_NAME];
5346 float scrollbar_hiding_timer;
5352 unsigned int scrolled;
5353 nk_bool widgets_disabled;
5356 unsigned int table_count;
5393 #ifndef NK_BUTTON_BEHAVIOR_STACK_SIZE
5394 #define NK_BUTTON_BEHAVIOR_STACK_SIZE 8
5397 #ifndef NK_FONT_STACK_SIZE
5398 #define NK_FONT_STACK_SIZE 8
5401 #ifndef NK_STYLE_ITEM_STACK_SIZE
5402 #define NK_STYLE_ITEM_STACK_SIZE 16
5405 #ifndef NK_FLOAT_STACK_SIZE
5406 #define NK_FLOAT_STACK_SIZE 32
5409 #ifndef NK_VECTOR_STACK_SIZE
5410 #define NK_VECTOR_STACK_SIZE 16
5413 #ifndef NK_FLAGS_STACK_SIZE
5414 #define NK_FLAGS_STACK_SIZE 32
5417 #ifndef NK_COLOR_STACK_SIZE
5418 #define NK_COLOR_STACK_SIZE 32
5421 #define NK_CONFIGURATION_STACK_TYPE(prefix, name, type)\
5422 struct nk_config_stack_##name##_element {\
5423 prefix##_##type *address;\
5424 prefix##_##type old_value;\
5426 #define NK_CONFIG_STACK(type,size)\
5427 struct nk_config_stack_##type {\
5429 struct nk_config_stack_##type##_element elements[size];\
5432 #define nk_float float
5433 NK_CONFIGURATION_STACK_TYPE(
struct nk, style_item, style_item);
5434 NK_CONFIGURATION_STACK_TYPE(nk ,
float,
float);
5435 NK_CONFIGURATION_STACK_TYPE(
struct nk, vec2, vec2);
5436 NK_CONFIGURATION_STACK_TYPE(nk ,flags, flags);
5437 NK_CONFIGURATION_STACK_TYPE(
struct nk, color, color);
5438 NK_CONFIGURATION_STACK_TYPE(
const struct nk, user_font, user_font*);
5439 NK_CONFIGURATION_STACK_TYPE(
enum nk, button_behavior, button_behavior);
5441 NK_CONFIG_STACK(style_item, NK_STYLE_ITEM_STACK_SIZE);
5442 NK_CONFIG_STACK(
float, NK_FLOAT_STACK_SIZE);
5443 NK_CONFIG_STACK(vec2, NK_VECTOR_STACK_SIZE);
5444 NK_CONFIG_STACK(flags, NK_FLAGS_STACK_SIZE);
5445 NK_CONFIG_STACK(color, NK_COLOR_STACK_SIZE);
5446 NK_CONFIG_STACK(user_font, NK_FONT_STACK_SIZE);
5447 NK_CONFIG_STACK(button_behavior, NK_BUTTON_BEHAVIOR_STACK_SIZE);
5450 struct nk_config_stack_style_item style_items;
5451 struct nk_config_stack_float floats;
5452 struct nk_config_stack_vec2 vectors;
5453 struct nk_config_stack_flags flags;
5454 struct nk_config_stack_color colors;
5455 struct nk_config_stack_user_font fonts;
5456 struct nk_config_stack_button_behavior button_behaviors;
5462 #define NK_VALUE_PAGE_CAPACITY \
5463 (((NK_MAX(sizeof(struct nk_window),sizeof(struct nk_panel)) / sizeof(nk_uint))) / 2)
5468 nk_hash keys[NK_VALUE_PAGE_CAPACITY];
5469 nk_uint values[NK_VALUE_PAGE_CAPACITY];
5493 enum nk_allocation_type type;
5494 unsigned int page_count;
5508 nk_flags last_widget_state;
5509 enum nk_button_behavior button_behavior;
5511 float delta_time_seconds;
5516 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
5517 struct nk_draw_list draw_list;
5519 #ifdef NK_INCLUDE_COMMAND_USERDATA
5546 #define NK_PI 3.141592654f
5547 #define NK_PI_HALF 1.570796326f
5548 #define NK_UTF_INVALID 0xFFFD
5549 #define NK_MAX_FLOAT_PRECISION 2
5551 #define NK_UNUSED(x) ((void)(x))
5552 #define NK_SATURATE(x) (NK_MAX(0, NK_MIN(1.0f, x)))
5553 #define NK_LEN(a) (sizeof(a)/sizeof(a)[0])
5554 #define NK_ABS(a) (((a) < 0) ? -(a) : (a))
5555 #define NK_BETWEEN(x, a, b) ((a) <= (x) && (x) < (b))
5556 #define NK_INBOX(px, py, x, y, w, h)\
5557 (NK_BETWEEN(px,x,x+w) && NK_BETWEEN(py,y,y+h))
5558 #define NK_INTERSECT(x0, y0, w0, h0, x1, y1, w1, h1) \
5559 ((x1 < (x0 + w0)) && (x0 < (x1 + w1)) && \
5560 (y1 < (y0 + h0)) && (y0 < (y1 + h1)))
5561 #define NK_CONTAINS(x, y, w, h, bx, by, bw, bh)\
5562 (NK_INBOX(x,y, bx, by, bw, bh) && NK_INBOX(x+w,y+h, bx, by, bw, bh))
5564 #define nk_vec2_sub(a, b) nk_vec2((a).x - (b).x, (a).y - (b).y)
5565 #define nk_vec2_add(a, b) nk_vec2((a).x + (b).x, (a).y + (b).y)
5566 #define nk_vec2_len_sqr(a) ((a).x*(a).x+(a).y*(a).y)
5567 #define nk_vec2_muls(a, t) nk_vec2((a).x * (t), (a).y * (t))
5569 #define nk_ptr_add(t, p, i) ((t*)((void*)((nk_byte*)(p) + (i))))
5570 #define nk_ptr_add_const(t, p, i) ((const t*)((const void*)((const nk_byte*)(p) + (i))))
5571 #define nk_zero_struct(s) nk_zero(&s, sizeof(s))
5577 #if defined(__PTRDIFF_TYPE__)
5578 # define NK_UINT_TO_PTR(x) ((void*)(__PTRDIFF_TYPE__)(x))
5579 # define NK_PTR_TO_UINT(x) ((nk_size)(__PTRDIFF_TYPE__)(x))
5580 #elif !defined(__GNUC__)
5581 # define NK_UINT_TO_PTR(x) ((void*)&((char*)0)[x])
5582 # define NK_PTR_TO_UINT(x) ((nk_size)(((char*)x)-(char*)0))
5583 #elif defined(NK_USE_FIXED_TYPES)
5584 # define NK_UINT_TO_PTR(x) ((void*)(uintptr_t)(x))
5585 # define NK_PTR_TO_UINT(x) ((uintptr_t)(x))
5587 # define NK_UINT_TO_PTR(x) ((void*)(x))
5588 # define NK_PTR_TO_UINT(x) ((nk_size)(x))
5591 #define NK_ALIGN_PTR(x, mask)\
5592 (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte*)(x) + (mask-1)) & ~(mask-1))))
5593 #define NK_ALIGN_PTR_BACK(x, mask)\
5594 (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte*)(x)) & ~(mask-1))))
5596 #if ((defined(__GNUC__) && __GNUC__ >= 4) || defined(__clang__)) && !defined(EMSCRIPTEN)
5597 #define NK_OFFSETOF(st,m) (__builtin_offsetof(st,m))
5599 #define NK_OFFSETOF(st,m) ((nk_ptr)&(((st*)0)->m))
5607 template<
typename T>
struct nk_alignof;
5608 template<
typename T,
int size_diff>
struct nk_helper{
enum {value = size_diff};};
5609 template<
typename T>
struct nk_helper<T,0>{
enum {value = nk_alignof<T>::value};};
5610 template<
typename T>
struct nk_alignof{
struct Big {T x;
char c;};
enum {
5611 diff =
sizeof(Big) -
sizeof(T), value = nk_helper<Big, diff>::value};};
5612 #define NK_ALIGNOF(t) (nk_alignof<t>::value)
5614 #define NK_ALIGNOF(t) NK_OFFSETOF(struct {char c; t _h;}, _h)
5617 #define NK_CONTAINER_OF(ptr,type,member)\
5618 (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member)))
5624 #ifdef NK_IMPLEMENTATION
5626 #ifndef NK_INTERNAL_H
5627 #define NK_INTERNAL_H
5629 #ifndef NK_POOL_DEFAULT_CAPACITY
5630 #define NK_POOL_DEFAULT_CAPACITY 16
5633 #ifndef NK_DEFAULT_COMMAND_BUFFER_SIZE
5634 #define NK_DEFAULT_COMMAND_BUFFER_SIZE (4*1024)
5637 #ifndef NK_BUFFER_DEFAULT_INITIAL_SIZE
5638 #define NK_BUFFER_DEFAULT_INITIAL_SIZE (4*1024)
5642 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
5645 #ifdef NK_INCLUDE_STANDARD_IO
5648 #ifdef NK_INCLUDE_STANDARD_VARARGS
5653 #define NK_ASSERT(expr) assert(expr)
5656 #define NK_DEFAULT (-1)
5658 #ifndef NK_VSNPRINTF
5663 #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) ||\
5664 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
5665 (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) ||\
5666 (defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)) ||\
5667 defined(_ISOC99_SOURCE) || defined(_BSD_SOURCE)
5668 #define NK_VSNPRINTF(s,n,f,a) vsnprintf(s,n,f,a)
5670 #define NK_VSNPRINTF(s,n,f,a) vsprintf(s,f,a)
5674 #define NK_SCHAR_MIN (-127)
5675 #define NK_SCHAR_MAX 127
5676 #define NK_UCHAR_MIN 0
5677 #define NK_UCHAR_MAX 256
5678 #define NK_SSHORT_MIN (-32767)
5679 #define NK_SSHORT_MAX 32767
5680 #define NK_USHORT_MIN 0
5681 #define NK_USHORT_MAX 65535
5682 #define NK_SINT_MIN (-2147483647)
5683 #define NK_SINT_MAX 2147483647
5684 #define NK_UINT_MIN 0
5685 #define NK_UINT_MAX 4294967295u
5690 NK_STATIC_ASSERT(
sizeof(nk_size) >=
sizeof(
void*));
5691 NK_STATIC_ASSERT(
sizeof(nk_ptr) ==
sizeof(
void*));
5692 NK_STATIC_ASSERT(
sizeof(nk_flags) >= 4);
5693 NK_STATIC_ASSERT(
sizeof(nk_rune) >= 4);
5694 NK_STATIC_ASSERT(
sizeof(nk_ushort) == 2);
5695 NK_STATIC_ASSERT(
sizeof(nk_short) == 2);
5696 NK_STATIC_ASSERT(
sizeof(nk_uint) == 4);
5697 NK_STATIC_ASSERT(
sizeof(nk_int) == 4);
5698 NK_STATIC_ASSERT(
sizeof(nk_byte) == 1);
5699 #ifdef NK_INCLUDE_STANDARD_BOOL
5700 NK_STATIC_ASSERT(
sizeof(nk_bool) ==
sizeof(
bool));
5702 NK_STATIC_ASSERT(
sizeof(nk_bool) == 4);
5705 NK_GLOBAL
const struct nk_rect nk_null_rect = {-8192.0f, -8192.0f, 16384, 16384};
5706 #define NK_FLOAT_PRECISION 0.00000000000001
5708 NK_GLOBAL
const struct nk_color nk_red = {255,0,0,255};
5709 NK_GLOBAL
const struct nk_color nk_green = {0,255,0,255};
5710 NK_GLOBAL
const struct nk_color nk_blue = {0,0,255,255};
5711 NK_GLOBAL
const struct nk_color nk_white = {255,255,255,255};
5712 NK_GLOBAL
const struct nk_color nk_black = {0,0,0,255};
5713 NK_GLOBAL
const struct nk_color nk_yellow = {255,255,0,255};
5716 #define nk_widget_state_reset(s)\
5717 if ((*(s)) & NK_WIDGET_STATE_MODIFIED)\
5718 (*(s)) = NK_WIDGET_STATE_INACTIVE|NK_WIDGET_STATE_MODIFIED;\
5719 else (*(s)) = NK_WIDGET_STATE_INACTIVE;
5723 NK_LIB
float nk_inv_sqrt(
float n);
5726 NK_LIB
float nk_sin(
float x);
5729 NK_LIB
float nk_cos(
float x);
5732 NK_LIB
float nk_atan(
float x);
5735 NK_LIB
float nk_atan2(
float y,
float x);
5737 NK_LIB nk_uint nk_round_up_pow2(nk_uint v);
5738 NK_LIB
struct nk_rect nk_shrink_rect(struct
nk_rect r, float amount);
5740 NK_LIB
void nk_unify(
struct nk_rect *clip,
const struct nk_rect *a,
float x0,
float y0,
float x1,
float y1);
5741 NK_LIB
double nk_pow(
double x,
int n);
5742 NK_LIB
int nk_ifloord(
double x);
5743 NK_LIB
int nk_ifloorf(
float x);
5744 NK_LIB
int nk_iceilf(
float x);
5745 NK_LIB
int nk_log10(
double n);
5746 NK_LIB
float nk_roundf(
float x);
5749 enum {NK_DO_NOT_STOP_ON_NEW_LINE, NK_STOP_ON_NEW_LINE};
5750 NK_LIB nk_bool nk_is_lower(
int c);
5751 NK_LIB nk_bool nk_is_upper(
int c);
5752 NK_LIB
int nk_to_upper(
int c);
5753 NK_LIB
int nk_to_lower(
int c);
5756 NK_LIB
void* nk_memcopy(
void *dst,
const void *src, nk_size n);
5759 NK_LIB
void nk_memset(
void *ptr,
int c0, nk_size size);
5761 NK_LIB
void nk_zero(
void *ptr, nk_size size);
5762 NK_LIB
char *nk_itoa(
char *s,
long n);
5763 NK_LIB
int nk_string_float_limit(
char *
string,
int prec);
5765 NK_LIB
char *nk_dtoa(
char *s,
double n);
5767 NK_LIB
int nk_text_clamp(
const struct nk_user_font *font,
const char *text,
int text_len,
float space,
int *glyphs,
float *text_width, nk_rune *sep_list,
int sep_count);
5768 NK_LIB
struct nk_vec2 nk_text_calculate_text_bounds(const struct
nk_user_font *font,
const char *begin,
int byte_len,
float row_height,
const char **remaining,
struct nk_vec2 *out_offset,
int *glyphs,
int op);
5769 #ifdef NK_INCLUDE_STANDARD_VARARGS
5770 NK_LIB
int nk_strfmt(
char *buf,
int buf_size,
const char *fmt, va_list args);
5772 #ifdef NK_INCLUDE_STANDARD_IO
5773 NK_LIB
char *nk_file_load(
const char* path, nk_size* siz,
const struct nk_allocator *alloc);
5777 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
5778 NK_LIB
void* nk_malloc(
nk_handle unused,
void *old,nk_size size);
5779 NK_LIB
void nk_mfree(
nk_handle unused,
void *ptr);
5781 NK_LIB
void* nk_buffer_align(
void *unaligned, nk_size align, nk_size *alignment,
enum nk_buffer_allocation_type type);
5782 NK_LIB
void* nk_buffer_alloc(
struct nk_buffer *b,
enum nk_buffer_allocation_type type, nk_size size, nk_size align);
5783 NK_LIB
void* nk_buffer_realloc(
struct nk_buffer *b, nk_size capacity, nk_size *size);
5788 NK_LIB
void* nk_command_buffer_push(
struct nk_command_buffer* b,
enum nk_command_type t, nk_size size);
5798 NK_LIB
void nk_build(
struct nk_context *ctx);
5801 NK_LIB
void nk_textedit_clear_state(
struct nk_text_edit *state,
enum nk_text_edit_type type, nk_plugin_filter filter);
5802 NK_LIB
void nk_textedit_click(
struct nk_text_edit *state,
float x,
float y,
const struct nk_user_font *font,
float row_height);
5803 NK_LIB
void nk_textedit_drag(
struct nk_text_edit *state,
float x,
float y,
const struct nk_user_font *font,
float row_height);
5804 NK_LIB
void nk_textedit_key(
struct nk_text_edit *state,
enum nk_keys key,
int shift_mod,
const struct nk_user_font *font,
float row_height);
5807 enum nk_window_insert_location {
5811 NK_LIB
void *nk_create_window(
struct nk_context *ctx);
5814 NK_LIB
struct nk_window *nk_find_window(
const struct nk_context *ctx, nk_hash hash,
const char *name);
5815 NK_LIB
void nk_insert_window(
struct nk_context *ctx,
struct nk_window *win,
enum nk_window_insert_location loc);
5818 NK_LIB
void nk_pool_init(
struct nk_pool *pool,
const struct nk_allocator *alloc,
unsigned int capacity);
5819 NK_LIB
void nk_pool_free(
struct nk_pool *pool);
5820 NK_LIB
void nk_pool_init_fixed(
struct nk_pool *pool,
void *memory, nk_size size);
5833 NK_LIB nk_uint *nk_add_value(
struct nk_context *ctx,
struct nk_window *win, nk_hash name, nk_uint value);
5834 NK_LIB nk_uint *nk_find_value(
const struct nk_window *win, nk_hash name);
5837 NK_LIB
void *nk_create_panel(
struct nk_context *ctx);
5839 NK_LIB nk_bool nk_panel_has_header(nk_flags flags,
const char *title);
5840 NK_LIB
struct nk_vec2 nk_panel_get_padding(const struct
nk_style *style,
enum nk_panel_type type);
5841 NK_LIB
float nk_panel_get_border(
const struct nk_style *style, nk_flags flags,
enum nk_panel_type type);
5842 NK_LIB
struct nk_color nk_panel_get_border_color(const struct
nk_style *style,
enum nk_panel_type type);
5843 NK_LIB nk_bool nk_panel_is_sub(
enum nk_panel_type type);
5844 NK_LIB nk_bool nk_panel_is_nonblock(
enum nk_panel_type type);
5845 NK_LIB nk_bool nk_panel_begin(
struct nk_context *ctx,
const char *title,
enum nk_panel_type panel_type);
5846 NK_LIB
void nk_panel_end(
struct nk_context *ctx);
5849 NK_LIB
float nk_layout_row_calculate_usable_space(
const struct nk_style *style,
enum nk_panel_type type,
float total_space,
int columns);
5850 NK_LIB
void nk_panel_layout(
const struct nk_context *ctx,
struct nk_window *win,
float height,
int cols);
5851 NK_LIB
void nk_row_layout(
struct nk_context *ctx,
enum nk_layout_format fmt,
float height,
int cols,
int width);
5854 NK_LIB
void nk_panel_alloc_space(
struct nk_rect *bounds,
const struct nk_context *ctx);
5855 NK_LIB
void nk_layout_peek(
struct nk_rect *bounds,
const struct nk_context *ctx);
5858 NK_LIB nk_bool nk_nonblock_begin(
struct nk_context *ctx, nk_flags flags,
struct nk_rect body,
struct nk_rect header,
enum nk_panel_type panel_type);
5870 NK_LIB nk_bool nk_button_behavior(nk_flags *state,
struct nk_rect r,
const struct nk_input *i,
enum nk_button_behavior behavior);
5880 NK_LIB nk_bool nk_do_button_text_symbol(nk_flags *state,
struct nk_command_buffer *out,
struct nk_rect bounds,
enum nk_symbol_type symbol,
const char *str,
int len, nk_flags align,
enum nk_button_behavior behavior,
const struct nk_style_button *style,
const struct nk_user_font *font,
const struct nk_input *in);
5882 NK_LIB nk_bool nk_do_button_text_image(nk_flags *state,
struct nk_command_buffer *out,
struct nk_rect bounds,
struct nk_image img,
const char* str,
int len, nk_flags align,
enum nk_button_behavior behavior,
const struct nk_style_button *style,
const struct nk_user_font *font,
const struct nk_input *in);
5885 enum nk_toggle_type {
5889 NK_LIB nk_bool nk_toggle_behavior(
const struct nk_input *in,
struct nk_rect select, nk_flags *state, nk_bool active);
5890 NK_LIB
void nk_draw_checkbox(
struct nk_command_buffer *out, nk_flags state,
const struct nk_style_toggle *style, nk_bool active,
const struct nk_rect *label,
const struct nk_rect *selector,
const struct nk_rect *cursors,
const char *
string,
int len,
const struct nk_user_font *font, nk_flags text_alignment);
5891 NK_LIB
void nk_draw_option(
struct nk_command_buffer *out, nk_flags state,
const struct nk_style_toggle *style, nk_bool active,
const struct nk_rect *label,
const struct nk_rect *selector,
const struct nk_rect *cursors,
const char *
string,
int len,
const struct nk_user_font *font, nk_flags text_alignment);
5892 NK_LIB nk_bool nk_do_toggle(nk_flags *state,
struct nk_command_buffer *out,
struct nk_rect r, nk_bool *active,
const char *str,
int len,
enum nk_toggle_type type,
const struct nk_style_toggle *style,
const struct nk_input *in,
const struct nk_user_font *font, nk_flags widget_alignment, nk_flags text_alignment);
5895 NK_LIB nk_size nk_progress_behavior(nk_flags *state,
struct nk_input *in,
struct nk_rect r,
struct nk_rect cursor, nk_size max, nk_size value, nk_bool modifiable);
5900 NK_LIB
float nk_slider_behavior(nk_flags *state,
struct nk_rect *logical_cursor,
struct nk_rect *visual_cursor,
struct nk_input *in,
struct nk_rect bounds,
float slider_min,
float slider_max,
float slider_value,
float slider_step,
float slider_steps);
5905 NK_LIB
float nk_scrollbar_behavior(nk_flags *state,
struct nk_input *in,
int has_scrolling,
const struct nk_rect *scroll,
const struct nk_rect *cursor,
const struct nk_rect *empty0,
const struct nk_rect *empty1,
float scroll_offset,
float target,
float scroll_step,
enum nk_orientation o);
5907 NK_LIB
float nk_do_scrollbarv(nk_flags *state,
struct nk_command_buffer *out,
struct nk_rect scroll,
int has_scrolling,
float offset,
float target,
float step,
float button_pixel_inc,
const struct nk_style_scrollbar *style,
struct nk_input *in,
const struct nk_user_font *font);
5908 NK_LIB
float nk_do_scrollbarh(nk_flags *state,
struct nk_command_buffer *out,
struct nk_rect scroll,
int has_scrolling,
float offset,
float target,
float step,
float button_pixel_inc,
const struct nk_style_scrollbar *style,
struct nk_input *in,
const struct nk_user_font *font);
5911 NK_LIB
void nk_draw_selectable(
struct nk_command_buffer *out, nk_flags state,
const struct nk_style_selectable *style, nk_bool active,
const struct nk_rect *bounds,
const struct nk_rect *icon,
const struct nk_image *img,
enum nk_symbol_type sym,
const char *
string,
int len, nk_flags align,
const struct nk_user_font *font);
5913 NK_LIB nk_bool nk_do_selectable_image(nk_flags *state,
struct nk_command_buffer *out,
struct nk_rect bounds,
const char *str,
int len, nk_flags align, nk_bool *value,
const struct nk_image *img,
const struct nk_style_selectable *style,
const struct nk_input *in,
const struct nk_user_font *font);
5916 NK_LIB
void nk_edit_draw_text(
struct nk_command_buffer *out,
const struct nk_style_edit *style,
float pos_x,
float pos_y,
float x_offset,
const char *text,
int byte_len,
float row_height,
const struct nk_user_font *font,
struct nk_color background,
struct nk_color foreground, nk_bool is_selected);
5920 NK_LIB nk_bool nk_color_picker_behavior(nk_flags *state,
const struct nk_rect *bounds,
const struct nk_rect *matrix,
const struct nk_rect *hue_bar,
const struct nk_rect *alpha_bar,
struct nk_colorf *color,
const struct nk_input *in);
5925 enum nk_property_status {
5926 NK_PROPERTY_DEFAULT,
5930 enum nk_property_filter {
5934 enum nk_property_kind {
5944 struct nk_property_variant {
5945 enum nk_property_kind kind;
5946 union nk_property value;
5947 union nk_property min_value;
5948 union nk_property max_value;
5949 union nk_property step;
5951 NK_LIB
struct nk_property_variant nk_property_variant_int(int value, int min_value, int max_value, int step);
5952 NK_LIB
struct nk_property_variant nk_property_variant_float(float value, float min_value, float max_value, float step);
5953 NK_LIB
struct nk_property_variant nk_property_variant_double(double value, double min_value, double max_value, double step);
5955 NK_LIB
void nk_drag_behavior(nk_flags *state,
const struct nk_input *in,
struct nk_rect drag,
struct nk_property_variant *variant,
float inc_per_pixel);
5956 NK_LIB
void nk_property_behavior(nk_flags *ws,
const struct nk_input *in,
struct nk_rect property,
struct nk_rect label,
struct nk_rect edit,
struct nk_rect empty,
int *state,
struct nk_property_variant *variant,
float inc_per_pixel);
5958 NK_LIB
void nk_do_property(nk_flags *ws,
struct nk_command_buffer *out,
struct nk_rect property,
const char *name,
struct nk_property_variant *variant,
float inc_per_pixel,
char *buffer,
int *len,
int *state,
int *cursor,
int *select_begin,
int *select_end,
const struct nk_style_property *style,
enum nk_property_filter filter,
struct nk_input *in,
const struct nk_user_font *font,
struct nk_text_edit *text_edit,
enum nk_button_behavior behavior);
5959 NK_LIB
void nk_property(
struct nk_context *ctx,
const char *name,
struct nk_property_variant *variant,
float inc_per_pixel,
const enum nk_property_filter filter);
5961 #ifdef NK_INCLUDE_FONT_BAKING
5968 #ifndef NK_NO_STB_RECT_PACK_IMPLEMENTATION
5969 #define STB_RECT_PACK_IMPLEMENTATION
5977 #ifndef NK_NO_STB_TRUETYPE_IMPLEMENTATION
5978 #define STB_TRUETYPE_IMPLEMENTATION
5982 #ifndef STBTT_malloc
5984 nk_stbtt_malloc(nk_size size,
void *user_data) {
5986 return alloc->alloc(alloc->userdata, 0, size);
5990 nk_stbtt_free(
void *ptr,
void *user_data) {
5992 alloc->free(alloc->userdata, ptr);
5995 #define STBTT_malloc(x,u) nk_stbtt_malloc(x,u)
5996 #define STBTT_free(x,u) nk_stbtt_free(x,u)
6041 #define NK_INV_SQRT nk_inv_sqrt
6053 nk_inv_sqrt(
float n)
6056 const float threehalfs = 1.5f;
6057 union {nk_uint i;
float f;} conv = {0};
6060 conv.i = 0x5f375A84 - (conv.i >> 1);
6061 conv.f = conv.f * (threehalfs - (x2 * conv.f * conv.f));
6066 #define NK_SIN nk_sin
6080 NK_STORAGE
const float a0 = +1.91059300966915117e-31f;
6081 NK_STORAGE
const float a1 = +1.00086760103908896f;
6082 NK_STORAGE
const float a2 = -1.21276126894734565e-2f;
6083 NK_STORAGE
const float a3 = -1.38078780785773762e-1f;
6084 NK_STORAGE
const float a4 = -2.67353392911981221e-2f;
6085 NK_STORAGE
const float a5 = +2.08026600266304389e-2f;
6086 NK_STORAGE
const float a6 = -3.03996055049204407e-3f;
6087 NK_STORAGE
const float a7 = +1.38235642404333740e-4f;
6088 return a0 + x*(a1 + x*(a2 + x*(a3 + x*(a4 + x*(a5 + x*(a6 + x*a7))))));
6092 #define NK_COS nk_cos
6108 NK_STORAGE
const float a0 = 9.9995999154986614e-1f;
6109 NK_STORAGE
const float a1 = 1.2548995793001028e-3f;
6110 NK_STORAGE
const float a2 = -5.0648546280678015e-1f;
6111 NK_STORAGE
const float a3 = 1.2942246466519995e-2f;
6112 NK_STORAGE
const float a4 = 2.8668384702547972e-2f;
6113 NK_STORAGE
const float a5 = 7.3726485210586547e-3f;
6114 NK_STORAGE
const float a6 = -3.8510875386947414e-3f;
6115 NK_STORAGE
const float a7 = 4.7196604604366623e-4f;
6116 NK_STORAGE
const float a8 = -1.8776444013090451e-5f;
6117 return a0 + x*(a1 + x*(a2 + x*(a3 + x*(a4 + x*(a5 + x*(a6 + x*(a7 + x*a8)))))));
6121 #define NK_ATAN nk_atan
6136 float u = -1.0989005e-05f;
6137 NK_ASSERT(x >= 0.0f &&
"TODO support negative floats");
6138 u = u * x + 0.00034117949f;
6139 u = u * x + -0.0044932296f;
6140 u = u * x + 0.032596264f;
6141 u = u * x + -0.14088021f;
6142 u = u * x + 0.36040401f;
6143 u = u * x + -0.47017866f;
6144 u = u * x + 0.00050198776f;
6145 u = u * x + 1.0077682f;
6146 u = u * x + -0.0004765437f;
6151 #define NK_ATAN2 nk_atan2
6164 nk_atan2(
float y,
float x)
6166 float ax = NK_ABS(x),
6170 nk_uint signs = (y < 0) | ((x < 0) << 1);
6173 if(y == 0.0 && x == 0.0)
return 0.0f;
6175 ? NK_PI_HALF - NK_ATAN(ax / ay)
6181 case 2:
return -a + NK_PI;
6182 case 3:
return a - NK_PI;
6198 nk_round_up_pow2(nk_uint v)
6221 nk_pow(
double x,
int n)
6226 n = (plus) ? n : -n;
6233 return plus ? r : 1.0 / r;
6246 nk_ifloord(
double x)
6248 x = (double)((
int)x - ((x < 0.0) ? 1 : 0));
6264 x = (float)((
int)x - ((x < 0.0f) ? 1 : 0));
6282 return (x > i) ? i+1: i;
6285 float r = x - (float)t;
6286 return (r > 0.0f) ? t+1: t;
6306 neg = (n < 0) ? 1 : 0;
6307 ret = (neg) ? (
int)-n : (int)n;
6308 while ((ret / 10) > 0) {
6312 if (neg) exp = -exp;
6328 return (x >= 0.0) ? nk_ifloorf(x + 0.5) : nk_iceilf(x - 0.5);
6341 nk_get_null_rect(void)
6343 return nk_null_rect;
6359 nk_rect(float x, float y, float w, float h)
6380 nk_recti(int x, int y, int w, int h)
6403 return nk_rect(pos.x, pos.y, size.x, size.y);
6416 nk_rectv(const float *r)
6418 return nk_rect(r[0], r[1], r[2], r[3]);
6431 nk_rectiv(const int *r)
6433 return nk_recti(r[0], r[1], r[2], r[3]);
6449 ret.x = r.x; ret.y = r.y;
6463 nk_rect_size(struct
nk_rect r)
6466 ret.x = r.w; ret.y = r.h;
6481 nk_shrink_rect(struct
nk_rect r, float amount)
6484 r.w = NK_MAX(r.w, 2 * amount);
6485 r.h = NK_MAX(r.h, 2 * amount);
6486 res.x = r.x + amount;
6487 res.y = r.y + amount;
6488 res.w = r.w - 2 * amount;
6489 res.h = r.h - 2 * amount;
6506 r.w = NK_MAX(r.w, 2 * pad.x);
6507 r.h = NK_MAX(r.h, 2 * pad.y);
6508 r.x += pad.x; r.y += pad.y;
6528 ret.x = x; ret.y = y;
6561 nk_vec2v(const float *v)
6576 nk_vec2iv(const int *v)
6594 nk_unify(
struct nk_rect *clip,
const struct nk_rect *a,
float x0,
float y0,
6599 clip->x = NK_MAX(a->x, x0);
6600 clip->y = NK_MAX(a->y, y0);
6601 clip->w = NK_MIN(a->x + a->w, x1) - clip->x;
6602 clip->h = NK_MIN(a->y + a->h, y1) - clip->y;
6603 clip->w = NK_MAX(0, clip->w);
6604 clip->h = NK_MAX(0, clip->h);
6619 nk_triangle_from_direction(
struct nk_vec2 *result,
struct nk_rect r,
6620 float pad_x,
float pad_y,
enum nk_heading direction)
6622 float w_half, h_half;
6625 r.w = NK_MAX(2 * pad_x, r.w);
6626 r.h = NK_MAX(2 * pad_y, r.h);
6627 r.w = r.w - 2 * pad_x;
6628 r.h = r.h - 2 * pad_y;
6633 w_half = r.w / 2.0f;
6634 h_half = r.h / 2.0f;
6636 if (direction == NK_UP) {
6637 result[0] =
nk_vec2(r.x + w_half, r.y);
6638 result[1] =
nk_vec2(r.x + r.w, r.y + r.h);
6639 result[2] =
nk_vec2(r.x, r.y + r.h);
6640 }
else if (direction == NK_RIGHT) {
6641 result[0] =
nk_vec2(r.x, r.y);
6642 result[1] =
nk_vec2(r.x + r.w, r.y + h_half);
6643 result[2] =
nk_vec2(r.x, r.y + r.h);
6644 }
else if (direction == NK_DOWN) {
6645 result[0] =
nk_vec2(r.x, r.y);
6646 result[1] =
nk_vec2(r.x + r.w, r.y);
6647 result[2] =
nk_vec2(r.x + w_half, r.y + r.h);
6649 result[0] =
nk_vec2(r.x, r.y + h_half);
6650 result[1] =
nk_vec2(r.x + r.w, r.y);
6651 result[2] =
nk_vec2(r.x + r.w, r.y + r.h);
6664 NK_INTERN
int nk_str_match_here(
const char *regexp,
const char *text);
6665 NK_INTERN
int nk_str_match_star(
int c,
const char *regexp,
const char *text);
6666 NK_LIB nk_bool nk_is_lower(
int c) {
return (c >=
'a' && c <=
'z') || (c >= 0xE0 && c <= 0xFF);}
6667 NK_LIB nk_bool nk_is_upper(
int c){
return (c >=
'A' && c <=
'Z') || (c >= 0xC0 && c <= 0xDF);}
6668 NK_LIB
int nk_to_upper(
int c) {
return (c >=
'a' && c <=
'z') ? (c - (
'a' -
'A')) : c;}
6669 NK_LIB
int nk_to_lower(
int c) {
return (c >=
'A' && c <=
'Z') ? (c - (
'a' +
'A')) : c;}
6672 #define NK_MEMCPY nk_memcopy
6686 nk_memcopy(
void *dst0,
const void *src0, nk_size length)
6689 char *dst = (
char*)dst0;
6690 const char *src = (
const char*)src0;
6691 if (length == 0 || dst == src)
6695 #define nk_wsize sizeof(nk_word)
6696 #define nk_wmask (nk_wsize-1)
6697 #define NK_TLOOP(s) if (t) NK_TLOOP1(s)
6698 #define NK_TLOOP1(s) do { s; } while (--t)
6702 if ((t | (nk_ptr)dst) & nk_wmask) {
6703 if ((t ^ (nk_ptr)dst) & nk_wmask || length < nk_wsize)
6706 t = nk_wsize - (t & nk_wmask);
6708 NK_TLOOP1(*dst++ = *src++);
6710 t = length / nk_wsize;
6711 NK_TLOOP(*(nk_word*)(
void*)dst = *(
const nk_word*)(
const void*)src;
6712 src += nk_wsize; dst += nk_wsize);
6713 t = length & nk_wmask;
6714 NK_TLOOP(*dst++ = *src++);
6719 if ((t | (nk_ptr)dst) & nk_wmask) {
6720 if ((t ^ (nk_ptr)dst) & nk_wmask || length <= nk_wsize)
6725 NK_TLOOP1(*--dst = *--src);
6727 t = length / nk_wsize;
6728 NK_TLOOP(src -= nk_wsize; dst -= nk_wsize;
6729 *(nk_word*)(
void*)dst = *(
const nk_word*)(
const void*)src);
6730 t = length & nk_wmask;
6731 NK_TLOOP(*--dst = *--src);
6743 #define NK_MEMSET nk_memset
6757 nk_memset(
void *ptr,
int c0, nk_size size)
6759 #define nk_word unsigned
6760 #define nk_wsize sizeof(nk_word)
6761 #define nk_wmask (nk_wsize - 1)
6762 nk_byte *dst = (nk_byte*)ptr;
6766 if ((c = (nk_byte)c0) != 0) {
6768 if (
sizeof(
unsigned int) > 2)
6773 dst = (nk_byte*)ptr;
6774 if (size < 3 * nk_wsize) {
6775 while (size--) *dst++ = (nk_byte)c0;
6780 if ((t = NK_PTR_TO_UINT(dst) & nk_wmask) != 0) {
6784 *dst++ = (nk_byte)c0;
6789 t = size / nk_wsize;
6791 *(nk_word*)((
void*)dst) = c;
6796 t = (size & nk_wmask);
6799 *dst++ = (nk_byte)c0;
6820 nk_zero(
void *ptr, nk_size size)
6823 NK_MEMSET(ptr, 0, size);
6836 nk_strlen(
const char *str)
6840 while (str && *str++ !=
'\0') siz++;
6855 nk_strtoi(
const char *str,
char **endptr)
6858 const char *p = str;
6865 while (*p ==
' ') p++;
6870 while (*p && *p >=
'0' && *p <=
'9') {
6871 value = value * 10 + (int) (*p -
'0');
6875 *endptr = (
char *)p;
6890 nk_strtod(
const char *str,
char **endptr)
6894 char *p = (
char *)str;
6902 while (*p ==
' ') p++;
6908 while (*p && *p !=
'.' && *p !=
'e') {
6909 value = value * 10.0 + (double) (*p -
'0');
6915 for(m = 0.1; *p && *p !=
'e'; p++ ) {
6916 value = value + (double) (*p -
'0') * m;
6926 }
else if (*p ==
'+') {
6929 }
else div = nk_false;
6931 for (pow = 0; *p; p++)
6932 pow = pow * 10 + (
int) (*p -
'0');
6934 for (m = 1.0, i = 0; i < pow; i++)
6941 number = value * neg;
6958 nk_strtof(
const char *str,
char **endptr)
6961 double double_value;
6962 double_value = NK_STRTOD(str, endptr);
6963 float_value = (float)double_value;
6978 nk_stricmp(
const char *s1,
const char *s2)
6986 if (c1 <= 'Z' && c1 >=
'A') {
6990 if (c2 <= 'Z' && c2 >=
'A') {
6994 return ((d >= 0) << 1) - 1;
7012 nk_stricmpn(
const char *s1,
const char *s2,
int n)
7023 if (c1 <= 'Z' && c1 >=
'A') {
7027 if (c2 <= 'Z' && c2 >=
'A') {
7031 return ((d >= 0) << 1) - 1;
7048 nk_str_match_here(
const char *regexp,
const char *text)
7050 if (regexp[0] ==
'\0')
7052 if (regexp[1] ==
'*')
7053 return nk_str_match_star(regexp[0], regexp+2, text);
7054 if (regexp[0] ==
'$' && regexp[1] ==
'\0')
7055 return *text ==
'\0';
7056 if (*text!=
'\0' && (regexp[0]==
'.' || regexp[0]==*text))
7057 return nk_str_match_here(regexp+1, text+1);
7073 nk_str_match_star(
int c,
const char *regexp,
const char *text)
7076 if (nk_str_match_here(regexp, text))
7078 }
while (*text !=
'\0' && (*text++ == c || c ==
'.'));
7093 nk_strfilter(
const char *text,
const char *regexp)
7101 if (regexp[0] ==
'^')
7102 return nk_str_match_here(regexp+1, text);
7104 if (nk_str_match_here(regexp, text))
7106 }
while (*text++ !=
'\0');
7121 nk_strmatch_fuzzy_text(
const char *str,
int str_len,
7122 const char *pattern,
int *out_score)
7129 #define NK_ADJACENCY_BONUS 5
7131 #define NK_SEPARATOR_BONUS 10
7133 #define NK_CAMEL_BONUS 10
7135 #define NK_LEADING_LETTER_PENALTY (-3)
7137 #define NK_MAX_LEADING_LETTER_PENALTY (-9)
7139 #define NK_UNMATCHED_LETTER_PENALTY (-1)
7143 char const * pattern_iter = pattern;
7145 int prev_matched = nk_false;
7146 int prev_lower = nk_false;
7148 int prev_separator = nk_true;
7151 char const * best_letter = 0;
7152 int best_letter_score = 0;
7157 if (!str || !str_len || !pattern)
return 0;
7158 while (str_iter < str_len)
7160 const char pattern_letter = *pattern_iter;
7161 const char str_letter = str[str_iter];
7163 int next_match = *pattern_iter !=
'\0' &&
7164 nk_to_lower(pattern_letter) == nk_to_lower(str_letter);
7165 int rematch = best_letter && nk_to_upper(*best_letter) == nk_to_upper(str_letter);
7167 int advanced = next_match && best_letter;
7168 int pattern_repeat = best_letter && *pattern_iter !=
'\0';
7169 pattern_repeat = pattern_repeat &&
7170 nk_to_lower(*best_letter) == nk_to_lower(pattern_letter);
7172 if (advanced || pattern_repeat) {
7173 score += best_letter_score;
7175 best_letter_score = 0;
7178 if (next_match || rematch)
7182 if (pattern_iter == pattern) {
7183 int count = (int)(&str[str_iter] - str);
7184 int penalty = NK_LEADING_LETTER_PENALTY * count;
7185 if (penalty < NK_MAX_LEADING_LETTER_PENALTY)
7186 penalty = NK_MAX_LEADING_LETTER_PENALTY;
7193 new_score += NK_ADJACENCY_BONUS;
7197 new_score += NK_SEPARATOR_BONUS;
7200 if (prev_lower && nk_is_upper(str_letter))
7201 new_score += NK_CAMEL_BONUS;
7208 if (new_score >= best_letter_score) {
7210 if (best_letter != 0)
7211 score += NK_UNMATCHED_LETTER_PENALTY;
7213 best_letter = &str[str_iter];
7214 best_letter_score = new_score;
7216 prev_matched = nk_true;
7218 score += NK_UNMATCHED_LETTER_PENALTY;
7219 prev_matched = nk_false;
7223 prev_lower = nk_is_lower(str_letter) != 0;
7224 prev_separator = str_letter ==
'_' || str_letter ==
' ';
7231 score += best_letter_score;
7234 if (*pattern_iter !=
'\0')
7254 nk_strmatch_fuzzy_string(
char const *str,
char const *pattern,
int *out_score)
7256 return nk_strmatch_fuzzy_text(str, nk_strlen(str), pattern, out_score);
7270 nk_string_float_limit(
char *
string,
int prec)
7280 if (dot == (prec+1)) {
7287 return (
int)(c - string);
7300 nk_strrev_ascii(
char *s)
7302 int len = nk_strlen(s);
7306 for (; i < end; ++i) {
7308 s[i] = s[len - 1 - i];
7324 nk_itoa(
char *s,
long n)
7337 s[i++] = (char)(
'0' + (n % 10));
7348 #define NK_DTOA nk_dtoa
7361 nk_dtoa(
char *s,
double n)
7364 int digit = 0, m = 0, m1 = 0;
7372 s[0] =
'0'; s[1] =
'\0';
7381 useExp = (m >= 14 || (neg && m >= 9) || m <= -9);
7382 if (neg) *(c++) =
'-';
7388 n = n / (double)nk_pow(10.0, m);
7397 while (n > NK_FLOAT_PRECISION || m >= 0) {
7398 double weight = nk_pow(10.0, m);
7400 double t = (double)n / weight;
7401 digit = nk_ifloord(t);
7402 n -= ((double)digit * weight);
7403 *(c++) = (
char)(
'0' + (char)digit);
7405 if (m == 0 && n > 0)
7422 *(c++) = (
char)(
'0' + (char)(m1 % 10));
7427 for (i = 0, j = m-1; i<j; i++, j--) {
7439 #ifdef NK_INCLUDE_STANDARD_VARARGS
7440 #ifndef NK_INCLUDE_STANDARD_IO
7455 nk_vsnprintf(
char *buf,
int buf_size,
const char *fmt, va_list args)
7460 NK_ARG_TYPE_DEFAULT,
7464 NK_ARG_FLAG_LEFT = 0x01,
7465 NK_ARG_FLAG_PLUS = 0x02,
7466 NK_ARG_FLAG_SPACE = 0x04,
7467 NK_ARG_FLAG_NUM = 0x10,
7468 NK_ARG_FLAG_ZERO = 0x20
7471 char number_buffer[NK_MAX_NUMBER_BUFFER];
7472 enum nk_arg_type arg_type = NK_ARG_TYPE_DEFAULT;
7473 int precision = NK_DEFAULT;
7474 int width = NK_DEFAULT;
7479 const char *iter = fmt;
7482 NK_ASSERT(buf_size);
7483 if (!buf || !buf_size || !fmt)
return 0;
7484 for (iter = fmt; *iter && len < buf_size; iter++) {
7486 while (*iter && (*iter !=
'%') && (len < buf_size))
7487 buf[len++] = *iter++;
7488 if (!(*iter) || len >= buf_size)
break;
7493 if (*iter ==
'-') flag |= NK_ARG_FLAG_LEFT;
7494 else if (*iter ==
'+') flag |= NK_ARG_FLAG_PLUS;
7495 else if (*iter ==
' ') flag |= NK_ARG_FLAG_SPACE;
7496 else if (*iter ==
'#') flag |= NK_ARG_FLAG_NUM;
7497 else if (*iter ==
'0') flag |= NK_ARG_FLAG_ZERO;
7504 if (*iter >=
'1' && *iter <=
'9') {
7506 width = nk_strtoi(iter, &end);
7510 }
else if (*iter ==
'*') {
7511 width = va_arg(args,
int);
7516 precision = NK_DEFAULT;
7520 precision = va_arg(args,
int);
7524 precision = nk_strtoi(iter, &end);
7533 if (*(iter+1) ==
'h') {
7534 arg_type = NK_ARG_TYPE_CHAR;
7536 }
else arg_type = NK_ARG_TYPE_SHORT;
7538 }
else if (*iter ==
'l') {
7539 arg_type = NK_ARG_TYPE_LONG;
7541 }
else arg_type = NK_ARG_TYPE_DEFAULT;
7545 NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
7546 NK_ASSERT(precision == NK_DEFAULT);
7547 NK_ASSERT(width == NK_DEFAULT);
7550 }
else if (*iter ==
's') {
7552 const char *str = va_arg(args,
const char*);
7553 NK_ASSERT(str != buf &&
"buffer and argument are not allowed to overlap!");
7554 NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
7555 NK_ASSERT(precision == NK_DEFAULT);
7556 NK_ASSERT(width == NK_DEFAULT);
7557 if (str == buf)
return -1;
7558 while (str && *str && len < buf_size)
7559 buf[len++] = *str++;
7560 }
else if (*iter ==
'n') {
7562 signed int *n = va_arg(args,
int*);
7563 NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
7564 NK_ASSERT(precision == NK_DEFAULT);
7565 NK_ASSERT(width == NK_DEFAULT);
7567 }
else if (*iter ==
'c' || *iter ==
'i' || *iter ==
'd') {
7570 const char *num_iter;
7571 int num_len, num_print, padding;
7572 int cur_precision = NK_MAX(precision, 1);
7573 int cur_width = NK_MAX(width, 0);
7576 if (arg_type == NK_ARG_TYPE_CHAR)
7577 value = (
signed char)va_arg(args,
int);
7578 else if (arg_type == NK_ARG_TYPE_SHORT)
7579 value = (
signed short)va_arg(args,
int);
7580 else if (arg_type == NK_ARG_TYPE_LONG)
7581 value = va_arg(args,
signed long);
7582 else if (*iter ==
'c')
7583 value = (
unsigned char)va_arg(args,
int);
7584 else value = va_arg(args,
signed int);
7587 nk_itoa(number_buffer, value);
7588 num_len = nk_strlen(number_buffer);
7589 padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0);
7590 if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE))
7591 padding = NK_MAX(padding-1, 0);
7594 if (!(flag & NK_ARG_FLAG_LEFT)) {
7595 while (padding-- > 0 && (len < buf_size)) {
7596 if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT))
7598 else buf[len++] =
' ';
7603 if ((flag & NK_ARG_FLAG_PLUS) && value >= 0 && len < buf_size)
7605 else if ((flag & NK_ARG_FLAG_SPACE) && value >= 0 && len < buf_size)
7609 num_print = NK_MAX(cur_precision, num_len);
7610 while (precision && (num_print > num_len) && (len < buf_size)) {
7616 num_iter = number_buffer;
7617 while (precision && *num_iter && len < buf_size)
7618 buf[len++] = *num_iter++;
7621 if (flag & NK_ARG_FLAG_LEFT) {
7622 while ((padding-- > 0) && (len < buf_size))
7625 }
else if (*iter ==
'o' || *iter ==
'x' || *iter ==
'X' || *iter ==
'u') {
7627 unsigned long value = 0;
7628 int num_len = 0, num_print, padding = 0;
7629 int cur_precision = NK_MAX(precision, 1);
7630 int cur_width = NK_MAX(width, 0);
7631 unsigned int base = (*iter ==
'o') ? 8: (*iter ==
'u')? 10: 16;
7634 const char *upper_output_format =
"0123456789ABCDEF";
7635 const char *lower_output_format =
"0123456789abcdef";
7636 const char *output_format = (*iter ==
'x') ?
7637 lower_output_format: upper_output_format;
7640 if (arg_type == NK_ARG_TYPE_CHAR)
7641 value = (
unsigned char)va_arg(args,
int);
7642 else if (arg_type == NK_ARG_TYPE_SHORT)
7643 value = (
unsigned short)va_arg(args,
int);
7644 else if (arg_type == NK_ARG_TYPE_LONG)
7645 value = va_arg(args,
unsigned long);
7646 else value = va_arg(args,
unsigned int);
7650 int digit = output_format[value % base];
7651 if (num_len < NK_MAX_NUMBER_BUFFER)
7652 number_buffer[num_len++] = (char)digit;
7654 }
while (value > 0);
7656 num_print = NK_MAX(cur_precision, num_len);
7657 padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0);
7658 if (flag & NK_ARG_FLAG_NUM)
7659 padding = NK_MAX(padding-1, 0);
7662 if (!(flag & NK_ARG_FLAG_LEFT)) {
7663 while ((padding-- > 0) && (len < buf_size)) {
7664 if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT))
7666 else buf[len++] =
' ';
7671 if (num_print && (flag & NK_ARG_FLAG_NUM)) {
7672 if ((*iter ==
'o') && (len < buf_size)) {
7674 }
else if ((*iter ==
'x') && ((len+1) < buf_size)) {
7677 }
else if ((*iter ==
'X') && ((len+1) < buf_size)) {
7682 while (precision && (num_print > num_len) && (len < buf_size)) {
7688 while (num_len > 0) {
7689 if (precision && (len < buf_size))
7690 buf[len++] = number_buffer[num_len-1];
7695 if (flag & NK_ARG_FLAG_LEFT) {
7696 while ((padding-- > 0) && (len < buf_size))
7699 }
else if (*iter ==
'f') {
7701 const char *num_iter;
7702 int cur_precision = (precision < 0) ? 6: precision;
7703 int prefix, cur_width = NK_MAX(width, 0);
7704 double value = va_arg(args,
double);
7705 int num_len = 0, frac_len = 0, dot = 0;
7708 NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
7709 NK_DTOA(number_buffer, value);
7710 num_len = nk_strlen(number_buffer);
7713 num_iter = number_buffer;
7714 while (*num_iter && *num_iter !=
'.')
7717 prefix = (*num_iter ==
'.')?(
int)(num_iter - number_buffer)+1:0;
7718 padding = NK_MAX(cur_width - (prefix + NK_MIN(cur_precision, num_len - prefix)) , 0);
7719 if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE))
7720 padding = NK_MAX(padding-1, 0);
7723 if (!(flag & NK_ARG_FLAG_LEFT)) {
7724 while (padding-- > 0 && (len < buf_size)) {
7725 if (flag & NK_ARG_FLAG_ZERO)
7727 else buf[len++] =
' ';
7732 num_iter = number_buffer;
7733 if ((flag & NK_ARG_FLAG_PLUS) && (value >= 0) && (len < buf_size))
7735 else if ((flag & NK_ARG_FLAG_SPACE) && (value >= 0) && (len < buf_size))
7738 if (dot) frac_len++;
7740 buf[len++] = *num_iter;
7741 if (*num_iter ==
'.') dot = 1;
7742 if (frac_len >= cur_precision)
break;
7747 while (frac_len < cur_precision) {
7748 if (!dot && len < buf_size) {
7758 if (flag & NK_ARG_FLAG_LEFT) {
7759 while ((padding-- > 0) && (len < buf_size))
7764 NK_ASSERT(0 &&
"specifier is not supported!");
7768 buf[(len >= buf_size)?(buf_size-1):len] = 0;
7769 result = (len >= buf_size)?-1:len;
7787 nk_strfmt(
char *buf,
int buf_size,
const char *fmt, va_list args)
7791 NK_ASSERT(buf_size);
7792 if (!buf || !buf_size || !fmt)
return 0;
7793 #ifdef NK_INCLUDE_STANDARD_IO
7794 result = NK_VSNPRINTF(buf, (nk_size)buf_size, fmt, args);
7795 result = (result >= buf_size) ? -1: result;
7796 buf[buf_size-1] = 0;
7798 result = nk_vsnprintf(buf, buf_size, fmt, args);
7816 nk_murmur_hash(
const void * key,
int len, nk_hash seed)
7819 #define NK_ROTL(x,r) ((x) << (r) | ((x) >> (32 - r)))
7823 const nk_byte *data = (
const nk_byte*)key;
7824 const nk_byte *keyptr = data;
7826 const int bsize =
sizeof(k1);
7827 const int nblocks = len/4;
7829 const nk_uint c1 = 0xcc9e2d51;
7830 const nk_uint c2 = 0x1b873593;
7831 const nk_byte *tail;
7836 for (i = 0; i < nblocks; ++i, keyptr += bsize) {
7837 k1ptr = (nk_byte*)&k1;
7838 k1ptr[0] = keyptr[0];
7839 k1ptr[1] = keyptr[1];
7840 k1ptr[2] = keyptr[2];
7841 k1ptr[3] = keyptr[3];
7844 k1 = NK_ROTL(k1,15);
7848 h1 = NK_ROTL(h1,13);
7849 h1 = h1*5+0xe6546b64;
7853 tail = (
const nk_byte*)(data + nblocks*4);
7856 case 3: k1 ^= (nk_uint)(tail[2] << 16);
7857 case 2: k1 ^= (nk_uint)(tail[1] << 8u);
7858 case 1: k1 ^= tail[0];
7860 k1 = NK_ROTL(k1,15);
7879 #ifdef NK_INCLUDE_STANDARD_IO
7893 nk_file_load(
const char* path, nk_size* siz,
const struct nk_allocator *alloc)
7902 if (!path || !siz || !alloc)
7905 fd = fopen(path,
"rb");
7907 fseek(fd, 0, SEEK_END);
7913 *siz = (nk_size)ret;
7914 fseek(fd, 0, SEEK_SET);
7915 buf = (
char*)alloc->alloc(alloc->userdata,0, *siz);
7921 *siz = (nk_size)fread(buf, 1,*siz, fd);
7938 nk_text_clamp(
const struct nk_user_font *font,
const char *text,
7939 int text_len,
float space,
int *glyphs,
float *text_width,
7940 nk_rune *sep_list,
int sep_count)
7944 float last_width = 0;
7945 nk_rune unicode = 0;
7953 float sep_width = 0;
7954 sep_count = NK_MAX(sep_count,0);
7956 glyph_len = nk_utf_decode(text, &unicode, text_len);
7957 while (glyph_len && (width < space) && (len < text_len)) {
7959 s = font->
width(font->userdata, font->
height, text, len);
7960 for (i = 0; i < sep_count; ++i) {
7961 if (unicode != sep_list[i])
continue;
7962 sep_width = last_width = width;
7967 if (i == sep_count){
7968 last_width = sep_width = width;
7972 glyph_len = nk_utf_decode(&text[len], &unicode, text_len - len);
7975 if (len >= text_len) {
7977 *text_width = last_width;
7981 *text_width = sep_width;
7982 return (!sep_len) ? len: sep_len;
7996 nk_text_calculate_text_bounds(const struct
nk_user_font *font,
7997 const char *begin,
int byte_len,
float row_height,
const char **remaining,
7998 struct nk_vec2 *out_offset,
int *glyphs,
int op)
8000 float line_height = row_height;
8002 float line_width = 0.0f;
8006 nk_rune unicode = 0;
8008 if (!begin || byte_len <= 0 || !font)
8011 glyph_len = nk_utf_decode(begin, &unicode, byte_len);
8012 if (!glyph_len)
return text_size;
8013 glyph_width = font->width(font->userdata, font->height, begin, glyph_len);
8016 while ((text_len < byte_len) && glyph_len) {
8017 if (unicode ==
'\n') {
8018 text_size.x = NK_MAX(text_size.x, line_width);
8019 text_size.y += line_height;
8022 if (op == NK_STOP_ON_NEW_LINE)
8026 glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
8030 if (unicode ==
'\r') {
8033 glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
8037 *glyphs = *glyphs + 1;
8038 text_len += glyph_len;
8039 line_width += (float)glyph_width;
8040 glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
8041 glyph_width = font->width(font->userdata, font->height, begin+text_len, glyph_len);
8045 if (text_size.x < line_width)
8046 text_size.x = line_width;
8048 *out_offset =
nk_vec2(line_width, text_size.y + line_height);
8049 if (line_width > 0 || text_size.y == 0.0f)
8050 text_size.y += line_height;
8052 *remaining = begin+text_len;
8077 nk_parse_hex(
const char *p,
int length)
8081 while (len < length) {
8083 if (p[len] >=
'a' && p[len] <=
'f')
8084 i += ((p[len] -
'a') + 10);
8085 else if (p[len] >=
'A' && p[len] <=
'F')
8086 i += ((p[len] -
'A') + 10);
8087 else i += (p[len] -
'0');
8104 nk_rgb_factor(struct
nk_color col, float factor)
8108 col.r = (nk_byte)(col.r * factor);
8109 col.g = (nk_byte)(col.g * factor);
8110 col.b = (nk_byte)(col.b * factor);
8127 nk_rgba(int r, int g, int b, int a)
8130 ret.r = (nk_byte)NK_CLAMP(0, r, 255);
8131 ret.g = (nk_byte)NK_CLAMP(0, g, 255);
8132 ret.b = (nk_byte)NK_CLAMP(0, b, 255);
8133 ret.a = (nk_byte)NK_CLAMP(0, a, 255);
8147 nk_rgb_hex(const char *rgb)
8150 const char *c = rgb;
8152 col.r = (nk_byte)nk_parse_hex(c, 2);
8153 col.g = (nk_byte)nk_parse_hex(c+2, 2);
8154 col.b = (nk_byte)nk_parse_hex(c+4, 2);
8169 nk_rgba_hex(const char *rgb)
8172 const char *c = rgb;
8174 col.r = (nk_byte)nk_parse_hex(c, 2);
8175 col.g = (nk_byte)nk_parse_hex(c+2, 2);
8176 col.b = (nk_byte)nk_parse_hex(c+4, 2);
8177 col.a = (nk_byte)nk_parse_hex(c+6, 2);
8192 nk_color_hex_rgba(
char *output,
struct nk_color col)
8194 #define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i): 'A' - 10 + (i))
8195 output[0] = (char)NK_TO_HEX((col.r & 0xF0) >> 4);
8196 output[1] = (char)NK_TO_HEX((col.r & 0x0F));
8197 output[2] = (char)NK_TO_HEX((col.g & 0xF0) >> 4);
8198 output[3] = (char)NK_TO_HEX((col.g & 0x0F));
8199 output[4] = (char)NK_TO_HEX((col.b & 0xF0) >> 4);
8200 output[5] = (char)NK_TO_HEX((col.b & 0x0F));
8201 output[6] = (char)NK_TO_HEX((col.a & 0xF0) >> 4);
8202 output[7] = (char)NK_TO_HEX((col.a & 0x0F));
8218 nk_color_hex_rgb(
char *output,
struct nk_color col)
8220 #define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i): 'A' - 10 + (i))
8221 output[0] = (char)NK_TO_HEX((col.r & 0xF0) >> 4);
8222 output[1] = (char)NK_TO_HEX((col.r & 0x0F));
8223 output[2] = (char)NK_TO_HEX((col.g & 0xF0) >> 4);
8224 output[3] = (char)NK_TO_HEX((col.g & 0x0F));
8225 output[4] = (char)NK_TO_HEX((col.b & 0xF0) >> 4);
8226 output[5] = (char)NK_TO_HEX((col.b & 0x0F));
8241 nk_rgba_iv(const int *c)
8243 return nk_rgba(c[0], c[1], c[2], c[3]);
8256 nk_rgba_bv(const nk_byte *c)
8258 return nk_rgba(c[0], c[1], c[2], c[3]);
8273 nk_rgb(int r, int g, int b)
8276 ret.r = (nk_byte)NK_CLAMP(0, r, 255);
8277 ret.g = (nk_byte)NK_CLAMP(0, g, 255);
8278 ret.b = (nk_byte)NK_CLAMP(0, b, 255);
8279 ret.a = (nk_byte)255;
8293 nk_rgb_iv(const int *c)
8295 return nk_rgb(c[0], c[1], c[2]);
8308 nk_rgb_bv(const nk_byte* c)
8310 return nk_rgb(c[0], c[1], c[2]);
8323 nk_rgba_u32(nk_uint in)
8326 ret.r = (in & 0xFF);
8327 ret.g = ((in >> 8) & 0xFF);
8328 ret.b = ((in >> 16) & 0xFF);
8329 ret.a = (nk_byte)((in >> 24) & 0xFF);
8346 nk_rgba_f(float r, float g, float b, float a)
8349 ret.r = (nk_byte)(NK_SATURATE(r) * 255.0f);
8350 ret.g = (nk_byte)(NK_SATURATE(g) * 255.0f);
8351 ret.b = (nk_byte)(NK_SATURATE(b) * 255.0f);
8352 ret.a = (nk_byte)(NK_SATURATE(a) * 255.0f);
8366 nk_rgba_fv(const float *c)
8368 return nk_rgba_f(c[0], c[1], c[2], c[3]);
8383 return nk_rgba_f(c.r, c.g, c.b, c.a);
8398 nk_rgb_f(float r, float g, float b)
8401 ret.r = (nk_byte)(NK_SATURATE(r) * 255.0f);
8402 ret.g = (nk_byte)(NK_SATURATE(g) * 255.0f);
8403 ret.b = (nk_byte)(NK_SATURATE(b) * 255.0f);
8418 nk_rgb_fv(const float *c)
8420 return nk_rgb_f(c[0], c[1], c[2]);
8435 return nk_rgb_f(c.r, c.g, c.b);
8450 nk_hsv(int h, int s, int v)
8452 return nk_hsva(h, s, v, 255);
8465 nk_hsv_iv(const int *c)
8467 return nk_hsv(c[0], c[1], c[2]);
8480 nk_hsv_bv(const nk_byte *c)
8482 return nk_hsv(c[0], c[1], c[2]);
8497 nk_hsv_f(float h, float s, float v)
8499 return nk_hsva_f(h, s, v, 1.0f);
8512 nk_hsv_fv(const float *c)
8514 return nk_hsv_f(c[0], c[1], c[2]);
8530 nk_hsva(int h, int s, int v, int a)
8532 float hf = ((float)NK_CLAMP(0, h, 255)) / 255.0f;
8533 float sf = ((float)NK_CLAMP(0, s, 255)) / 255.0f;
8534 float vf = ((float)NK_CLAMP(0, v, 255)) / 255.0f;
8535 float af = ((float)NK_CLAMP(0, a, 255)) / 255.0f;
8536 return nk_hsva_f(hf, sf, vf, af);
8549 nk_hsva_iv(const int *c)
8551 return nk_hsva(c[0], c[1], c[2], c[3]);
8564 nk_hsva_bv(const nk_byte *c)
8566 return nk_hsva(c[0], c[1], c[2], c[3]);
8582 nk_hsva_colorf(float h, float s, float v, float a)
8588 out.r = v; out.g = v; out.b = v; out.a = a;
8591 h = h / (60.0f/360.0f);
8595 q = v * (1.0f - (s * f));
8596 t = v * (1.0f - s * (1.0f - f));
8599 case 0:
default: out.r = v; out.g = t; out.b = p;
break;
8600 case 1: out.r = q; out.g = v; out.b = p;
break;
8601 case 2: out.r = p; out.g = v; out.b = t;
break;
8602 case 3: out.r = p; out.g = q; out.b = v;
break;
8603 case 4: out.r = t; out.g = p; out.b = v;
break;
8604 case 5: out.r = v; out.g = p; out.b = q;
break;}
8619 nk_hsva_colorfv(const float *c)
8621 return nk_hsva_colorf(c[0], c[1], c[2], c[3]);
8637 nk_hsva_f(float h, float s, float v, float a)
8639 struct nk_colorf c = nk_hsva_colorf(h, s, v, a);
8640 return nk_rgba_f(c.r, c.g, c.b, c.a);
8653 nk_hsva_fv(const float *c)
8655 return nk_hsva_f(c[0], c[1], c[2], c[3]);
8670 nk_uint out = (nk_uint)in.r;
8671 out |= ((nk_uint)in.g << 8);
8672 out |= ((nk_uint)in.b << 16);
8673 out |= ((nk_uint)in.a << 24);
8691 nk_color_f(
float *r,
float *g,
float *b,
float *a,
struct nk_color in)
8693 NK_STORAGE
const float s = 1.0f/255.0f;
8694 *r = (float)in.r * s;
8695 *g = (
float)in.g * s;
8696 *b = (float)in.b * s;
8697 *a = (
float)in.a * s;
8711 nk_color_fv(
float *c,
struct nk_color in)
8713 nk_color_f(&c[0], &c[1], &c[2], &c[3], in);
8729 nk_color_f(&o.r, &o.g, &o.b, &o.a, in);
8747 nk_color_d(
double *r,
double *g,
double *b,
double *a,
struct nk_color in)
8749 NK_STORAGE
const double s = 1.0/255.0;
8750 *r = (double)in.r * s;
8751 *g = (
double)in.g * s;
8752 *b = (double)in.b * s;
8753 *a = (
double)in.a * s;
8767 nk_color_dv(
double *c,
struct nk_color in)
8769 nk_color_d(&c[0], &c[1], &c[2], &c[3], in);
8785 nk_color_hsv_f(
float *out_h,
float *out_s,
float *out_v,
struct nk_color in)
8788 nk_color_hsva_f(out_h, out_s, out_v, &a, in);
8802 nk_color_hsv_fv(
float *out,
struct nk_color in)
8805 nk_color_hsva_f(&out[0], &out[1], &out[2], &a, in);
8819 nk_colorf_hsva_f(
float *out_h,
float *out_s,
8820 float *out_v,
float *out_a,
struct nk_colorf in)
8825 const float t = in.g; in.g = in.b; in.b = t;
8829 const float t = in.r; in.r = in.g; in.g = t;
8832 chroma = in.r - ((in.g < in.b) ? in.g: in.b);
8833 *out_h = NK_ABS(K + (in.g - in.b)/(6.0f * chroma + 1e-20f));
8834 *out_s = chroma / (in.r + 1e-20f);
8851 nk_colorf_hsva_fv(
float *hsva,
struct nk_colorf in)
8853 nk_colorf_hsva_f(&hsva[0], &hsva[1], &hsva[2], &hsva[3], in);
8867 nk_color_hsva_f(
float *out_h,
float *out_s,
8868 float *out_v,
float *out_a,
struct nk_color in)
8871 nk_color_f(&col.r,&col.g,&col.b,&col.a, in);
8872 nk_colorf_hsva_f(out_h, out_s, out_v, out_a, col);
8886 nk_color_hsva_fv(
float *out,
struct nk_color in)
8888 nk_color_hsva_f(&out[0], &out[1], &out[2], &out[3], in);
8903 nk_color_hsva_i(
int *out_h,
int *out_s,
int *out_v,
8907 nk_color_hsva_f(&h, &s, &v, &a, in);
8908 *out_h = (nk_byte)(h * 255.0f);
8909 *out_s = (nk_byte)(s * 255.0f);
8910 *out_v = (nk_byte)(v * 255.0f);
8911 *out_a = (nk_byte)(a * 255.0f);
8925 nk_color_hsva_iv(
int *out,
struct nk_color in)
8927 nk_color_hsva_i(&out[0], &out[1], &out[2], &out[3], in);
8941 nk_color_hsva_bv(nk_byte *out,
struct nk_color in)
8944 nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
8945 out[0] = (nk_byte)tmp[0];
8946 out[1] = (nk_byte)tmp[1];
8947 out[2] = (nk_byte)tmp[2];
8948 out[3] = (nk_byte)tmp[3];
8965 nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a,
struct nk_color in)
8968 nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
8969 *h = (nk_byte)tmp[0];
8970 *s = (nk_byte)tmp[1];
8971 *v = (nk_byte)tmp[2];
8972 *a = (nk_byte)tmp[3];
8988 nk_color_hsv_i(
int *out_h,
int *out_s,
int *out_v,
struct nk_color in)
8991 nk_color_hsva_i(out_h, out_s, out_v, &a, in);
9007 nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v,
struct nk_color in)
9010 nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
9011 *out_h = (nk_byte)tmp[0];
9012 *out_s = (nk_byte)tmp[1];
9013 *out_v = (nk_byte)tmp[2];
9027 nk_color_hsv_iv(
int *out,
struct nk_color in)
9029 nk_color_hsv_i(&out[0], &out[1], &out[2], in);
9043 nk_color_hsv_bv(nk_byte *out,
struct nk_color in)
9046 nk_color_hsv_i(&tmp[0], &tmp[1], &tmp[2], in);
9047 out[0] = (nk_byte)tmp[0];
9048 out[1] = (nk_byte)tmp[1];
9049 out[2] = (nk_byte)tmp[2];
9060 NK_GLOBAL
const nk_byte nk_utfbyte[
NK_UTF_SIZE+1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
9061 NK_GLOBAL
const nk_byte nk_utfmask[
NK_UTF_SIZE+1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
9062 NK_GLOBAL
const nk_uint nk_utfmin[
NK_UTF_SIZE+1] = {0, 0, 0x80, 0x800, 0x10000};
9063 NK_GLOBAL
const nk_uint nk_utfmax[
NK_UTF_SIZE+1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
9077 nk_utf_validate(nk_rune *u,
int i)
9081 if (!NK_BETWEEN(*u, nk_utfmin[i], nk_utfmax[i]) ||
9082 NK_BETWEEN(*u, 0xD800, 0xDFFF))
9084 for (i = 1; *u > nk_utfmax[i]; ++i);
9099 nk_utf_decode_byte(
char c,
int *i)
9103 for(*i = 0; *i < (int)NK_LEN(nk_utfmask); ++(*i)) {
9104 if (((nk_byte)c & nk_utfmask[*i]) == nk_utfbyte[*i])
9105 return (nk_byte)(c & ~nk_utfmask[*i]);
9122 nk_utf_decode(
const char *c, nk_rune *u,
int clen)
9124 int i, j, len, type=0;
9130 if (!c || !u)
return 0;
9131 if (!clen)
return 0;
9134 udecoded = nk_utf_decode_byte(c[0], &len);
9138 for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
9139 udecoded = (udecoded << 6) | nk_utf_decode_byte(c[i], &type);
9146 nk_utf_validate(u, len);
9161 nk_utf_encode_byte(nk_rune u,
int i)
9163 return (
char)((nk_utfbyte[i]) | ((nk_byte)u & ~nk_utfmask[i]));
9178 nk_utf_encode(nk_rune u,
char *c,
int clen)
9181 len = nk_utf_validate(&u, 0);
9185 for (i = len - 1; i != 0; --i) {
9186 c[i] = nk_utf_encode_byte(u, 0);
9189 c[0] = nk_utf_encode_byte(u, len);
9204 nk_utf_len(
const char *str,
int len)
9214 if (!str || !len)
return 0;
9218 glyph_len = nk_utf_decode(text, &unicode, text_len);
9219 while (glyph_len && src_len < len) {
9221 src_len = src_len + glyph_len;
9222 glyph_len = nk_utf_decode(text + src_len, &unicode, text_len - src_len);
9239 nk_utf_at(
const char *buffer,
int length,
int index,
9240 nk_rune *unicode,
int *len)
9252 if (!buffer || !unicode || !len)
return 0;
9261 glyph_len = nk_utf_decode(text, unicode, text_len);
9269 src_len = src_len + glyph_len;
9270 glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
9272 if (i != index)
return 0;
9273 return buffer + src_len;
9285 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
9299 nk_malloc(
nk_handle unused,
void *old,nk_size size)
9303 return malloc(size);
9333 nk_buffer_init_default(
struct nk_buffer *buffer)
9336 alloc.userdata.ptr = 0;
9337 alloc.alloc = nk_malloc;
9338 alloc.free = nk_mfree;
9339 nk_buffer_init(buffer, &alloc, NK_BUFFER_DEFAULT_INITIAL_SIZE);
9356 nk_size initial_size)
9360 NK_ASSERT(initial_size);
9361 if (!b || !a || !initial_size)
return;
9363 nk_zero(b,
sizeof(*b));
9364 b->
type = NK_BUFFER_DYNAMIC;
9365 b->
memory.ptr = a->alloc(a->userdata,0, initial_size);
9366 b->
memory.size = initial_size;
9367 b->
size = initial_size;
9384 nk_buffer_init_fixed(
struct nk_buffer *b,
void *m, nk_size size)
9389 if (!b || !m || !size)
return;
9391 nk_zero(b,
sizeof(*b));
9392 b->
type = NK_BUFFER_FIXED;
9408 nk_buffer_align(
void *unaligned,
9409 nk_size align, nk_size *alignment,
9410 enum nk_buffer_allocation_type type)
9416 case NK_BUFFER_FRONT:
9418 memory = NK_ALIGN_PTR(unaligned, align);
9419 *alignment = (nk_size)((nk_byte*)memory - (nk_byte*)unaligned);
9425 case NK_BUFFER_BACK:
9427 memory = NK_ALIGN_PTR_BACK(unaligned, align);
9428 *alignment = (nk_size)((nk_byte*)unaligned - (nk_byte*)memory);
9450 nk_buffer_realloc(
struct nk_buffer *b, nk_size capacity, nk_size *size)
9453 nk_size buffer_size;
9457 if (!b || !size || !b->
pool.alloc || !b->
pool.free)
9460 buffer_size = b->
memory.size;
9463 if (!temp)
return 0;
9466 if (temp != b->
memory.ptr) {
9467 NK_MEMCPY(temp, b->
memory.ptr, buffer_size);
9471 if (b->
size == buffer_size) {
9479 back_size = buffer_size - b->
size;
9480 dst = nk_ptr_add(
void, temp, capacity - back_size);
9481 src = nk_ptr_add(
void, temp, b->
size);
9482 NK_MEMCPY(dst, src, back_size);
9483 b->
size = capacity - back_size;
9499 nk_buffer_alloc(
struct nk_buffer *b,
enum nk_buffer_allocation_type type,
9500 nk_size size, nk_size align)
9509 if (!b || !size)
return 0;
9513 if (type == NK_BUFFER_FRONT)
9515 else unaligned = nk_ptr_add(
void, b->
memory.ptr, b->
size - size);
9516 memory = nk_buffer_align(unaligned, align, &alignment, type);
9519 if (type == NK_BUFFER_FRONT)
9525 if (b->
type != NK_BUFFER_DYNAMIC)
9527 NK_ASSERT(b->
pool.alloc && b->
pool.free);
9528 if (b->
type != NK_BUFFER_DYNAMIC || !b->
pool.alloc || !b->
pool.free)
9533 capacity = NK_MAX(capacity, nk_round_up_pow2((nk_uint)(b->
allocated + size)));
9534 b->
memory.ptr = nk_buffer_realloc(b, capacity, &b->
memory.size);
9535 if (!b->
memory.ptr)
return 0;
9538 if (type == NK_BUFFER_FRONT)
9540 else unaligned = nk_ptr_add(
void, b->
memory.ptr, b->
size - size);
9541 memory = nk_buffer_align(unaligned, align, &alignment, type);
9543 if (type == NK_BUFFER_FRONT)
9545 else b->
size -= (size + alignment);
9562 nk_buffer_push(
struct nk_buffer *b,
enum nk_buffer_allocation_type type,
9563 const void *memory, nk_size size, nk_size align)
9565 void *mem = nk_buffer_alloc(b, type, size, align);
9567 NK_MEMCPY(mem, memory, size);
9581 nk_buffer_mark(
struct nk_buffer *buffer,
enum nk_buffer_allocation_type type)
9584 if (!buffer)
return;
9585 buffer->marker[type].active = nk_true;
9586 if (type == NK_BUFFER_BACK)
9587 buffer->marker[type].offset = buffer->
size;
9588 else buffer->marker[type].offset = buffer->
allocated;
9602 nk_buffer_reset(
struct nk_buffer *buffer,
enum nk_buffer_allocation_type type)
9605 if (!buffer)
return;
9606 if (type == NK_BUFFER_BACK) {
9608 buffer->
needed -= (buffer->
memory.size - buffer->marker[type].offset);
9609 if (buffer->marker[type].active)
9610 buffer->
size = buffer->marker[type].offset;
9612 buffer->marker[type].active = nk_false;
9616 if (buffer->marker[type].active)
9617 buffer->
allocated = buffer->marker[type].offset;
9619 buffer->marker[type].active = nk_false;
9656 if (!b || !b->
memory.ptr)
return;
9657 if (b->
type == NK_BUFFER_FIXED)
return;
9658 if (!b->
pool.free)
return;
9659 NK_ASSERT(b->
pool.free);
9678 if (!s || !b)
return;
9680 s->size = b->
memory.size;
9682 s->memory = b->
memory.ptr;
9683 s->calls = b->
calls;
9696 nk_buffer_memory(
struct nk_buffer *buffer)
9699 if (!buffer)
return 0;
9700 return buffer->
memory.ptr;
9713 nk_buffer_memory_const(
const struct nk_buffer *buffer)
9716 if (!buffer)
return 0;
9717 return buffer->
memory.ptr;
9730 nk_buffer_total(
const struct nk_buffer *buffer)
9733 if (!buffer)
return 0;
9734 return buffer->
memory.size;
9745 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
9757 nk_str_init_default(
struct nk_str *str)
9760 alloc.userdata.ptr = 0;
9761 alloc.alloc = nk_malloc;
9762 alloc.free = nk_mfree;
9763 nk_buffer_init(&str->buffer, &alloc, 32);
9783 nk_buffer_init(&str->buffer, alloc, size);
9799 nk_str_init_fixed(
struct nk_str *str,
void *memory, nk_size size)
9801 nk_buffer_init_fixed(&str->buffer, memory, size);
9817 nk_str_append_text_char(
struct nk_str *s,
const char *str,
int len)
9822 if (!s || !str || !len)
return 0;
9823 mem = (
char*)nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len *
sizeof(char), 0);
9825 NK_MEMCPY(mem, str, (nk_size)len *
sizeof(
char));
9826 s->len += nk_utf_len(str, len);
9841 nk_str_append_str_char(
struct nk_str *s,
const char *str)
9843 return nk_str_append_text_char(s, str, nk_strlen(str));
9858 nk_str_append_text_utf8(
struct nk_str *str,
const char *text,
int len)
9863 if (!str || !text || !len)
return 0;
9864 for (i = 0; i < len; ++i)
9865 byte_len += nk_utf_decode(text+byte_len, &unicode, 4);
9866 nk_str_append_text_char(str, text, byte_len);
9881 nk_str_append_str_utf8(
struct nk_str *str,
const char *text)
9887 if (!str || !text)
return 0;
9889 glyph_len = byte_len = nk_utf_decode(text+byte_len, &unicode, 4);
9890 while (unicode !=
'\0' && glyph_len) {
9891 glyph_len = nk_utf_decode(text+byte_len, &unicode, 4);
9892 byte_len += glyph_len;
9895 nk_str_append_text_char(str, text, byte_len);
9911 nk_str_append_text_runes(
struct nk_str *str,
const nk_rune *text,
int len)
9918 if (!str || !text || !len)
return 0;
9919 for (i = 0; i < len; ++i) {
9920 byte_len = nk_utf_encode(text[i], glyph,
NK_UTF_SIZE);
9921 if (!byte_len)
break;
9922 nk_str_append_text_char(str, glyph, byte_len);
9938 nk_str_append_str_runes(
struct nk_str *str,
const nk_rune *runes)
9944 if (!str || !runes)
return 0;
9945 while (runes[i] !=
'\0') {
9946 byte_len = nk_utf_encode(runes[i], glyph,
NK_UTF_SIZE);
9947 nk_str_append_text_char(str, glyph, byte_len);
9966 nk_str_insert_at_char(
struct nk_str *s,
int pos,
const char *str,
int len)
9976 NK_ASSERT(len >= 0);
9977 if (!s || !str || !len || (nk_size)pos > s->buffer.
allocated)
return 0;
9979 (s->buffer.
type == NK_BUFFER_FIXED))
return 0;
9981 copylen = (int)s->buffer.
allocated - pos;
9983 nk_str_append_text_char(s, str, len);
9986 mem = nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len *
sizeof(
char), 0);
9990 NK_ASSERT(((
int)pos + (
int)len + ((
int)copylen - 1)) >= 0);
9991 NK_ASSERT(((
int)pos + ((
int)copylen - 1)) >= 0);
9992 dst = nk_ptr_add(
char, s->buffer.
memory.ptr, pos + len + (copylen - 1));
9993 src = nk_ptr_add(
char, s->buffer.
memory.ptr, pos + (copylen-1));
9994 for (i = 0; i < copylen; ++i) *dst-- = *src--;
9995 mem = nk_ptr_add(
void, s->buffer.
memory.ptr, pos);
9996 NK_MEMCPY(mem, str, (nk_size)len *
sizeof(
char));
9997 s->len = nk_utf_len((
char *)s->buffer.
memory.ptr, (
int)s->buffer.
allocated);
10014 nk_str_insert_at_rune(
struct nk_str *str,
int pos,
const char *cstr,
int len)
10019 const char *buffer;
10024 if (!str || !cstr || !len)
return 0;
10025 begin = nk_str_at_rune(str, pos, &unicode, &glyph_len);
10027 return nk_str_append_text_char(str, cstr, len);
10028 buffer = nk_str_get_const(str);
10029 if (!begin)
return 0;
10030 return nk_str_insert_at_char(str, (
int)(begin - buffer), cstr, len);
10046 nk_str_insert_text_char(
struct nk_str *str,
int pos,
const char *text,
int len)
10048 return nk_str_insert_text_utf8(str, pos, text, len);
10063 nk_str_insert_str_char(
struct nk_str *str,
int pos,
const char *text)
10065 return nk_str_insert_text_utf8(str, pos, text, nk_strlen(text));
10081 nk_str_insert_text_utf8(
struct nk_str *str,
int pos,
const char *text,
int len)
10089 if (!str || !text || !len)
return 0;
10090 for (i = 0; i < len; ++i)
10091 byte_len += nk_utf_decode(text+byte_len, &unicode, 4);
10092 nk_str_insert_at_rune(str, pos, text, byte_len);
10108 nk_str_insert_str_utf8(
struct nk_str *str,
int pos,
const char *text)
10114 if (!str || !text)
return 0;
10116 glyph_len = byte_len = nk_utf_decode(text+byte_len, &unicode, 4);
10117 while (unicode !=
'\0' && glyph_len) {
10118 glyph_len = nk_utf_decode(text+byte_len, &unicode, 4);
10119 byte_len += glyph_len;
10122 nk_str_insert_at_rune(str, pos, text, byte_len);
10139 nk_str_insert_text_runes(
struct nk_str *str,
int pos,
const nk_rune *runes,
int len)
10146 if (!str || !runes || !len)
return 0;
10147 for (i = 0; i < len; ++i) {
10148 byte_len = nk_utf_encode(runes[i], glyph,
NK_UTF_SIZE);
10149 if (!byte_len)
break;
10150 nk_str_insert_at_rune(str, pos+i, glyph, byte_len);
10167 nk_str_insert_str_runes(
struct nk_str *str,
int pos,
const nk_rune *runes)
10173 if (!str || !runes)
return 0;
10174 while (runes[i] !=
'\0') {
10175 byte_len = nk_utf_encode(runes[i], glyph,
NK_UTF_SIZE);
10176 nk_str_insert_at_rune(str, pos+i, glyph, byte_len);
10193 nk_str_remove_chars(
struct nk_str *s,
int len)
10196 NK_ASSERT(len >= 0);
10197 if (!s || len < 0 || (nk_size)len > s->buffer.
allocated)
return;
10198 NK_ASSERT(((
int)s->buffer.
allocated - (
int)len) >= 0);
10200 s->len = nk_utf_len((
char *)s->buffer.
memory.ptr, (
int)s->buffer.
allocated);
10214 nk_str_remove_runes(
struct nk_str *str,
int len)
10222 NK_ASSERT(len >= 0);
10223 if (!str || len < 0)
return;
10224 if (len >= str->len) {
10229 index = str->len - len;
10230 begin = nk_str_at_rune(str, index, &unicode, &len);
10232 nk_str_remove_chars(str, (
int)(end-begin)+1);
10247 nk_str_delete_chars(
struct nk_str *s,
int pos,
int len)
10250 if (!s || !len || (nk_size)pos > s->buffer.
allocated ||
10251 (nk_size)(pos + len) > s->buffer.
allocated)
return;
10253 if ((nk_size)(pos + len) < s->buffer.
allocated) {
10255 char *dst = nk_ptr_add(
char, s->buffer.
memory.ptr, pos);
10256 char *src = nk_ptr_add(
char, s->buffer.
memory.ptr, pos + len);
10257 NK_MEMCPY(dst, src, s->buffer.
allocated - (nk_size)(pos + len));
10258 NK_ASSERT(((
int)s->buffer.
allocated - (
int)len) >= 0);
10260 }
else nk_str_remove_chars(s, len);
10261 s->len = nk_utf_len((
char *)s->buffer.
memory.ptr, (
int)s->buffer.
allocated);
10276 nk_str_delete_runes(
struct nk_str *s,
int pos,
int len)
10285 NK_ASSERT(s->len >= pos + len);
10286 if (s->len < pos + len)
10287 len = NK_CLAMP(0, (s->len - pos), s->len);
10290 temp = (
char *)s->buffer.
memory.ptr;
10291 begin = nk_str_at_rune(s, pos, &unicode, &unused);
10292 if (!begin)
return;
10293 s->buffer.
memory.ptr = begin;
10294 end = nk_str_at_rune(s, len, &unicode, &unused);
10295 s->buffer.
memory.ptr = temp;
10297 nk_str_delete_chars(s, (
int)(begin - temp), (
int)(end - begin));
10311 nk_str_at_char(
struct nk_str *s,
int pos)
10314 if (!s || pos > (
int)s->buffer.
allocated)
return 0;
10315 return nk_ptr_add(
char, s->buffer.
memory.ptr, pos);
10331 nk_str_at_rune(
struct nk_str *str,
int pos, nk_rune *unicode,
int *len)
10340 NK_ASSERT(unicode);
10343 if (!str || !unicode || !len)
return 0;
10350 text = (
char*)str->buffer.
memory.ptr;
10352 glyph_len = nk_utf_decode(text, unicode, text_len);
10353 while (glyph_len) {
10360 src_len = src_len + glyph_len;
10361 glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
10363 if (i != pos)
return 0;
10364 return text + src_len;
10378 nk_str_at_char_const(
const struct nk_str *s,
int pos)
10381 if (!s || pos > (
int)s->buffer.
allocated)
return 0;
10382 return nk_ptr_add(
char, s->buffer.
memory.ptr, pos);
10398 nk_str_at_const(
const struct nk_str *str,
int pos, nk_rune *unicode,
int *len)
10407 NK_ASSERT(unicode);
10410 if (!str || !unicode || !len)
return 0;
10417 text = (
char*)str->buffer.
memory.ptr;
10419 glyph_len = nk_utf_decode(text, unicode, text_len);
10420 while (glyph_len) {
10427 src_len = src_len + glyph_len;
10428 glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
10430 if (i != pos)
return 0;
10431 return text + src_len;
10445 nk_str_rune_at(
const struct nk_str *str,
int pos)
10448 nk_rune unicode = 0;
10449 nk_str_at_const(str, pos, &unicode, &len);
10463 nk_str_get(
struct nk_str *s)
10466 if (!s || !s->len || !s->buffer.
allocated)
return 0;
10467 return (
char*)s->buffer.
memory.ptr;
10480 nk_str_get_const(
const struct nk_str *s)
10483 if (!s || !s->len || !s->buffer.
allocated)
return 0;
10484 return (
const char*)s->buffer.
memory.ptr;
10497 nk_str_len(
const struct nk_str *s)
10500 if (!s || !s->len || !s->buffer.
allocated)
return 0;
10514 nk_str_len_char(
const struct nk_str *s)
10517 if (!s || !s->len || !s->buffer.
allocated)
return 0;
10531 nk_str_clear(
struct nk_str *str)
10534 nk_buffer_clear(&str->buffer);
10548 nk_str_free(
struct nk_str *str)
10551 nk_buffer_free(&str->buffer);
10575 struct nk_buffer *b,
enum nk_command_clipping clip)
10579 if (!cb || !b)
return;
10581 cb->use_clipping = (int)clip;
10604 b->clip = nk_null_rect;
10605 #ifdef NK_INCLUDE_COMMAND_USERDATA
10606 b->userdata.ptr = 0;
10621 enum nk_command_type t, nk_size size)
10623 NK_STORAGE
const nk_size align = NK_ALIGNOF(
struct nk_command);
10630 NK_ASSERT(b->base);
10632 cmd = (
struct nk_command*)nk_buffer_alloc(b->base,NK_BUFFER_FRONT,size,align);
10633 if (!cmd)
return 0;
10636 b->last = (nk_size)((nk_byte*)cmd - (nk_byte*)b->base->
memory.ptr);
10637 unaligned = (nk_byte*)cmd + size;
10638 memory = NK_ALIGN_PTR(unaligned, align);
10639 alignment = (nk_size)((nk_byte*)memory - (nk_byte*)unaligned);
10640 #ifdef NK_ZERO_COMMAND_MEMORY
10641 NK_MEMSET(cmd, 0, size + alignment);
10645 cmd->next = b->base->
allocated + alignment;
10646 #ifdef NK_INCLUDE_COMMAND_USERDATA
10647 cmd->userdata = b->userdata;
10649 b->end = cmd->next;
10675 nk_command_buffer_push(b, NK_COMMAND_SCISSOR,
sizeof(*cmd));
10678 cmd->x = (short)r.x;
10679 cmd->y = (
short)r.y;
10680 cmd->w = (
unsigned short)NK_MAX(0, r.w);
10681 cmd->h = (
unsigned short)NK_MAX(0, r.h);
10697 float x1,
float y1,
float line_thickness,
struct nk_color c)
10701 if (!b || line_thickness <= 0)
return;
10703 nk_command_buffer_push(b, NK_COMMAND_LINE,
sizeof(*cmd));
10705 cmd->line_thickness = (
unsigned short)line_thickness;
10706 cmd->begin.x = (short)x0;
10707 cmd->begin.y = (short)y0;
10708 cmd->end.x = (short)x1;
10709 cmd->end.y = (short)y1;
10726 float ctrl0x,
float ctrl0y,
float ctrl1x,
float ctrl1y,
10727 float bx,
float by,
float line_thickness,
struct nk_color col)
10731 if (!b || col.a == 0 || line_thickness <= 0)
return;
10734 nk_command_buffer_push(b, NK_COMMAND_CURVE,
sizeof(*cmd));
10736 cmd->line_thickness = (
unsigned short)line_thickness;
10737 cmd->begin.x = (short)ax;
10738 cmd->begin.y = (short)ay;
10739 cmd->ctrl[0].x = (short)ctrl0x;
10740 cmd->ctrl[0].y = (short)ctrl0y;
10741 cmd->ctrl[1].x = (short)ctrl1x;
10742 cmd->ctrl[1].y = (short)ctrl1y;
10743 cmd->end.x = (short)bx;
10744 cmd->end.y = (short)by;
10760 float rounding,
float line_thickness,
struct nk_color c)
10764 if (!b || c.a == 0 || rect.w == 0 || rect.h == 0 || line_thickness <= 0)
return;
10765 if (b->use_clipping) {
10766 const struct nk_rect *clip = &b->clip;
10767 if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
10768 clip->x, clip->y, clip->w, clip->h))
return;
10771 nk_command_buffer_push(b, NK_COMMAND_RECT,
sizeof(*cmd));
10773 cmd->rounding = (
unsigned short)rounding;
10774 cmd->line_thickness = (
unsigned short)line_thickness;
10775 cmd->x = (short)rect.x;
10776 cmd->y = (
short)rect.y;
10777 cmd->w = (
unsigned short)NK_MAX(0, rect.w);
10778 cmd->h = (
unsigned short)NK_MAX(0, rect.h);
10794 float rounding,
struct nk_color c)
10798 if (!b || c.a == 0 || rect.w == 0 || rect.h == 0)
return;
10799 if (b->use_clipping) {
10800 const struct nk_rect *clip = &b->clip;
10801 if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
10802 clip->x, clip->y, clip->w, clip->h))
return;
10806 nk_command_buffer_push(b, NK_COMMAND_RECT_FILLED,
sizeof(*cmd));
10808 cmd->rounding = (
unsigned short)rounding;
10809 cmd->x = (short)rect.x;
10810 cmd->y = (
short)rect.y;
10811 cmd->w = (
unsigned short)NK_MAX(0, rect.w);
10812 cmd->h = (
unsigned short)NK_MAX(0, rect.h);
10833 if (!b || rect.w == 0 || rect.h == 0)
return;
10834 if (b->use_clipping) {
10835 const struct nk_rect *clip = &b->clip;
10836 if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
10837 clip->x, clip->y, clip->w, clip->h))
return;
10841 nk_command_buffer_push(b, NK_COMMAND_RECT_MULTI_COLOR,
sizeof(*cmd));
10843 cmd->x = (short)rect.x;
10844 cmd->y = (
short)rect.y;
10845 cmd->w = (
unsigned short)NK_MAX(0, rect.w);
10846 cmd->h = (
unsigned short)NK_MAX(0, rect.h);
10849 cmd->right = right;
10850 cmd->bottom = bottom;
10865 float line_thickness,
struct nk_color c)
10868 if (!b || r.w == 0 || r.h == 0 || line_thickness <= 0)
return;
10869 if (b->use_clipping) {
10870 const struct nk_rect *clip = &b->clip;
10871 if (!NK_INTERSECT(r.x, r.y, r.w, r.h, clip->x, clip->y, clip->w, clip->h))
10876 nk_command_buffer_push(b, NK_COMMAND_CIRCLE,
sizeof(*cmd));
10878 cmd->line_thickness = (
unsigned short)line_thickness;
10879 cmd->x = (short)r.x;
10880 cmd->y = (
short)r.y;
10881 cmd->w = (
unsigned short)NK_MAX(r.w, 0);
10882 cmd->h = (
unsigned short)NK_MAX(r.h, 0);
10902 if (!b || c.a == 0 || r.w == 0 || r.h == 0)
return;
10903 if (b->use_clipping) {
10904 const struct nk_rect *clip = &b->clip;
10905 if (!NK_INTERSECT(r.x, r.y, r.w, r.h, clip->x, clip->y, clip->w, clip->h))
10910 nk_command_buffer_push(b, NK_COMMAND_CIRCLE_FILLED,
sizeof(*cmd));
10912 cmd->x = (short)r.x;
10913 cmd->y = (
short)r.y;
10914 cmd->w = (
unsigned short)NK_MAX(r.w, 0);
10915 cmd->h = (
unsigned short)NK_MAX(r.h, 0);
10933 float a_min,
float a_max,
float line_thickness,
struct nk_color c)
10936 if (!b || c.a == 0 || line_thickness <= 0)
return;
10938 nk_command_buffer_push(b, NK_COMMAND_ARC,
sizeof(*cmd));
10940 cmd->line_thickness = (
unsigned short)line_thickness;
10941 cmd->cx = (short)cx;
10942 cmd->cy = (short)cy;
10943 cmd->r = (
unsigned short)radius;
10963 float a_min,
float a_max,
struct nk_color c)
10967 if (!b || c.a == 0)
return;
10969 nk_command_buffer_push(b, NK_COMMAND_ARC_FILLED,
sizeof(*cmd));
10971 cmd->cx = (short)cx;
10972 cmd->cy = (short)cy;
10973 cmd->r = (
unsigned short)radius;
10993 float y1,
float x2,
float y2,
float line_thickness,
struct nk_color c)
10997 if (!b || c.a == 0 || line_thickness <= 0)
return;
10998 if (b->use_clipping) {
10999 const struct nk_rect *clip = &b->clip;
11000 if (!NK_INBOX(x0, y0, clip->x, clip->y, clip->w, clip->h) &&
11001 !NK_INBOX(x1, y1, clip->x, clip->y, clip->w, clip->h) &&
11002 !NK_INBOX(x2, y2, clip->x, clip->y, clip->w, clip->h))
11007 nk_command_buffer_push(b, NK_COMMAND_TRIANGLE,
sizeof(*cmd));
11009 cmd->line_thickness = (
unsigned short)line_thickness;
11010 cmd->a.x = (short)x0;
11011 cmd->a.y = (short)y0;
11012 cmd->b.x = (short)x1;
11013 cmd->b.y = (short)y1;
11014 cmd->c.x = (short)x2;
11015 cmd->c.y = (short)y2;
11033 float y1,
float x2,
float y2,
struct nk_color c)
11037 if (!b || c.a == 0)
return;
11039 if (b->use_clipping) {
11040 const struct nk_rect *clip = &b->clip;
11041 if (!NK_INBOX(x0, y0, clip->x, clip->y, clip->w, clip->h) &&
11042 !NK_INBOX(x1, y1, clip->x, clip->y, clip->w, clip->h) &&
11043 !NK_INBOX(x2, y2, clip->x, clip->y, clip->w, clip->h))
11048 nk_command_buffer_push(b, NK_COMMAND_TRIANGLE_FILLED,
sizeof(*cmd));
11050 cmd->a.x = (short)x0;
11051 cmd->a.y = (short)y0;
11052 cmd->b.x = (short)x1;
11053 cmd->b.y = (short)y1;
11054 cmd->c.x = (short)x2;
11055 cmd->c.y = (short)y2;
11071 nk_stroke_polygon(
struct nk_command_buffer *b,
const float *points,
int point_count,
11072 float line_thickness,
struct nk_color col)
11079 if (!b || col.a == 0 || line_thickness <= 0)
return;
11080 size =
sizeof(*cmd) +
sizeof(short) * 2 * (nk_size)point_count;
11081 cmd = (
struct nk_command_polygon*) nk_command_buffer_push(b, NK_COMMAND_POLYGON, size);
11084 cmd->line_thickness = (
unsigned short)line_thickness;
11085 cmd->point_count = (
unsigned short)point_count;
11086 for (i = 0; i < point_count; ++i) {
11087 cmd->points[i].x = (short)points[i*2];
11088 cmd->points[i].y = (short)points[i*2+1];
11104 nk_fill_polygon(
struct nk_command_buffer *b,
const float *points,
int point_count,
11112 if (!b || col.a == 0)
return;
11113 size =
sizeof(*cmd) +
sizeof(short) * 2 * (nk_size)point_count;
11115 nk_command_buffer_push(b, NK_COMMAND_POLYGON_FILLED, size);
11118 cmd->point_count = (
unsigned short)point_count;
11119 for (i = 0; i < point_count; ++i) {
11120 cmd->points[i].x = (short)points[i*2+0];
11121 cmd->points[i].y = (short)points[i*2+1];
11137 nk_stroke_polyline(
struct nk_command_buffer *b,
const float *points,
int point_count,
11138 float line_thickness,
struct nk_color col)
11145 if (!b || col.a == 0 || line_thickness <= 0)
return;
11146 size =
sizeof(*cmd) +
sizeof(short) * 2 * (nk_size)point_count;
11147 cmd = (
struct nk_command_polyline*) nk_command_buffer_push(b, NK_COMMAND_POLYLINE, size);
11150 cmd->point_count = (
unsigned short)point_count;
11151 cmd->line_thickness = (
unsigned short)line_thickness;
11152 for (i = 0; i < point_count; ++i) {
11153 cmd->points[i].x = (short)points[i*2];
11154 cmd->points[i].y = (short)points[i*2+1];
11175 if (b->use_clipping) {
11176 const struct nk_rect *c = &b->clip;
11177 if (c->w == 0 || c->h == 0 || !NK_INTERSECT(r.x, r.y, r.w, r.h, c->x, c->y, c->w, c->h))
11182 nk_command_buffer_push(b, NK_COMMAND_IMAGE,
sizeof(*cmd));
11184 cmd->x = (short)r.x;
11185 cmd->y = (
short)r.y;
11186 cmd->w = (
unsigned short)NK_MAX(0, r.w);
11187 cmd->h = (
unsigned short)NK_MAX(0, r.h);
11208 nk_ushort rgnX, rgnY, rgnW, rgnH;
11209 rgnX = slcimg->region[0];
11210 rgnY = slcimg->region[1];
11211 rgnW = slcimg->region[2];
11212 rgnH = slcimg->region[3];
11215 img.handle = slcimg->handle;
11218 img.region[0] = rgnX;
11219 img.region[1] = rgnY;
11220 img.region[2] = slc->l;
11221 img.region[3] = slc->t;
11224 nk_rect(r.x, r.y, (
float)slc->l, (
float)slc->t),
11227 #define IMG_RGN(x, y, w, h) img.region[0] = (nk_ushort)(x); img.region[1] = (nk_ushort)(y); img.region[2] = (nk_ushort)(w); img.region[3] = (nk_ushort)(h);
11230 IMG_RGN(rgnX + slc->l, rgnY, rgnW - slc->l - slc->r, slc->t);
11232 nk_rect(r.x + (
float)slc->l, r.y, (
float)(r.w - slc->l - slc->r), (
float)slc->t),
11236 IMG_RGN(rgnX + rgnW - slc->r, rgnY, slc->r, slc->t);
11238 nk_rect(r.x + r.w - (
float)slc->r, r.y, (
float)slc->r, (
float)slc->t),
11242 IMG_RGN(rgnX, rgnY + slc->t, slc->l, rgnH - slc->t - slc->b);
11244 nk_rect(r.x, r.y + (
float)slc->t, (
float)slc->l, (
float)(r.h - slc->t - slc->b)),
11248 IMG_RGN(rgnX + slc->l, rgnY + slc->t, rgnW - slc->l - slc->r, rgnH - slc->t - slc->b);
11250 nk_rect(r.x + (
float)slc->l, r.y + (
float)slc->t, (
float)(r.w - slc->l - slc->r), (
float)(r.h - slc->t - slc->b)),
11254 IMG_RGN(rgnX + rgnW - slc->r, rgnY + slc->t, slc->r, rgnH - slc->t - slc->b);
11256 nk_rect(r.x + r.w - (
float)slc->r, r.y + (
float)slc->t, (
float)slc->r, (
float)(r.h - slc->t - slc->b)),
11260 IMG_RGN(rgnX, rgnY + rgnH - slc->b, slc->l, slc->b);
11262 nk_rect(r.x, r.y + r.h - (
float)slc->b, (
float)slc->l, (
float)slc->b),
11266 IMG_RGN(rgnX + slc->l, rgnY + rgnH - slc->b, rgnW - slc->l - slc->r, slc->b);
11268 nk_rect(r.x + (
float)slc->l, r.y + r.h - (
float)slc->b, (
float)(r.w - slc->l - slc->r), (
float)slc->b),
11272 IMG_RGN(rgnX + rgnW - slc->r, rgnY + rgnH - slc->b, slc->r, slc->b);
11274 nk_rect(r.x + r.w - (
float)slc->r, r.y + r.h - (
float)slc->b, (
float)slc->r, (
float)slc->b),
11292 nk_command_custom_callback cb,
nk_handle usr)
11297 if (b->use_clipping) {
11298 const struct nk_rect *c = &b->clip;
11299 if (c->w == 0 || c->h == 0 || !NK_INTERSECT(r.x, r.y, r.w, r.h, c->x, c->y, c->w, c->h))
11304 nk_command_buffer_push(b, NK_COMMAND_CUSTOM,
sizeof(*cmd));
11306 cmd->x = (short)r.x;
11307 cmd->y = (
short)r.y;
11308 cmd->w = (
unsigned short)NK_MAX(0, r.w);
11309 cmd->h = (
unsigned short)NK_MAX(0, r.h);
11310 cmd->callback_data = usr;
11311 cmd->callback = cb;
11326 const char *
string,
int length,
const struct nk_user_font *font,
11329 float text_width = 0;
11334 if (!b || !
string || !length || (bg.a == 0 && fg.a == 0))
return;
11335 if (b->use_clipping) {
11336 const struct nk_rect *c = &b->clip;
11337 if (c->w == 0 || c->h == 0 || !NK_INTERSECT(r.x, r.y, r.w, r.h, c->x, c->y, c->w, c->h))
11342 text_width = font->
width(font->userdata, font->
height,
string, length);
11343 if (text_width > r.w){
11345 float txt_width = (float)text_width;
11346 length = nk_text_clamp(font,
string, length, r.w, &glyphs, &txt_width, 0,0);
11349 if (!length)
return;
11351 nk_command_buffer_push(b, NK_COMMAND_TEXT,
sizeof(*cmd) + (nk_size)(length + 1));
11353 cmd->x = (short)r.x;
11354 cmd->y = (
short)r.y;
11355 cmd->w = (
unsigned short)r.w;
11356 cmd->h = (
unsigned short)r.h;
11357 cmd->background = bg;
11358 cmd->foreground = fg;
11360 cmd->length = length;
11361 cmd->height = font->
height;
11362 NK_MEMCPY(cmd->string,
string, (nk_size)length);
11363 cmd->string[length] =
'\0';
11374 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
11386 nk_draw_list_init(
struct nk_draw_list *list)
11391 nk_zero(list,
sizeof(*list));
11392 for (i = 0; i < NK_LEN(list->circle_vtx); ++i) {
11393 const float a = ((float)i / (
float)NK_LEN(list->circle_vtx)) * 2 * NK_PI;
11394 list->circle_vtx[i].x = (float)NK_COS(a);
11395 list->circle_vtx[i].y = (float)NK_SIN(a);
11410 nk_draw_list_setup(
struct nk_draw_list *canvas,
const struct nk_convert_config *config,
11412 enum nk_anti_aliasing line_aa,
enum nk_anti_aliasing shape_aa)
11417 NK_ASSERT(vertices);
11418 NK_ASSERT(elements);
11419 if (!canvas || !config || !cmds || !vertices || !elements)
11422 canvas->buffer = cmds;
11423 canvas->config = *config;
11424 canvas->elements = elements;
11425 canvas->vertices = vertices;
11426 canvas->line_AA = line_aa;
11427 canvas->shape_AA = shape_aa;
11428 canvas->clip_rect = nk_null_rect;
11430 canvas->cmd_offset = 0;
11431 canvas->element_count = 0;
11432 canvas->vertex_count = 0;
11433 canvas->cmd_offset = 0;
11434 canvas->cmd_count = 0;
11435 canvas->path_count = 0;
11448 NK_API
const struct nk_draw_command*
11449 nk__draw_list_begin(
const struct nk_draw_list *canvas,
const struct nk_buffer *buffer)
11453 const struct nk_draw_command *cmd;
11456 if (!buffer || !buffer->
size || !canvas->cmd_count)
11459 memory = (nk_byte*)buffer->
memory.ptr;
11460 offset = buffer->
memory.size - canvas->cmd_offset;
11461 cmd = nk_ptr_add(
const struct nk_draw_command, memory, offset);
11475 NK_API
const struct nk_draw_command*
11476 nk__draw_list_end(
const struct nk_draw_list *canvas,
const struct nk_buffer *buffer)
11481 const struct nk_draw_command *end;
11485 if (!buffer || !canvas)
11488 memory = (nk_byte*)buffer->
memory.ptr;
11489 size = buffer->
memory.size;
11490 offset = size - canvas->cmd_offset;
11491 end = nk_ptr_add(
const struct nk_draw_command, memory, offset);
11492 end -= (canvas->cmd_count-1);
11505 NK_API
const struct nk_draw_command*
11506 nk__draw_list_next(
const struct nk_draw_command *cmd,
11507 const struct nk_buffer *buffer,
const struct nk_draw_list *canvas)
11509 const struct nk_draw_command *end;
11512 if (!cmd || !buffer || !canvas)
11515 end = nk__draw_list_end(canvas, buffer);
11516 if (cmd <= end)
return 0;
11531 nk_draw_list_alloc_path(
struct nk_draw_list *list,
int count)
11534 NK_STORAGE
const nk_size point_align = NK_ALIGNOF(
struct nk_vec2);
11535 NK_STORAGE
const nk_size point_size =
sizeof(
struct nk_vec2);
11537 nk_buffer_alloc(list->buffer, NK_BUFFER_FRONT,
11538 point_size * (nk_size)count, point_align);
11540 if (!points)
return 0;
11541 if (!list->path_offset) {
11542 void *memory = nk_buffer_memory(list->buffer);
11543 list->path_offset = (
unsigned int)((nk_byte*)points - (nk_byte*)memory);
11545 list->path_count += (
unsigned int)count;
11559 nk_draw_list_path_last(struct nk_draw_list *list)
11563 NK_ASSERT(list->path_count);
11564 memory = nk_buffer_memory(list->buffer);
11565 point = nk_ptr_add(
struct nk_vec2, memory, list->path_offset);
11566 point += (list->path_count-1);
11580 NK_INTERN
struct nk_draw_command*
11581 nk_draw_list_push_command(
struct nk_draw_list *list,
struct nk_rect clip,
11584 NK_STORAGE
const nk_size cmd_align = NK_ALIGNOF(
struct nk_draw_command);
11585 NK_STORAGE
const nk_size cmd_size =
sizeof(
struct nk_draw_command);
11586 struct nk_draw_command *cmd;
11589 cmd = (
struct nk_draw_command*)
11590 nk_buffer_alloc(list->buffer, NK_BUFFER_BACK, cmd_size, cmd_align);
11592 if (!cmd)
return 0;
11593 if (!list->cmd_count) {
11594 nk_byte *memory = (nk_byte*)nk_buffer_memory(list->buffer);
11595 nk_size total = nk_buffer_total(list->buffer);
11596 memory = nk_ptr_add(nk_byte, memory, total);
11597 list->cmd_offset = (nk_size)(memory - (nk_byte*)cmd);
11600 cmd->elem_count = 0;
11601 cmd->clip_rect = clip;
11602 cmd->texture = texture;
11603 #ifdef NK_INCLUDE_COMMAND_USERDATA
11604 cmd->userdata = list->userdata;
11608 list->clip_rect = clip;
11621 NK_INTERN
struct nk_draw_command*
11622 nk_draw_list_command_last(
struct nk_draw_list *list)
11626 struct nk_draw_command *cmd;
11627 NK_ASSERT(list->cmd_count);
11629 memory = nk_buffer_memory(list->buffer);
11630 size = nk_buffer_total(list->buffer);
11631 cmd = nk_ptr_add(
struct nk_draw_command, memory, size - list->cmd_offset);
11632 return (cmd - (list->cmd_count-1));
11646 nk_draw_list_add_clip(
struct nk_draw_list *list,
struct nk_rect rect)
11650 if (!list->cmd_count) {
11651 nk_draw_list_push_command(list, rect, list->config.tex_null.texture);
11653 struct nk_draw_command *prev = nk_draw_list_command_last(list);
11654 if (prev->elem_count == 0)
11655 prev->clip_rect = rect;
11656 nk_draw_list_push_command(list, rect, prev->texture);
11671 nk_draw_list_push_image(
struct nk_draw_list *list,
nk_handle texture)
11675 if (!list->cmd_count) {
11676 nk_draw_list_push_command(list, nk_null_rect, texture);
11678 struct nk_draw_command *prev = nk_draw_list_command_last(list);
11679 if (prev->elem_count == 0) {
11680 prev->texture = texture;
11681 #ifdef NK_INCLUDE_COMMAND_USERDATA
11682 prev->userdata = list->userdata;
11684 }
else if (prev->texture.id != texture.id
11685 #ifdef NK_INCLUDE_COMMAND_USERDATA
11686 || prev->userdata.id != list->userdata.id
11689 nk_draw_list_push_command(list, prev->clip_rect, texture);
11693 #ifdef NK_INCLUDE_COMMAND_USERDATA
11706 nk_draw_list_push_userdata(
struct nk_draw_list *list,
nk_handle userdata)
11708 list->userdata = userdata;
11723 nk_draw_list_alloc_vertices(
struct nk_draw_list *list, nk_size count)
11727 if (!list)
return 0;
11728 vtx = nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT,
11729 list->config.vertex_size*count, list->config.vertex_alignment);
11730 if (!vtx)
return 0;
11731 list->vertex_count += (
unsigned int)count;
11742 if(
sizeof(nk_draw_index)==2) NK_ASSERT((list->vertex_count < NK_USHORT_MAX &&
11743 "To many vertices for 16-bit vertex indices. Please read comment above on how to solve this problem"));
11757 NK_INTERN nk_draw_index*
11758 nk_draw_list_alloc_elements(
struct nk_draw_list *list, nk_size count)
11760 nk_draw_index *ids;
11761 struct nk_draw_command *cmd;
11762 NK_STORAGE
const nk_size elem_align = NK_ALIGNOF(nk_draw_index);
11763 NK_STORAGE
const nk_size elem_size =
sizeof(nk_draw_index);
11765 if (!list)
return 0;
11767 ids = (nk_draw_index*)
11768 nk_buffer_alloc(list->elements, NK_BUFFER_FRONT, elem_size*count, elem_align);
11769 if (!ids)
return 0;
11770 cmd = nk_draw_list_command_last(list);
11771 list->element_count += (
unsigned int)count;
11772 cmd->elem_count += (
unsigned int)count;
11785 nk_draw_vertex_layout_element_is_end_of_layout(
11786 const struct nk_draw_vertex_layout_element *element)
11788 return (element->attribute == NK_VERTEX_ATTRIBUTE_COUNT ||
11789 element->format == NK_FORMAT_COUNT);
11803 nk_draw_vertex_color(
void *attr,
const float *vals,
11804 enum nk_draw_vertex_layout_format format)
11808 NK_ASSERT(format >= NK_FORMAT_COLOR_BEGIN);
11809 NK_ASSERT(format <= NK_FORMAT_COLOR_END);
11810 if (format < NK_FORMAT_COLOR_BEGIN || format > NK_FORMAT_COLOR_END)
return;
11812 val[0] = NK_SATURATE(vals[0]);
11813 val[1] = NK_SATURATE(vals[1]);
11814 val[2] = NK_SATURATE(vals[2]);
11815 val[3] = NK_SATURATE(vals[3]);
11818 default: NK_ASSERT(0 &&
"Invalid vertex layout color format");
break;
11819 case NK_FORMAT_R8G8B8A8:
11820 case NK_FORMAT_R8G8B8: {
11821 struct nk_color col = nk_rgba_fv(val);
11822 NK_MEMCPY(attr, &col.r,
sizeof(col));
11824 case NK_FORMAT_B8G8R8A8: {
11825 struct nk_color col = nk_rgba_fv(val);
11826 struct nk_color bgra = nk_rgba(col.b, col.g, col.r, col.a);
11827 NK_MEMCPY(attr, &bgra,
sizeof(bgra));
11829 case NK_FORMAT_R16G15B16: {
11831 col[0] = (nk_ushort)(val[0]*(
float)NK_USHORT_MAX);
11832 col[1] = (nk_ushort)(val[1]*(
float)NK_USHORT_MAX);
11833 col[2] = (nk_ushort)(val[2]*(
float)NK_USHORT_MAX);
11834 NK_MEMCPY(attr, col,
sizeof(col));
11836 case NK_FORMAT_R16G15B16A16: {
11838 col[0] = (nk_ushort)(val[0]*(
float)NK_USHORT_MAX);
11839 col[1] = (nk_ushort)(val[1]*(
float)NK_USHORT_MAX);
11840 col[2] = (nk_ushort)(val[2]*(
float)NK_USHORT_MAX);
11841 col[3] = (nk_ushort)(val[3]*(
float)NK_USHORT_MAX);
11842 NK_MEMCPY(attr, col,
sizeof(col));
11844 case NK_FORMAT_R32G32B32: {
11846 col[0] = (nk_uint)(val[0]*(
float)NK_UINT_MAX);
11847 col[1] = (nk_uint)(val[1]*(
float)NK_UINT_MAX);
11848 col[2] = (nk_uint)(val[2]*(
float)NK_UINT_MAX);
11849 NK_MEMCPY(attr, col,
sizeof(col));
11851 case NK_FORMAT_R32G32B32A32: {
11853 col[0] = (nk_uint)(val[0]*(
float)NK_UINT_MAX);
11854 col[1] = (nk_uint)(val[1]*(
float)NK_UINT_MAX);
11855 col[2] = (nk_uint)(val[2]*(
float)NK_UINT_MAX);
11856 col[3] = (nk_uint)(val[3]*(
float)NK_UINT_MAX);
11857 NK_MEMCPY(attr, col,
sizeof(col));
11859 case NK_FORMAT_R32G32B32A32_FLOAT:
11860 NK_MEMCPY(attr, val,
sizeof(
float)*4);
11862 case NK_FORMAT_R32G32B32A32_DOUBLE: {
11864 col[0] = (double)val[0];
11865 col[1] = (double)val[1];
11866 col[2] = (double)val[2];
11867 col[3] = (double)val[3];
11868 NK_MEMCPY(attr, col,
sizeof(col));
11870 case NK_FORMAT_RGB32:
11871 case NK_FORMAT_RGBA32: {
11872 struct nk_color col = nk_rgba_fv(val);
11873 nk_uint color = nk_color_u32(col);
11874 NK_MEMCPY(attr, &color,
sizeof(color));
11890 nk_draw_vertex_element(
void *dst,
const float *values,
int value_count,
11891 enum nk_draw_vertex_layout_format format)
11894 void *attribute = dst;
11896 NK_ASSERT(format < NK_FORMAT_COLOR_BEGIN);
11897 if (format >= NK_FORMAT_COLOR_BEGIN && format <= NK_FORMAT_COLOR_END)
return;
11898 for (value_index = 0; value_index < value_count; ++value_index) {
11900 default: NK_ASSERT(0 &&
"invalid vertex layout format");
break;
11901 case NK_FORMAT_SCHAR: {
11902 char value = (char)NK_CLAMP((
float)NK_SCHAR_MIN, values[value_index], (float)NK_SCHAR_MAX);
11903 NK_MEMCPY(attribute, &value,
sizeof(value));
11904 attribute = (
void*)((
char*)attribute +
sizeof(char));
11906 case NK_FORMAT_SSHORT: {
11907 nk_short value = (nk_short)NK_CLAMP((
float)NK_SSHORT_MIN, values[value_index], (float)NK_SSHORT_MAX);
11908 NK_MEMCPY(attribute, &value,
sizeof(value));
11909 attribute = (
void*)((
char*)attribute +
sizeof(value));
11911 case NK_FORMAT_SINT: {
11912 nk_int value = (nk_int)NK_CLAMP((
float)NK_SINT_MIN, values[value_index], (float)NK_SINT_MAX);
11913 NK_MEMCPY(attribute, &value,
sizeof(value));
11914 attribute = (
void*)((
char*)attribute +
sizeof(nk_int));
11916 case NK_FORMAT_UCHAR: {
11917 unsigned char value = (
unsigned char)NK_CLAMP((
float)NK_UCHAR_MIN, values[value_index], (float)NK_UCHAR_MAX);
11918 NK_MEMCPY(attribute, &value,
sizeof(value));
11919 attribute = (
void*)((
char*)attribute +
sizeof(
unsigned char));
11921 case NK_FORMAT_USHORT: {
11922 nk_ushort value = (nk_ushort)NK_CLAMP((
float)NK_USHORT_MIN, values[value_index], (float)NK_USHORT_MAX);
11923 NK_MEMCPY(attribute, &value,
sizeof(value));
11924 attribute = (
void*)((
char*)attribute +
sizeof(value));
11926 case NK_FORMAT_UINT: {
11927 nk_uint value = (nk_uint)NK_CLAMP((
float)NK_UINT_MIN, values[value_index], (float)NK_UINT_MAX);
11928 NK_MEMCPY(attribute, &value,
sizeof(value));
11929 attribute = (
void*)((
char*)attribute +
sizeof(nk_uint));
11931 case NK_FORMAT_FLOAT:
11932 NK_MEMCPY(attribute, &values[value_index],
sizeof(values[value_index]));
11933 attribute = (
void*)((
char*)attribute +
sizeof(float));
11935 case NK_FORMAT_DOUBLE: {
11936 double value = (double)values[value_index];
11937 NK_MEMCPY(attribute, &value,
sizeof(value));
11938 attribute = (
void*)((
char*)attribute +
sizeof(double));
11958 void *result = (
void*)((
char*)dst + config->
vertex_size);
11959 const struct nk_draw_vertex_layout_element *elem_iter = config->
vertex_layout;
11960 while (!nk_draw_vertex_layout_element_is_end_of_layout(elem_iter)) {
11961 void *address = (
void*)((
char*)dst + elem_iter->offset);
11962 switch (elem_iter->attribute) {
11963 case NK_VERTEX_ATTRIBUTE_COUNT:
11964 default: NK_ASSERT(0 &&
"wrong element attribute");
break;
11965 case NK_VERTEX_POSITION: nk_draw_vertex_element(address, &pos.x, 2, elem_iter->format);
break;
11966 case NK_VERTEX_TEXCOORD: nk_draw_vertex_element(address, &uv.x, 2, elem_iter->format);
break;
11967 case NK_VERTEX_COLOR: nk_draw_vertex_color(address, &color.r, elem_iter->format);
break;
11985 nk_draw_list_stroke_poly_line(
struct nk_draw_list *list,
const struct nk_vec2 *points,
11986 const unsigned int points_count,
struct nk_color color,
enum nk_draw_list_stroke closed,
11987 float thickness,
enum nk_anti_aliasing aliasing)
11994 if (!list || points_count < 2)
return;
11996 color.a = (nk_byte)((
float)color.a * list->config.global_alpha);
11997 count = points_count;
11998 if (!closed) count = points_count-1;
11999 thick_line = thickness > 1.0f;
12001 #ifdef NK_INCLUDE_COMMAND_USERDATA
12002 nk_draw_list_push_userdata(list, list->userdata);
12005 color.a = (nk_byte)((
float)color.a * list->config.global_alpha);
12006 nk_color_fv(&col.r, color);
12010 if (aliasing == NK_ANTI_ALIASING_ON) {
12012 const float AA_SIZE = 1.0f;
12013 NK_STORAGE
const nk_size pnt_align = NK_ALIGNOF(
struct nk_vec2);
12014 NK_STORAGE
const nk_size pnt_size =
sizeof(
struct nk_vec2);
12018 nk_size vertex_offset;
12019 nk_size index = list->vertex_count;
12021 const nk_size idx_count = (thick_line) ? (count * 18) : (count * 12);
12022 const nk_size vtx_count = (thick_line) ? (points_count * 4): (points_count *3);
12024 void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
12025 nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
12028 struct nk_vec2 *normals, *temp;
12029 if (!vtx || !ids)
return;
12032 vertex_offset = (nk_size)((nk_byte*)vtx - (nk_byte*)list->vertices->memory.ptr);
12033 nk_buffer_mark(list->vertices, NK_BUFFER_FRONT);
12034 size = pnt_size * ((thick_line) ? 5 : 3) * points_count;
12035 normals = (
struct nk_vec2*) nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, size, pnt_align);
12036 if (!normals)
return;
12037 temp = normals + points_count;
12040 vtx = (
void*)((nk_byte*)list->vertices->memory.ptr + vertex_offset);
12043 for (i1 = 0; i1 < count; ++i1) {
12044 const nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1);
12045 struct nk_vec2 diff = nk_vec2_sub(points[i2], points[i1]);
12049 len = nk_vec2_len_sqr(diff);
12051 len = NK_INV_SQRT(len);
12054 diff = nk_vec2_muls(diff, len);
12055 normals[i1].x = diff.y;
12056 normals[i1].y = -diff.x;
12060 normals[points_count-1] = normals[points_count-2];
12066 temp[0] = nk_vec2_add(points[0], nk_vec2_muls(normals[0], AA_SIZE));
12067 temp[1] = nk_vec2_sub(points[0], nk_vec2_muls(normals[0], AA_SIZE));
12068 d = nk_vec2_muls(normals[points_count-1], AA_SIZE);
12069 temp[(points_count-1) * 2 + 0] = nk_vec2_add(points[points_count-1], d);
12070 temp[(points_count-1) * 2 + 1] = nk_vec2_sub(points[points_count-1], d);
12075 for (i1 = 0; i1 < count; i1++) {
12078 nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1);
12079 nk_size idx2 = ((i1+1) == points_count) ? index: (idx1 + 3);
12082 dm = nk_vec2_muls(nk_vec2_add(normals[i1], normals[i2]), 0.5f);
12083 dmr2 = dm.x * dm.x + dm.y* dm.y;
12084 if (dmr2 > 0.000001f) {
12085 float scale = 1.0f/dmr2;
12086 scale = NK_MIN(100.0f, scale);
12087 dm = nk_vec2_muls(dm, scale);
12090 dm = nk_vec2_muls(dm, AA_SIZE);
12091 temp[i2*2+0] = nk_vec2_add(points[i2], dm);
12092 temp[i2*2+1] = nk_vec2_sub(points[i2], dm);
12094 ids[0] = (nk_draw_index)(idx2 + 0); ids[1] = (nk_draw_index)(idx1+0);
12095 ids[2] = (nk_draw_index)(idx1 + 2); ids[3] = (nk_draw_index)(idx1+2);
12096 ids[4] = (nk_draw_index)(idx2 + 2); ids[5] = (nk_draw_index)(idx2+0);
12097 ids[6] = (nk_draw_index)(idx2 + 1); ids[7] = (nk_draw_index)(idx1+1);
12098 ids[8] = (nk_draw_index)(idx1 + 0); ids[9] = (nk_draw_index)(idx1+0);
12099 ids[10]= (nk_draw_index)(idx2 + 0); ids[11]= (nk_draw_index)(idx2+1);
12105 for (i = 0; i < points_count; ++i) {
12106 const struct nk_vec2 uv = list->config.tex_null.uv;
12107 vtx = nk_draw_vertex(vtx, &list->config, points[i], uv, col);
12108 vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+0], uv, col_trans);
12109 vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+1], uv, col_trans);
12113 const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f;
12115 struct nk_vec2 d1 = nk_vec2_muls(normals[0], half_inner_thickness + AA_SIZE);
12116 struct nk_vec2 d2 = nk_vec2_muls(normals[0], half_inner_thickness);
12118 temp[0] = nk_vec2_add(points[0], d1);
12119 temp[1] = nk_vec2_add(points[0], d2);
12120 temp[2] = nk_vec2_sub(points[0], d2);
12121 temp[3] = nk_vec2_sub(points[0], d1);
12123 d1 = nk_vec2_muls(normals[points_count-1], half_inner_thickness + AA_SIZE);
12124 d2 = nk_vec2_muls(normals[points_count-1], half_inner_thickness);
12126 temp[(points_count-1)*4+0] = nk_vec2_add(points[points_count-1], d1);
12127 temp[(points_count-1)*4+1] = nk_vec2_add(points[points_count-1], d2);
12128 temp[(points_count-1)*4+2] = nk_vec2_sub(points[points_count-1], d2);
12129 temp[(points_count-1)*4+3] = nk_vec2_sub(points[points_count-1], d1);
12134 for (i1 = 0; i1 < count; ++i1) {
12135 struct nk_vec2 dm_out, dm_in;
12136 const nk_size i2 = ((i1+1) == points_count) ? 0: (i1 + 1);
12137 nk_size idx2 = ((i1+1) == points_count) ? index: (idx1 + 4);
12140 struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(normals[i1], normals[i2]), 0.5f);
12141 float dmr2 = dm.x * dm.x + dm.y* dm.y;
12142 if (dmr2 > 0.000001f) {
12143 float scale = 1.0f/dmr2;
12144 scale = NK_MIN(100.0f, scale);
12145 dm = nk_vec2_muls(dm, scale);
12148 dm_out = nk_vec2_muls(dm, ((half_inner_thickness) + AA_SIZE));
12149 dm_in = nk_vec2_muls(dm, half_inner_thickness);
12150 temp[i2*4+0] = nk_vec2_add(points[i2], dm_out);
12151 temp[i2*4+1] = nk_vec2_add(points[i2], dm_in);
12152 temp[i2*4+2] = nk_vec2_sub(points[i2], dm_in);
12153 temp[i2*4+3] = nk_vec2_sub(points[i2], dm_out);
12156 ids[0] = (nk_draw_index)(idx2 + 1); ids[1] = (nk_draw_index)(idx1+1);
12157 ids[2] = (nk_draw_index)(idx1 + 2); ids[3] = (nk_draw_index)(idx1+2);
12158 ids[4] = (nk_draw_index)(idx2 + 2); ids[5] = (nk_draw_index)(idx2+1);
12159 ids[6] = (nk_draw_index)(idx2 + 1); ids[7] = (nk_draw_index)(idx1+1);
12160 ids[8] = (nk_draw_index)(idx1 + 0); ids[9] = (nk_draw_index)(idx1+0);
12161 ids[10]= (nk_draw_index)(idx2 + 0); ids[11] = (nk_draw_index)(idx2+1);
12162 ids[12]= (nk_draw_index)(idx2 + 2); ids[13] = (nk_draw_index)(idx1+2);
12163 ids[14]= (nk_draw_index)(idx1 + 3); ids[15] = (nk_draw_index)(idx1+3);
12164 ids[16]= (nk_draw_index)(idx2 + 3); ids[17] = (nk_draw_index)(idx2+2);
12170 for (i = 0; i < points_count; ++i) {
12171 const struct nk_vec2 uv = list->config.tex_null.uv;
12172 vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+0], uv, col_trans);
12173 vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+1], uv, col);
12174 vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+2], uv, col);
12175 vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+3], uv, col_trans);
12179 nk_buffer_reset(list->vertices, NK_BUFFER_FRONT);
12183 nk_size idx = list->vertex_count;
12184 const nk_size idx_count = count * 6;
12185 const nk_size vtx_count = count * 4;
12186 void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
12187 nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
12188 if (!vtx || !ids)
return;
12190 for (i1 = 0; i1 < count; ++i1) {
12192 const struct nk_vec2 uv = list->config.tex_null.uv;
12193 const nk_size i2 = ((i1+1) == points_count) ? 0 : i1 + 1;
12194 const struct nk_vec2 p1 = points[i1];
12195 const struct nk_vec2 p2 = points[i2];
12196 struct nk_vec2 diff = nk_vec2_sub(p2, p1);
12200 len = nk_vec2_len_sqr(diff);
12202 len = NK_INV_SQRT(len);
12204 diff = nk_vec2_muls(diff, len);
12207 dx = diff.x * (thickness * 0.5f);
12208 dy = diff.y * (thickness * 0.5f);
12210 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(p1.x + dy, p1.y - dx), uv, col);
12211 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(p2.x + dy, p2.y - dx), uv, col);
12212 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(p2.x - dy, p2.y + dx), uv, col);
12213 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(p1.x - dy, p1.y + dx), uv, col);
12215 ids[0] = (nk_draw_index)(idx+0); ids[1] = (nk_draw_index)(idx+1);
12216 ids[2] = (nk_draw_index)(idx+2); ids[3] = (nk_draw_index)(idx+0);
12217 ids[4] = (nk_draw_index)(idx+2); ids[5] = (nk_draw_index)(idx+3);
12235 nk_draw_list_fill_poly_convex(
struct nk_draw_list *list,
12236 const struct nk_vec2 *points,
const unsigned int points_count,
12237 struct nk_color color,
enum nk_anti_aliasing aliasing)
12242 NK_STORAGE
const nk_size pnt_align = NK_ALIGNOF(
struct nk_vec2);
12243 NK_STORAGE
const nk_size pnt_size =
sizeof(
struct nk_vec2);
12245 if (!list || points_count < 3)
return;
12247 #ifdef NK_INCLUDE_COMMAND_USERDATA
12248 nk_draw_list_push_userdata(list, list->userdata);
12251 color.a = (nk_byte)((
float)color.a * list->config.global_alpha);
12252 nk_color_fv(&col.r, color);
12256 if (aliasing == NK_ANTI_ALIASING_ON) {
12261 const float AA_SIZE = 1.0f;
12262 nk_size vertex_offset = 0;
12263 nk_size index = list->vertex_count;
12265 const nk_size idx_count = (points_count-2)*3 + points_count*6;
12266 const nk_size vtx_count = (points_count*2);
12268 void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
12269 nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
12273 unsigned int vtx_inner_idx = (
unsigned int)(index + 0);
12274 unsigned int vtx_outer_idx = (
unsigned int)(index + 1);
12275 if (!vtx || !ids)
return;
12278 vertex_offset = (nk_size)((nk_byte*)vtx - (nk_byte*)list->vertices->memory.ptr);
12279 nk_buffer_mark(list->vertices, NK_BUFFER_FRONT);
12280 size = pnt_size * points_count;
12281 normals = (
struct nk_vec2*) nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, size, pnt_align);
12282 if (!normals)
return;
12283 vtx = (
void*)((nk_byte*)list->vertices->memory.ptr + vertex_offset);
12286 for (i = 2; i < points_count; i++) {
12287 ids[0] = (nk_draw_index)(vtx_inner_idx);
12288 ids[1] = (nk_draw_index)(vtx_inner_idx + ((i-1) << 1));
12289 ids[2] = (nk_draw_index)(vtx_inner_idx + (i << 1));
12294 for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) {
12295 struct nk_vec2 p0 = points[i0];
12296 struct nk_vec2 p1 = points[i1];
12297 struct nk_vec2 diff = nk_vec2_sub(p1, p0);
12300 float len = nk_vec2_len_sqr(diff);
12302 len = NK_INV_SQRT(len);
12304 diff = nk_vec2_muls(diff, len);
12306 normals[i0].x = diff.y;
12307 normals[i0].y = -diff.x;
12311 for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) {
12312 const struct nk_vec2 uv = list->config.tex_null.uv;
12313 struct nk_vec2 n0 = normals[i0];
12314 struct nk_vec2 n1 = normals[i1];
12315 struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(n0, n1), 0.5f);
12316 float dmr2 = dm.x*dm.x + dm.y*dm.y;
12317 if (dmr2 > 0.000001f) {
12318 float scale = 1.0f / dmr2;
12319 scale = NK_MIN(scale, 100.0f);
12320 dm = nk_vec2_muls(dm, scale);
12322 dm = nk_vec2_muls(dm, AA_SIZE * 0.5f);
12325 vtx = nk_draw_vertex(vtx, &list->config, nk_vec2_sub(points[i1], dm), uv, col);
12326 vtx = nk_draw_vertex(vtx, &list->config, nk_vec2_add(points[i1], dm), uv, col_trans);
12329 ids[0] = (nk_draw_index)(vtx_inner_idx+(i1<<1));
12330 ids[1] = (nk_draw_index)(vtx_inner_idx+(i0<<1));
12331 ids[2] = (nk_draw_index)(vtx_outer_idx+(i0<<1));
12332 ids[3] = (nk_draw_index)(vtx_outer_idx+(i0<<1));
12333 ids[4] = (nk_draw_index)(vtx_outer_idx+(i1<<1));
12334 ids[5] = (nk_draw_index)(vtx_inner_idx+(i1<<1));
12338 nk_buffer_reset(list->vertices, NK_BUFFER_FRONT);
12341 nk_size index = list->vertex_count;
12342 const nk_size idx_count = (points_count-2)*3;
12343 const nk_size vtx_count = points_count;
12344 void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
12345 nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
12347 if (!vtx || !ids)
return;
12348 for (i = 0; i < vtx_count; ++i)
12349 vtx = nk_draw_vertex(vtx, &list->config, points[i], list->config.tex_null.uv, col);
12350 for (i = 2; i < points_count; ++i) {
12351 ids[0] = (nk_draw_index)index;
12352 ids[1] = (nk_draw_index)(index+ i - 1);
12353 ids[2] = (nk_draw_index)(index+i);
12369 nk_draw_list_path_clear(
struct nk_draw_list *list)
12373 nk_buffer_reset(list->buffer, NK_BUFFER_FRONT);
12374 list->path_count = 0;
12375 list->path_offset = 0;
12389 nk_draw_list_path_line_to(
struct nk_draw_list *list,
struct nk_vec2 pos)
12392 struct nk_draw_command *cmd = 0;
12395 if (!list->cmd_count)
12396 nk_draw_list_add_clip(list, nk_null_rect);
12398 cmd = nk_draw_list_command_last(list);
12399 if (cmd && cmd->texture.ptr != list->config.tex_null.texture.ptr)
12400 nk_draw_list_push_image(list, list->config.tex_null.texture);
12402 points = nk_draw_list_alloc_path(list, 1);
12403 if (!points)
return;
12418 nk_draw_list_path_arc_to_fast(
struct nk_draw_list *list,
struct nk_vec2 center,
12419 float radius,
int a_min,
int a_max)
12424 if (a_min <= a_max) {
12425 for (a = a_min; a <= a_max; a++) {
12426 const struct nk_vec2 c = list->circle_vtx[(nk_size)a % NK_LEN(list->circle_vtx)];
12427 const float x = center.x + c.x * radius;
12428 const float y = center.y + c.y * radius;
12429 nk_draw_list_path_line_to(list,
nk_vec2(x, y));
12445 nk_draw_list_path_arc_to(
struct nk_draw_list *list,
struct nk_vec2 center,
12446 float radius,
float a_min,
float a_max,
unsigned int segments)
12448 unsigned int i = 0;
12451 if (radius == 0.0f)
return;
12471 {
const float d_angle = (a_max - a_min) / (
float)segments;
12472 const float sin_d = (float)NK_SIN(d_angle);
12473 const float cos_d = (float)NK_COS(d_angle);
12475 float cx = (float)NK_COS(a_min) * radius;
12476 float cy = (float)NK_SIN(a_min) * radius;
12477 for(i = 0; i <= segments; ++i) {
12478 float new_cx, new_cy;
12479 const float x = center.x + cx;
12480 const float y = center.y + cy;
12481 nk_draw_list_path_line_to(list,
nk_vec2(x, y));
12483 new_cx = cx * cos_d - cy * sin_d;
12484 new_cy = cy * cos_d + cx * sin_d;
12501 nk_draw_list_path_rect_to(
struct nk_draw_list *list,
struct nk_vec2 a,
12502 struct nk_vec2 b,
float rounding)
12508 r = NK_MIN(r, ((b.x-a.x) < 0) ? -(b.x-a.x): (b.x-a.x));
12509 r = NK_MIN(r, ((b.y-a.y) < 0) ? -(b.y-a.y): (b.y-a.y));
12512 nk_draw_list_path_line_to(list, a);
12513 nk_draw_list_path_line_to(list,
nk_vec2(b.x,a.y));
12514 nk_draw_list_path_line_to(list, b);
12515 nk_draw_list_path_line_to(list,
nk_vec2(a.x,b.y));
12517 nk_draw_list_path_arc_to_fast(list,
nk_vec2(a.x + r, a.y + r), r, 6, 9);
12518 nk_draw_list_path_arc_to_fast(list,
nk_vec2(b.x - r, a.y + r), r, 9, 12);
12519 nk_draw_list_path_arc_to_fast(list,
nk_vec2(b.x - r, b.y - r), r, 0, 3);
12520 nk_draw_list_path_arc_to_fast(list,
nk_vec2(a.x + r, b.y - r), r, 3, 6);
12535 nk_draw_list_path_curve_to(
struct nk_draw_list *list,
struct nk_vec2 p2,
12536 struct nk_vec2 p3,
struct nk_vec2 p4,
unsigned int num_segments)
12539 unsigned int i_step;
12543 NK_ASSERT(list->path_count);
12544 if (!list || !list->path_count)
return;
12545 num_segments = NK_MAX(num_segments, 1);
12547 p1 = nk_draw_list_path_last(list);
12548 t_step = 1.0f/(float)num_segments;
12549 for (i_step = 1; i_step <= num_segments; ++i_step) {
12550 float t = t_step * (float)i_step;
12551 float u = 1.0f - t;
12553 float w2 = 3*u*u*t;
12554 float w3 = 3*u*t*t;
12555 float w4 = t * t *t;
12556 float x = w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x;
12557 float y = w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y;
12558 nk_draw_list_path_line_to(list,
nk_vec2(x,y));
12573 nk_draw_list_path_fill(
struct nk_draw_list *list,
struct nk_color color)
12578 points = (
struct nk_vec2*)nk_buffer_memory(list->buffer);
12579 nk_draw_list_fill_poly_convex(list, points, list->path_count, color, list->config.shape_AA);
12580 nk_draw_list_path_clear(list);
12594 nk_draw_list_path_stroke(
struct nk_draw_list *list,
struct nk_color color,
12595 enum nk_draw_list_stroke closed,
float thickness)
12600 points = (
struct nk_vec2*)nk_buffer_memory(list->buffer);
12601 nk_draw_list_stroke_poly_line(list, points, list->path_count, color,
12602 closed, thickness, list->config.line_AA);
12603 nk_draw_list_path_clear(list);
12617 nk_draw_list_stroke_line(
struct nk_draw_list *list,
struct nk_vec2 a,
12621 if (!list || !col.a)
return;
12622 if (list->line_AA == NK_ANTI_ALIASING_ON) {
12623 nk_draw_list_path_line_to(list, a);
12624 nk_draw_list_path_line_to(list, b);
12626 nk_draw_list_path_line_to(list, nk_vec2_sub(a,
nk_vec2(0.5f,0.5f)));
12627 nk_draw_list_path_line_to(list, nk_vec2_sub(b,
nk_vec2(0.5f,0.5f)));
12629 nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness);
12643 nk_draw_list_fill_rect(
struct nk_draw_list *list,
struct nk_rect rect,
12644 struct nk_color col,
float rounding)
12647 if (!list || !col.a)
return;
12649 if (list->line_AA == NK_ANTI_ALIASING_ON) {
12650 nk_draw_list_path_rect_to(list,
nk_vec2(rect.x, rect.y),
12651 nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
12653 nk_draw_list_path_rect_to(list,
nk_vec2(rect.x-0.5f, rect.y-0.5f),
12654 nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
12655 } nk_draw_list_path_fill(list, col);
12669 nk_draw_list_stroke_rect(
struct nk_draw_list *list,
struct nk_rect rect,
12670 struct nk_color col,
float rounding,
float thickness)
12673 if (!list || !col.a)
return;
12674 if (list->line_AA == NK_ANTI_ALIASING_ON) {
12675 nk_draw_list_path_rect_to(list,
nk_vec2(rect.x, rect.y),
12676 nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
12678 nk_draw_list_path_rect_to(list,
nk_vec2(rect.x-0.5f, rect.y-0.5f),
12679 nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
12680 } nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
12694 nk_draw_list_fill_rect_multi_color(
struct nk_draw_list *list,
struct nk_rect rect,
12700 struct nk_colorf col_right, col_bottom;
12701 nk_draw_index *idx;
12702 nk_draw_index index;
12704 nk_color_fv(&col_left.r, left);
12705 nk_color_fv(&col_right.r, right);
12706 nk_color_fv(&col_top.r, top);
12707 nk_color_fv(&col_bottom.r, bottom);
12712 nk_draw_list_push_image(list, list->config.tex_null.texture);
12713 index = (nk_draw_index)list->vertex_count;
12714 vtx = nk_draw_list_alloc_vertices(list, 4);
12715 idx = nk_draw_list_alloc_elements(list, 6);
12716 if (!vtx || !idx)
return;
12718 idx[0] = (nk_draw_index)(index+0); idx[1] = (nk_draw_index)(index+1);
12719 idx[2] = (nk_draw_index)(index+2); idx[3] = (nk_draw_index)(index+0);
12720 idx[4] = (nk_draw_index)(index+2); idx[5] = (nk_draw_index)(index+3);
12722 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(rect.x, rect.y), list->config.tex_null.uv, col_left);
12723 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(rect.x + rect.w, rect.y), list->config.tex_null.uv, col_top);
12724 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(rect.x + rect.w, rect.y + rect.h), list->config.tex_null.uv, col_right);
12725 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(rect.x, rect.y + rect.h), list->config.tex_null.uv, col_bottom);
12739 nk_draw_list_fill_triangle(
struct nk_draw_list *list,
struct nk_vec2 a,
12743 if (!list || !col.a)
return;
12744 nk_draw_list_path_line_to(list, a);
12745 nk_draw_list_path_line_to(list, b);
12746 nk_draw_list_path_line_to(list, c);
12747 nk_draw_list_path_fill(list, col);
12761 nk_draw_list_stroke_triangle(
struct nk_draw_list *list,
struct nk_vec2 a,
12765 if (!list || !col.a)
return;
12766 nk_draw_list_path_line_to(list, a);
12767 nk_draw_list_path_line_to(list, b);
12768 nk_draw_list_path_line_to(list, c);
12769 nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
12783 nk_draw_list_fill_circle(
struct nk_draw_list *list,
struct nk_vec2 center,
12784 float radius,
struct nk_color col,
unsigned int segs)
12788 if (!list || !col.a)
return;
12789 a_max = NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs;
12790 nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs);
12791 nk_draw_list_path_fill(list, col);
12805 nk_draw_list_stroke_circle(
struct nk_draw_list *list,
struct nk_vec2 center,
12806 float radius,
struct nk_color col,
unsigned int segs,
float thickness)
12810 if (!list || !col.a)
return;
12811 a_max = NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs;
12812 nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs);
12813 nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
12827 nk_draw_list_stroke_curve(
struct nk_draw_list *list,
struct nk_vec2 p0,
12829 struct nk_color col,
unsigned int segments,
float thickness)
12832 if (!list || !col.a)
return;
12833 nk_draw_list_path_line_to(list, p0);
12834 nk_draw_list_path_curve_to(list, cp0, cp1, p1, segments);
12835 nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness);
12849 nk_draw_list_push_rect_uv(
struct nk_draw_list *list,
struct nk_vec2 a,
12860 nk_draw_index *idx;
12861 nk_draw_index index;
12865 nk_color_fv(&col.r, color);
12871 index = (nk_draw_index)list->vertex_count;
12872 vtx = nk_draw_list_alloc_vertices(list, 4);
12873 idx = nk_draw_list_alloc_elements(list, 6);
12874 if (!vtx || !idx)
return;
12876 idx[0] = (nk_draw_index)(index+0); idx[1] = (nk_draw_index)(index+1);
12877 idx[2] = (nk_draw_index)(index+2); idx[3] = (nk_draw_index)(index+0);
12878 idx[4] = (nk_draw_index)(index+2); idx[5] = (nk_draw_index)(index+3);
12880 vtx = nk_draw_vertex(vtx, &list->config, a, uva, col);
12881 vtx = nk_draw_vertex(vtx, &list->config, b, uvb, col);
12882 vtx = nk_draw_vertex(vtx, &list->config, c, uvc, col);
12883 vtx = nk_draw_vertex(vtx, &list->config, d, uvd, col);
12897 nk_draw_list_add_image(
struct nk_draw_list *list,
struct nk_image texture,
12903 nk_draw_list_push_image(list, texture.handle);
12904 if (nk_image_is_subimage(&texture)) {
12907 uv[0].x = (float)texture.region[0]/(
float)texture.w;
12908 uv[0].y = (float)texture.region[1]/(
float)texture.h;
12909 uv[1].x = (float)(texture.region[0] + texture.region[2])/(float)texture.w;
12910 uv[1].y = (
float)(texture.region[1] + texture.region[3])/(
float)texture.h;
12911 nk_draw_list_push_rect_uv(list,
nk_vec2(rect.x, rect.y),
12912 nk_vec2(rect.x + rect.w, rect.y + rect.h), uv[0], uv[1], color);
12913 }
else nk_draw_list_push_rect_uv(list,
nk_vec2(rect.x, rect.y),
12914 nk_vec2(rect.x + rect.w, rect.y + rect.h),
12929 nk_draw_list_add_text(
struct nk_draw_list *list,
const struct nk_user_font *font,
12930 struct nk_rect rect,
const char *text,
int len,
float font_height,
12935 nk_rune unicode = 0;
12938 int next_glyph_len = 0;
12939 struct nk_user_font_glyph g;
12942 if (!list || !len || !text)
return;
12943 if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
12944 list->clip_rect.x, list->clip_rect.y, list->clip_rect.w, list->clip_rect.h))
return;
12946 nk_draw_list_push_image(list, font->texture);
12948 glyph_len = nk_utf_decode(text, &unicode, len);
12949 if (!glyph_len)
return;
12952 fg.a = (nk_byte)((
float)fg.a * list->config.global_alpha);
12953 while (text_len < len && glyph_len) {
12954 float gx, gy, gh, gw;
12955 float char_width = 0;
12959 next_glyph_len = nk_utf_decode(text + text_len + glyph_len, &next, (
int)len - text_len);
12960 font->query(font->userdata, font_height, &g, unicode,
12964 gx = x + g.offset.x;
12965 gy = rect.y + g.offset.y;
12966 gw = g.width; gh = g.height;
12967 char_width = g.xadvance;
12968 nk_draw_list_push_rect_uv(list,
nk_vec2(gx,gy),
nk_vec2(gx + gw, gy+ gh),
12969 g.uv[0], g.uv[1], fg);
12972 text_len += glyph_len;
12974 glyph_len = next_glyph_len;
12994 nk_flags res = NK_CONVERT_SUCCESS;
12998 NK_ASSERT(vertices);
12999 NK_ASSERT(elements);
13003 if (!ctx || !cmds || !vertices || !elements || !config || !config->
vertex_layout)
13004 return NK_CONVERT_INVALID_PARAM;
13006 nk_draw_list_setup(&ctx->draw_list, config, cmds, vertices, elements,
13010 #ifdef NK_INCLUDE_COMMAND_USERDATA
13011 ctx->draw_list.userdata = cmd->userdata;
13013 switch (cmd->type) {
13014 case NK_COMMAND_NOP:
break;
13015 case NK_COMMAND_SCISSOR: {
13017 nk_draw_list_add_clip(&ctx->draw_list,
nk_rect(s->x, s->y, s->w, s->h));
13019 case NK_COMMAND_LINE: {
13021 nk_draw_list_stroke_line(&ctx->draw_list,
nk_vec2(l->begin.x, l->begin.y),
13022 nk_vec2(l->end.x, l->end.y), l->color, l->line_thickness);
13024 case NK_COMMAND_CURVE: {
13026 nk_draw_list_stroke_curve(&ctx->draw_list,
nk_vec2(q->begin.x, q->begin.y),
13028 q->ctrl[1].y),
nk_vec2(q->end.x, q->end.y), q->color,
13031 case NK_COMMAND_RECT: {
13033 nk_draw_list_stroke_rect(&ctx->draw_list,
nk_rect(r->x, r->y, r->w, r->h),
13034 r->color, (
float)r->rounding, r->line_thickness);
13036 case NK_COMMAND_RECT_FILLED: {
13038 nk_draw_list_fill_rect(&ctx->draw_list,
nk_rect(r->x, r->y, r->w, r->h),
13039 r->color, (
float)r->rounding);
13041 case NK_COMMAND_RECT_MULTI_COLOR: {
13043 nk_draw_list_fill_rect_multi_color(&ctx->draw_list,
nk_rect(r->x, r->y, r->w, r->h),
13044 r->left, r->top, r->right, r->bottom);
13046 case NK_COMMAND_CIRCLE: {
13048 nk_draw_list_stroke_circle(&ctx->draw_list,
nk_vec2((
float)c->x + (
float)c->w/2,
13049 (
float)c->y + (
float)c->h/2), (
float)c->w/2, c->color,
13052 case NK_COMMAND_CIRCLE_FILLED: {
13054 nk_draw_list_fill_circle(&ctx->draw_list,
nk_vec2((
float)c->x + (
float)c->w/2,
13055 (
float)c->y + (
float)c->h/2), (
float)c->w/2, c->color,
13058 case NK_COMMAND_ARC: {
13060 nk_draw_list_path_line_to(&ctx->draw_list,
nk_vec2(c->cx, c->cy));
13061 nk_draw_list_path_arc_to(&ctx->draw_list,
nk_vec2(c->cx, c->cy), c->r,
13063 nk_draw_list_path_stroke(&ctx->draw_list, c->color, NK_STROKE_CLOSED, c->line_thickness);
13065 case NK_COMMAND_ARC_FILLED: {
13067 nk_draw_list_path_line_to(&ctx->draw_list,
nk_vec2(c->cx, c->cy));
13068 nk_draw_list_path_arc_to(&ctx->draw_list,
nk_vec2(c->cx, c->cy), c->r,
13070 nk_draw_list_path_fill(&ctx->draw_list, c->color);
13072 case NK_COMMAND_TRIANGLE: {
13074 nk_draw_list_stroke_triangle(&ctx->draw_list,
nk_vec2(t->a.x, t->a.y),
13076 t->line_thickness);
13078 case NK_COMMAND_TRIANGLE_FILLED: {
13080 nk_draw_list_fill_triangle(&ctx->draw_list,
nk_vec2(t->a.x, t->a.y),
13083 case NK_COMMAND_POLYGON: {
13086 for (i = 0; i < p->point_count; ++i) {
13087 struct nk_vec2 pnt =
nk_vec2((
float)p->points[i].x, (
float)p->points[i].y);
13088 nk_draw_list_path_line_to(&ctx->draw_list, pnt);
13090 nk_draw_list_path_stroke(&ctx->draw_list, p->color, NK_STROKE_CLOSED, p->line_thickness);
13092 case NK_COMMAND_POLYGON_FILLED: {
13095 for (i = 0; i < p->point_count; ++i) {
13096 struct nk_vec2 pnt =
nk_vec2((
float)p->points[i].x, (
float)p->points[i].y);
13097 nk_draw_list_path_line_to(&ctx->draw_list, pnt);
13099 nk_draw_list_path_fill(&ctx->draw_list, p->color);
13101 case NK_COMMAND_POLYLINE: {
13104 for (i = 0; i < p->point_count; ++i) {
13105 struct nk_vec2 pnt =
nk_vec2((
float)p->points[i].x, (
float)p->points[i].y);
13106 nk_draw_list_path_line_to(&ctx->draw_list, pnt);
13108 nk_draw_list_path_stroke(&ctx->draw_list, p->color, NK_STROKE_OPEN, p->line_thickness);
13110 case NK_COMMAND_TEXT: {
13112 nk_draw_list_add_text(&ctx->draw_list, t->font,
nk_rect(t->x, t->y, t->w, t->h),
13113 t->string, t->length, t->height, t->foreground);
13115 case NK_COMMAND_IMAGE: {
13117 nk_draw_list_add_image(&ctx->draw_list, i->img,
nk_rect(i->x, i->y, i->w, i->h), i->col);
13119 case NK_COMMAND_CUSTOM: {
13121 c->callback(&ctx->draw_list, c->x, c->y, c->w, c->h, c->callback_data);
13127 res |= (vertices->
needed > vertices->
allocated) ? NK_CONVERT_VERTEX_BUFFER_FULL: 0;
13128 res |= (elements->
needed > elements->
allocated) ? NK_CONVERT_ELEMENT_BUFFER_FULL: 0;
13141 NK_API
const struct nk_draw_command*
13142 nk__draw_begin(
const struct nk_context *ctx,
13145 return nk__draw_list_begin(&ctx->draw_list, buffer);
13158 NK_API
const struct nk_draw_command*
13161 return nk__draw_list_end(&ctx->draw_list, buffer);
13173 NK_API
const struct nk_draw_command*
13174 nk__draw_next(
const struct nk_draw_command *cmd,
13177 return nk__draw_list_next(cmd, buffer, &ctx->draw_list);
13247 #ifndef STB_INCLUDE_STB_RECT_PACK_H
13248 #define STB_INCLUDE_STB_RECT_PACK_H
13250 #define STB_RECT_PACK_VERSION 1
13252 #ifdef STBRP_STATIC
13253 #define STBRP_DEF static
13255 #define STBRP_DEF extern
13262 typedef struct stbrp_context stbrp_context;
13263 typedef struct stbrp_node stbrp_node;
13264 typedef struct stbrp_rect stbrp_rect;
13266 typedef int stbrp_coord;
13268 #define STBRP__MAXVAL 0x7fffffff
13271 STBRP_DEF
int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects,
int num_rects);
13311 STBRP_DEF
void stbrp_init_target (stbrp_context *context,
int width,
int height, stbrp_node *nodes,
int num_nodes);
13332 STBRP_DEF
void stbrp_setup_allow_out_of_mem (stbrp_context *context,
int allow_out_of_mem);
13338 STBRP_DEF
void stbrp_setup_heuristic (stbrp_context *context,
int heuristic);
13345 STBRP_HEURISTIC_Skyline_default=0,
13346 STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
13347 STBRP_HEURISTIC_Skyline_BF_sortHeight
13362 struct stbrp_context
13370 stbrp_node *active_head;
13371 stbrp_node *free_head;
13372 stbrp_node extra[2];
13386 #ifdef STB_RECT_PACK_IMPLEMENTATION
13388 #include <stdlib.h>
13389 #define STBRP_SORT qsort
13392 #ifndef STBRP_ASSERT
13393 #include <assert.h>
13394 #define STBRP_ASSERT assert
13398 #define STBRP__NOTUSED(v) (void)(v)
13399 #define STBRP__CDECL __cdecl
13401 #define STBRP__NOTUSED(v) (void)sizeof(v)
13402 #define STBRP__CDECL
13407 STBRP__INIT_skyline = 1
13410 STBRP_DEF
void stbrp_setup_heuristic(stbrp_context *context,
int heuristic)
13412 switch (context->init_mode) {
13413 case STBRP__INIT_skyline:
13414 STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
13415 context->heuristic = heuristic;
13422 STBRP_DEF
void stbrp_setup_allow_out_of_mem(stbrp_context *context,
int allow_out_of_mem)
13424 if (allow_out_of_mem)
13429 context->align = 1;
13438 context->align = (context->width + context->num_nodes-1) / context->num_nodes;
13442 STBRP_DEF
void stbrp_init_target(stbrp_context *context,
int width,
int height, stbrp_node *nodes,
int num_nodes)
13446 for (i=0; i < num_nodes-1; ++i)
13447 nodes[i].next = &nodes[i+1];
13448 nodes[i].next = NULL;
13449 context->init_mode = STBRP__INIT_skyline;
13450 context->heuristic = STBRP_HEURISTIC_Skyline_default;
13451 context->free_head = &nodes[0];
13452 context->active_head = &context->extra[0];
13453 context->width = width;
13454 context->height = height;
13455 context->num_nodes = num_nodes;
13456 stbrp_setup_allow_out_of_mem(context, 0);
13459 context->extra[0].x = 0;
13460 context->extra[0].y = 0;
13461 context->extra[0].next = &context->extra[1];
13462 context->extra[1].x = (stbrp_coord) width;
13463 context->extra[1].y = (1<<30);
13464 context->extra[1].next = NULL;
13468 static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first,
int x0,
int width,
int *pwaste)
13470 stbrp_node *node = first;
13471 int x1 = x0 + width;
13472 int min_y, visited_width, waste_area;
13476 STBRP_ASSERT(first->x <= x0);
13480 while (node->next->x <= x0)
13483 STBRP_ASSERT(node->next->x > x0);
13486 STBRP_ASSERT(node->x <= x0);
13491 while (node->x < x1) {
13492 if (node->y > min_y) {
13496 waste_area += visited_width * (node->y - min_y);
13500 visited_width += node->next->x - x0;
13502 visited_width += node->next->x - node->x;
13505 int under_width = node->next->x - node->x;
13506 if (under_width + visited_width > width)
13507 under_width = width - visited_width;
13508 waste_area += under_width * (min_y - node->y);
13509 visited_width += under_width;
13514 *pwaste = waste_area;
13521 stbrp_node **prev_link;
13522 } stbrp__findresult;
13524 static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c,
int width,
int height)
13526 int best_waste = (1<<30), best_x, best_y = (1 << 30);
13527 stbrp__findresult fr;
13528 stbrp_node **prev, *node, *tail, **best = NULL;
13531 width = (width + c->align - 1);
13532 width -= width % c->align;
13533 STBRP_ASSERT(width % c->align == 0);
13536 if (width > c->width || height > c->height) {
13537 fr.prev_link = NULL;
13542 node = c->active_head;
13543 prev = &c->active_head;
13544 while (node->x + width <= c->width) {
13546 y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
13547 if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) {
13555 if (y + height <= c->height) {
13557 if (y < best_y || (y == best_y && waste < best_waste)) {
13559 best_waste = waste;
13564 prev = &node->next;
13568 best_x = (best == NULL) ? 0 : (*best)->x;
13587 if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
13588 tail = c->active_head;
13589 node = c->active_head;
13590 prev = &c->active_head;
13592 while (tail->x < width)
13595 int xpos = tail->x - width;
13597 STBRP_ASSERT(xpos >= 0);
13599 while (node->next->x <= xpos) {
13600 prev = &node->next;
13603 STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
13604 y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
13605 if (y + height <= c->height) {
13607 if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
13609 STBRP_ASSERT(y <= best_y);
13611 best_waste = waste;
13620 fr.prev_link = best;
13626 static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context,
int width,
int height)
13629 stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
13630 stbrp_node *node, *cur;
13636 if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
13637 res.prev_link = NULL;
13642 node = context->free_head;
13643 node->x = (stbrp_coord) res.x;
13644 node->y = (stbrp_coord) (res.y + height);
13646 context->free_head = node->next;
13652 cur = *res.prev_link;
13653 if (cur->x < res.x) {
13655 stbrp_node *next = cur->next;
13659 *res.prev_link = node;
13664 while (cur->next && cur->next->x <= res.x + width) {
13665 stbrp_node *next = cur->next;
13667 cur->next = context->free_head;
13668 context->free_head = cur;
13675 if (cur->x < res.x + width)
13676 cur->x = (stbrp_coord) (res.x + width);
13679 cur = context->active_head;
13680 while (cur->x < context->width) {
13681 STBRP_ASSERT(cur->x < cur->next->x);
13684 STBRP_ASSERT(cur->next == NULL);
13688 cur = context->active_head;
13693 cur = context->free_head;
13698 STBRP_ASSERT(count == context->num_nodes+2);
13705 static int STBRP__CDECL rect_height_compare(
const void *a,
const void *b)
13707 const stbrp_rect *p = (
const stbrp_rect *) a;
13708 const stbrp_rect *q = (
const stbrp_rect *) b;
13713 return (p->w > q->w) ? -1 : (p->w < q->w);
13716 static int STBRP__CDECL rect_original_order(
const void *a,
const void *b)
13718 const stbrp_rect *p = (
const stbrp_rect *) a;
13719 const stbrp_rect *q = (
const stbrp_rect *) b;
13720 return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
13723 STBRP_DEF
int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects,
int num_rects)
13725 int i, all_rects_packed = 1;
13728 for (i=0; i < num_rects; ++i) {
13729 rects[i].was_packed = i;
13733 STBRP_SORT(rects, num_rects,
sizeof(rects[0]), rect_height_compare);
13735 for (i=0; i < num_rects; ++i) {
13736 if (rects[i].w == 0 || rects[i].h == 0) {
13737 rects[i].x = rects[i].y = 0;
13739 stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
13740 if (fr.prev_link) {
13741 rects[i].x = (stbrp_coord) fr.x;
13742 rects[i].y = (stbrp_coord) fr.y;
13744 rects[i].x = rects[i].y = STBRP__MAXVAL;
13750 STBRP_SORT(rects, num_rects,
sizeof(rects[0]), rect_original_order);
13753 for (i=0; i < num_rects; ++i) {
13754 rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
13755 if (!rects[i].was_packed)
13756 all_rects_packed = 0;
13760 return all_rects_packed;
14083 #define STB_TRUETYPE_IMPLEMENTATION
14084 #include "stb_truetype.h"
14086 unsigned char ttf_buffer[1<<20];
14087 unsigned char temp_bitmap[512*512];
14089 stbtt_bakedchar cdata[96];
14092 void my_stbtt_initfont(
void)
14094 fread(ttf_buffer, 1, 1<<20, fopen(
"c:/windows/fonts/times.ttf",
"rb"));
14095 stbtt_BakeFontBitmap(ttf_buffer,0, 32.0, temp_bitmap,512,512, 32,96, cdata);
14097 glGenTextures(1, &ftex);
14098 glBindTexture(GL_TEXTURE_2D, ftex);
14099 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512,512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap);
14101 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
14104 void my_stbtt_print(
float x,
float y,
char *text)
14107 glEnable(GL_BLEND);
14108 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
14109 glEnable(GL_TEXTURE_2D);
14110 glBindTexture(GL_TEXTURE_2D, ftex);
14113 if (*text >= 32 && *text < 128) {
14114 stbtt_aligned_quad q;
14115 stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);
14116 glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y0);
14117 glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y0);
14118 glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y1);
14119 glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y1);
14134 #define STB_TRUETYPE_IMPLEMENTATION
14135 #include "stb_truetype.h"
14137 char ttf_buffer[1<<25];
14139 int main(
int argc,
char **argv)
14141 stbtt_fontinfo font;
14142 unsigned char *bitmap;
14143 int w,h,i,j,c = (argc > 1 ? atoi(argv[1]) :
'a'), s = (argc > 2 ? atoi(argv[2]) : 20);
14145 fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] :
"c:/windows/fonts/arialbd.ttf",
"rb"));
14147 stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0));
14148 bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), c, &w, &h, 0,0);
14150 for (j=0; j < h; ++j) {
14151 for (i=0; i < w; ++i)
14152 putchar(
" .:ioVM@"[bitmap[j*w+i]>>5]);
14177 char buffer[24<<20];
14178 unsigned char screen[20][79];
14180 int main(
int arg,
char **argv)
14182 stbtt_fontinfo font;
14183 int i,j,ascent,baseline,ch=0;
14184 float scale, xpos=2;
14185 char *text =
"Heljo World!";
14187 fread(buffer, 1, 1000000, fopen(
"c:/windows/fonts/arialbd.ttf",
"rb"));
14188 stbtt_InitFont(&font, buffer, 0);
14190 scale = stbtt_ScaleForPixelHeight(&font, 15);
14191 stbtt_GetFontVMetrics(&font, &ascent,0,0);
14192 baseline = (int) (ascent*scale);
14195 int advance,lsb,x0,y0,x1,y1;
14196 float x_shift = xpos - (float) floor(xpos);
14197 stbtt_GetCodepointHMetrics(&font, text[ch], &advance, &lsb);
14198 stbtt_GetCodepointBitmapBoxSubpixel(&font, text[ch], scale,scale,x_shift,0, &x0,&y0,&x1,&y1);
14199 stbtt_MakeCodepointBitmapSubpixel(&font, &screen[baseline + y0][(
int) xpos + x0], x1-x0,y1-y0, 79, scale,scale,x_shift,0, text[ch]);
14204 xpos += (advance * scale);
14206 xpos += scale*stbtt_GetCodepointKernAdvance(&font, text[ch],text[ch+1]);
14210 for (j=0; j < 20; ++j) {
14211 for (i=0; i < 78; ++i)
14212 putchar(
" .:ioVM@"[screen[j][i]>>5]);
14230 #ifdef STB_TRUETYPE_IMPLEMENTATION
14232 #ifndef stbtt_uint8
14233 typedef unsigned char stbtt_uint8;
14234 typedef signed char stbtt_int8;
14235 typedef unsigned short stbtt_uint16;
14236 typedef signed short stbtt_int16;
14237 typedef unsigned int stbtt_uint32;
14238 typedef signed int stbtt_int32;
14241 typedef char stbtt__check_size32[
sizeof(stbtt_int32)==4 ? 1 : -1];
14242 typedef char stbtt__check_size16[
sizeof(stbtt_int16)==2 ? 1 : -1];
14245 #ifndef STBTT_ifloor
14247 #define STBTT_ifloor(x) ((int) floor(x))
14248 #define STBTT_iceil(x) ((int) ceil(x))
14253 #define STBTT_sqrt(x) sqrt(x)
14254 #define STBTT_pow(x,y) pow(x,y)
14259 #define STBTT_fmod(x,y) fmod(x,y)
14264 #define STBTT_cos(x) cos(x)
14265 #define STBTT_acos(x) acos(x)
14270 #define STBTT_fabs(x) fabs(x)
14274 #ifndef STBTT_malloc
14275 #include <stdlib.h>
14276 #define STBTT_malloc(x,u) ((void)(u),malloc(x))
14277 #define STBTT_free(x,u) ((void)(u),free(x))
14280 #ifndef STBTT_assert
14281 #include <assert.h>
14282 #define STBTT_assert(x) assert(x)
14285 #ifndef STBTT_strlen
14286 #include <string.h>
14287 #define STBTT_strlen(x) strlen(x)
14290 #ifndef STBTT_memcpy
14291 #include <string.h>
14292 #define STBTT_memcpy memcpy
14293 #define STBTT_memset memset
14304 #ifndef __STB_INCLUDE_STB_TRUETYPE_H__
14305 #define __STB_INCLUDE_STB_TRUETYPE_H__
14307 #ifdef STBTT_STATIC
14308 #define STBTT_DEF static
14310 #define STBTT_DEF extern
14320 unsigned char *data;
14334 unsigned short x0,y0,x1,y1;
14335 float xoff,yoff,xadvance;
14338 STBTT_DEF
int stbtt_BakeFontBitmap(
const unsigned char *data,
int offset,
14339 float pixel_height,
14340 unsigned char *pixels,
int pw,
int ph,
14341 int first_char,
int num_chars,
14342 stbtt_bakedchar *chardata);
14352 } stbtt_aligned_quad;
14354 STBTT_DEF
void stbtt_GetBakedQuad(
const stbtt_bakedchar *chardata,
int pw,
int ph,
14356 float *xpos,
float *ypos,
14357 stbtt_aligned_quad *q,
14358 int opengl_fillrule);
14369 STBTT_DEF
void stbtt_GetScaledFontVMetrics(
const unsigned char *fontdata,
int index,
float size,
float *ascent,
float *descent,
float *lineGap);
14382 unsigned short x0,y0,x1,y1;
14383 float xoff,yoff,xadvance;
14385 } stbtt_packedchar;
14387 typedef struct stbtt_pack_context stbtt_pack_context;
14388 typedef struct stbtt_fontinfo stbtt_fontinfo;
14389 #ifndef STB_RECT_PACK_VERSION
14390 typedef struct stbrp_rect stbrp_rect;
14393 STBTT_DEF
int stbtt_PackBegin(stbtt_pack_context *spc,
unsigned char *pixels,
int width,
int height,
int stride_in_bytes,
int padding,
void *alloc_context);
14404 STBTT_DEF
void stbtt_PackEnd (stbtt_pack_context *spc);
14407 #define STBTT_POINT_SIZE(x) (-(x))
14409 STBTT_DEF
int stbtt_PackFontRange(stbtt_pack_context *spc,
const unsigned char *fontdata,
int font_index,
float font_size,
14410 int first_unicode_char_in_range,
int num_chars_in_range, stbtt_packedchar *chardata_for_range);
14427 int first_unicode_codepoint_in_range;
14428 int *array_of_unicode_codepoints;
14430 stbtt_packedchar *chardata_for_range;
14431 unsigned char h_oversample, v_oversample;
14432 } stbtt_pack_range;
14434 STBTT_DEF
int stbtt_PackFontRanges(stbtt_pack_context *spc,
const unsigned char *fontdata,
int font_index, stbtt_pack_range *ranges,
int num_ranges);
14440 STBTT_DEF
void stbtt_PackSetOversampling(stbtt_pack_context *spc,
unsigned int h_oversample,
unsigned int v_oversample);
14456 STBTT_DEF
void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc,
int skip);
14462 STBTT_DEF
void stbtt_GetPackedQuad(
const stbtt_packedchar *chardata,
int pw,
int ph,
14464 float *xpos,
float *ypos,
14465 stbtt_aligned_quad *q,
14466 int align_to_integer);
14468 STBTT_DEF
int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc,
const stbtt_fontinfo *info, stbtt_pack_range *ranges,
int num_ranges, stbrp_rect *rects);
14469 STBTT_DEF
void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects,
int num_rects);
14470 STBTT_DEF
int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc,
const stbtt_fontinfo *info, stbtt_pack_range *ranges,
int num_ranges, stbrp_rect *rects);
14483 struct stbtt_pack_context {
14484 void *user_allocator_context;
14488 int stride_in_bytes;
14491 unsigned int h_oversample, v_oversample;
14492 unsigned char *pixels;
14502 STBTT_DEF
int stbtt_GetNumberOfFonts(
const unsigned char *data);
14509 STBTT_DEF
int stbtt_GetFontOffsetForIndex(
const unsigned char *data,
int index);
14518 struct stbtt_fontinfo
14521 unsigned char * data;
14526 int loca,head,glyf,hhea,hmtx,kern,gpos,svg;
14528 int indexToLocFormat;
14531 stbtt__buf charstrings;
14534 stbtt__buf fontdicts;
14535 stbtt__buf fdselect;
14538 STBTT_DEF
int stbtt_InitFont(stbtt_fontinfo *info,
const unsigned char *data,
int offset);
14550 STBTT_DEF
int stbtt_FindGlyphIndex(
const stbtt_fontinfo *info,
int unicode_codepoint);
14563 STBTT_DEF
float stbtt_ScaleForPixelHeight(
const stbtt_fontinfo *info,
float pixels);
14571 STBTT_DEF
float stbtt_ScaleForMappingEmToPixels(
const stbtt_fontinfo *info,
float pixels);
14576 STBTT_DEF
void stbtt_GetFontVMetrics(
const stbtt_fontinfo *info,
int *ascent,
int *descent,
int *lineGap);
14584 STBTT_DEF
int stbtt_GetFontVMetricsOS2(
const stbtt_fontinfo *info,
int *typoAscent,
int *typoDescent,
int *typoLineGap);
14590 STBTT_DEF
void stbtt_GetFontBoundingBox(
const stbtt_fontinfo *info,
int *x0,
int *y0,
int *x1,
int *y1);
14593 STBTT_DEF
void stbtt_GetCodepointHMetrics(
const stbtt_fontinfo *info,
int codepoint,
int *advanceWidth,
int *leftSideBearing);
14598 STBTT_DEF
int stbtt_GetCodepointKernAdvance(
const stbtt_fontinfo *info,
int ch1,
int ch2);
14601 STBTT_DEF
int stbtt_GetCodepointBox(
const stbtt_fontinfo *info,
int codepoint,
int *x0,
int *y0,
int *x1,
int *y1);
14604 STBTT_DEF
void stbtt_GetGlyphHMetrics(
const stbtt_fontinfo *info,
int glyph_index,
int *advanceWidth,
int *leftSideBearing);
14605 STBTT_DEF
int stbtt_GetGlyphKernAdvance(
const stbtt_fontinfo *info,
int glyph1,
int glyph2);
14606 STBTT_DEF
int stbtt_GetGlyphBox(
const stbtt_fontinfo *info,
int glyph_index,
int *x0,
int *y0,
int *x1,
int *y1);
14609 typedef struct stbtt_kerningentry
14614 } stbtt_kerningentry;
14616 STBTT_DEF
int stbtt_GetKerningTableLength(
const stbtt_fontinfo *info);
14617 STBTT_DEF
int stbtt_GetKerningTable(
const stbtt_fontinfo *info, stbtt_kerningentry* table,
int table_length);
14628 #ifndef STBTT_vmove
14637 #ifndef stbtt_vertex
14639 #define stbtt_vertex_type short
14642 stbtt_vertex_type x,y,cx,cy,cx1,cy1;
14643 unsigned char type,padding;
14647 STBTT_DEF
int stbtt_IsGlyphEmpty(
const stbtt_fontinfo *info,
int glyph_index);
14650 STBTT_DEF
int stbtt_GetCodepointShape(
const stbtt_fontinfo *info,
int unicode_codepoint, stbtt_vertex **vertices);
14651 STBTT_DEF
int stbtt_GetGlyphShape(
const stbtt_fontinfo *info,
int glyph_index, stbtt_vertex **vertices);
14662 STBTT_DEF
void stbtt_FreeShape(
const stbtt_fontinfo *info, stbtt_vertex *vertices);
14665 STBTT_DEF
unsigned char *stbtt_FindSVGDoc(
const stbtt_fontinfo *info,
int gl);
14666 STBTT_DEF
int stbtt_GetCodepointSVG(
const stbtt_fontinfo *info,
int unicode_codepoint,
const char **svg);
14667 STBTT_DEF
int stbtt_GetGlyphSVG(
const stbtt_fontinfo *info,
int gl,
const char **svg);
14676 STBTT_DEF
void stbtt_FreeBitmap(
unsigned char *bitmap,
void *userdata);
14679 STBTT_DEF
unsigned char *stbtt_GetCodepointBitmap(
const stbtt_fontinfo *info,
float scale_x,
float scale_y,
int codepoint,
int *width,
int *height,
int *xoff,
int *yoff);
14688 STBTT_DEF
unsigned char *stbtt_GetCodepointBitmapSubpixel(
const stbtt_fontinfo *info,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int codepoint,
int *width,
int *height,
int *xoff,
int *yoff);
14692 STBTT_DEF
void stbtt_MakeCodepointBitmap(
const stbtt_fontinfo *info,
unsigned char *output,
int out_w,
int out_h,
int out_stride,
float scale_x,
float scale_y,
int codepoint);
14698 STBTT_DEF
void stbtt_MakeCodepointBitmapSubpixel(
const stbtt_fontinfo *info,
unsigned char *output,
int out_w,
int out_h,
int out_stride,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int codepoint);
14702 STBTT_DEF
void stbtt_MakeCodepointBitmapSubpixelPrefilter(
const stbtt_fontinfo *info,
unsigned char *output,
int out_w,
int out_h,
int out_stride,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int oversample_x,
int oversample_y,
float *sub_x,
float *sub_y,
int codepoint);
14706 STBTT_DEF
void stbtt_GetCodepointBitmapBox(
const stbtt_fontinfo *font,
int codepoint,
float scale_x,
float scale_y,
int *ix0,
int *iy0,
int *ix1,
int *iy1);
14713 STBTT_DEF
void stbtt_GetCodepointBitmapBoxSubpixel(
const stbtt_fontinfo *font,
int codepoint,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int *ix0,
int *iy0,
int *ix1,
int *iy1);
14719 STBTT_DEF
unsigned char *stbtt_GetGlyphBitmap(
const stbtt_fontinfo *info,
float scale_x,
float scale_y,
int glyph,
int *width,
int *height,
int *xoff,
int *yoff);
14720 STBTT_DEF
unsigned char *stbtt_GetGlyphBitmapSubpixel(
const stbtt_fontinfo *info,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int glyph,
int *width,
int *height,
int *xoff,
int *yoff);
14721 STBTT_DEF
void stbtt_MakeGlyphBitmap(
const stbtt_fontinfo *info,
unsigned char *output,
int out_w,
int out_h,
int out_stride,
float scale_x,
float scale_y,
int glyph);
14722 STBTT_DEF
void stbtt_MakeGlyphBitmapSubpixel(
const stbtt_fontinfo *info,
unsigned char *output,
int out_w,
int out_h,
int out_stride,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int glyph);
14723 STBTT_DEF
void stbtt_MakeGlyphBitmapSubpixelPrefilter(
const stbtt_fontinfo *info,
unsigned char *output,
int out_w,
int out_h,
int out_stride,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int oversample_x,
int oversample_y,
float *sub_x,
float *sub_y,
int glyph);
14724 STBTT_DEF
void stbtt_GetGlyphBitmapBox(
const stbtt_fontinfo *font,
int glyph,
float scale_x,
float scale_y,
int *ix0,
int *iy0,
int *ix1,
int *iy1);
14725 STBTT_DEF
void stbtt_GetGlyphBitmapBoxSubpixel(
const stbtt_fontinfo *font,
int glyph,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int *ix0,
int *iy0,
int *ix1,
int *iy1);
14732 unsigned char *pixels;
14736 STBTT_DEF
void stbtt_Rasterize(stbtt__bitmap *result,
14737 float flatness_in_pixels,
14738 stbtt_vertex *vertices,
14740 float scale_x,
float scale_y,
14741 float shift_x,
float shift_y,
14742 int x_off,
int y_off,
14750 STBTT_DEF
void stbtt_FreeSDF(
unsigned char *bitmap,
void *userdata);
14753 STBTT_DEF
unsigned char * stbtt_GetGlyphSDF(
const stbtt_fontinfo *info,
float scale,
int glyph,
int padding,
unsigned char onedge_value,
float pixel_dist_scale,
int *width,
int *height,
int *xoff,
int *yoff);
14754 STBTT_DEF
unsigned char * stbtt_GetCodepointSDF(
const stbtt_fontinfo *info,
float scale,
int codepoint,
int padding,
unsigned char onedge_value,
float pixel_dist_scale,
int *width,
int *height,
int *xoff,
int *yoff);
14826 STBTT_DEF
int stbtt_FindMatchingFont(
const unsigned char *fontdata,
const char *name,
int flags);
14831 #define STBTT_MACSTYLE_DONTCARE 0
14832 #define STBTT_MACSTYLE_BOLD 1
14833 #define STBTT_MACSTYLE_ITALIC 2
14834 #define STBTT_MACSTYLE_UNDERSCORE 4
14835 #define STBTT_MACSTYLE_NONE 8
14837 STBTT_DEF
int stbtt_CompareUTF8toUTF16_bigendian(
const char *s1,
int len1,
const char *s2,
int len2);
14841 STBTT_DEF
const char *stbtt_GetFontNameString(
const stbtt_fontinfo *font,
int *length,
int platformID,
int encodingID,
int languageID,
int nameID);
14850 STBTT_PLATFORM_ID_UNICODE =0,
14851 STBTT_PLATFORM_ID_MAC =1,
14852 STBTT_PLATFORM_ID_ISO =2,
14853 STBTT_PLATFORM_ID_MICROSOFT =3
14857 STBTT_UNICODE_EID_UNICODE_1_0 =0,
14858 STBTT_UNICODE_EID_UNICODE_1_1 =1,
14859 STBTT_UNICODE_EID_ISO_10646 =2,
14860 STBTT_UNICODE_EID_UNICODE_2_0_BMP=3,
14861 STBTT_UNICODE_EID_UNICODE_2_0_FULL=4
14865 STBTT_MS_EID_SYMBOL =0,
14866 STBTT_MS_EID_UNICODE_BMP =1,
14867 STBTT_MS_EID_SHIFTJIS =2,
14868 STBTT_MS_EID_UNICODE_FULL =10
14872 STBTT_MAC_EID_ROMAN =0, STBTT_MAC_EID_ARABIC =4,
14873 STBTT_MAC_EID_JAPANESE =1, STBTT_MAC_EID_HEBREW =5,
14874 STBTT_MAC_EID_CHINESE_TRAD =2, STBTT_MAC_EID_GREEK =6,
14875 STBTT_MAC_EID_KOREAN =3, STBTT_MAC_EID_RUSSIAN =7
14880 STBTT_MS_LANG_ENGLISH =0x0409, STBTT_MS_LANG_ITALIAN =0x0410,
14881 STBTT_MS_LANG_CHINESE =0x0804, STBTT_MS_LANG_JAPANESE =0x0411,
14882 STBTT_MS_LANG_DUTCH =0x0413, STBTT_MS_LANG_KOREAN =0x0412,
14883 STBTT_MS_LANG_FRENCH =0x040c, STBTT_MS_LANG_RUSSIAN =0x0419,
14884 STBTT_MS_LANG_GERMAN =0x0407, STBTT_MS_LANG_SPANISH =0x0409,
14885 STBTT_MS_LANG_HEBREW =0x040d, STBTT_MS_LANG_SWEDISH =0x041D
14889 STBTT_MAC_LANG_ENGLISH =0 , STBTT_MAC_LANG_JAPANESE =11,
14890 STBTT_MAC_LANG_ARABIC =12, STBTT_MAC_LANG_KOREAN =23,
14891 STBTT_MAC_LANG_DUTCH =4 , STBTT_MAC_LANG_RUSSIAN =32,
14892 STBTT_MAC_LANG_FRENCH =1 , STBTT_MAC_LANG_SPANISH =6 ,
14893 STBTT_MAC_LANG_GERMAN =2 , STBTT_MAC_LANG_SWEDISH =5 ,
14894 STBTT_MAC_LANG_HEBREW =10, STBTT_MAC_LANG_CHINESE_SIMPLIFIED =33,
14895 STBTT_MAC_LANG_ITALIAN =3 , STBTT_MAC_LANG_CHINESE_TRAD =19
14911 #ifdef STB_TRUETYPE_IMPLEMENTATION
14913 #ifndef STBTT_MAX_OVERSAMPLE
14914 #define STBTT_MAX_OVERSAMPLE 8
14917 #if STBTT_MAX_OVERSAMPLE > 255
14918 #error "STBTT_MAX_OVERSAMPLE cannot be > 255"
14921 typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE-1)) == 0 ? 1 : -1];
14923 #ifndef STBTT_RASTERIZER_VERSION
14924 #define STBTT_RASTERIZER_VERSION 2
14928 #define STBTT__NOTUSED(v) (void)(v)
14930 #define STBTT__NOTUSED(v) (void)sizeof(v)
14938 static stbtt_uint8 stbtt__buf_get8(stbtt__buf *b)
14940 if (b->cursor >= b->size)
14942 return b->data[b->cursor++];
14945 static stbtt_uint8 stbtt__buf_peek8(stbtt__buf *b)
14947 if (b->cursor >= b->size)
14949 return b->data[b->cursor];
14952 static void stbtt__buf_seek(stbtt__buf *b,
int o)
14954 STBTT_assert(!(o > b->size || o < 0));
14955 b->cursor = (o > b->size || o < 0) ? b->size : o;
14958 static void stbtt__buf_skip(stbtt__buf *b,
int o)
14960 stbtt__buf_seek(b, b->cursor + o);
14963 static stbtt_uint32 stbtt__buf_get(stbtt__buf *b,
int n)
14965 stbtt_uint32 v = 0;
14967 STBTT_assert(n >= 1 && n <= 4);
14968 for (i = 0; i < n; i++)
14969 v = (v << 8) | stbtt__buf_get8(b);
14973 static stbtt__buf stbtt__new_buf(
const void *p,
size_t size)
14976 STBTT_assert(size < 0x40000000);
14977 r.data = (stbtt_uint8*) p;
14978 r.size = (int) size;
14983 #define stbtt__buf_get16(b) stbtt__buf_get((b), 2)
14984 #define stbtt__buf_get32(b) stbtt__buf_get((b), 4)
14986 static stbtt__buf stbtt__buf_range(
const stbtt__buf *b,
int o,
int s)
14988 stbtt__buf r = stbtt__new_buf(NULL, 0);
14989 if (o < 0 || s < 0 || o > b->size || s > b->size - o)
return r;
14990 r.data = b->data + o;
14995 static stbtt__buf stbtt__cff_get_index(stbtt__buf *b)
14997 int count, start, offsize;
14999 count = stbtt__buf_get16(b);
15001 offsize = stbtt__buf_get8(b);
15002 STBTT_assert(offsize >= 1 && offsize <= 4);
15003 stbtt__buf_skip(b, offsize * count);
15004 stbtt__buf_skip(b, stbtt__buf_get(b, offsize) - 1);
15006 return stbtt__buf_range(b, start, b->cursor - start);
15009 static stbtt_uint32 stbtt__cff_int(stbtt__buf *b)
15011 int b0 = stbtt__buf_get8(b);
15012 if (b0 >= 32 && b0 <= 246)
return b0 - 139;
15013 else if (b0 >= 247 && b0 <= 250)
return (b0 - 247)*256 + stbtt__buf_get8(b) + 108;
15014 else if (b0 >= 251 && b0 <= 254)
return -(b0 - 251)*256 - stbtt__buf_get8(b) - 108;
15015 else if (b0 == 28)
return stbtt__buf_get16(b);
15016 else if (b0 == 29)
return stbtt__buf_get32(b);
15021 static void stbtt__cff_skip_operand(stbtt__buf *b) {
15022 int v, b0 = stbtt__buf_peek8(b);
15023 STBTT_assert(b0 >= 28);
15025 stbtt__buf_skip(b, 1);
15026 while (b->cursor < b->size) {
15027 v = stbtt__buf_get8(b);
15028 if ((v & 0xF) == 0xF || (v >> 4) == 0xF)
15036 static stbtt__buf stbtt__dict_get(stbtt__buf *b,
int key)
15038 stbtt__buf_seek(b, 0);
15039 while (b->cursor < b->size) {
15040 int start = b->cursor, end, op;
15041 while (stbtt__buf_peek8(b) >= 28)
15042 stbtt__cff_skip_operand(b);
15044 op = stbtt__buf_get8(b);
15045 if (op == 12) op = stbtt__buf_get8(b) | 0x100;
15046 if (op == key)
return stbtt__buf_range(b, start, end-start);
15048 return stbtt__buf_range(b, 0, 0);
15051 static void stbtt__dict_get_ints(stbtt__buf *b,
int key,
int outcount, stbtt_uint32 *out)
15054 stbtt__buf operands = stbtt__dict_get(b, key);
15055 for (i = 0; i < outcount && operands.cursor < operands.size; i++)
15056 out[i] = stbtt__cff_int(&operands);
15059 static int stbtt__cff_index_count(stbtt__buf *b)
15061 stbtt__buf_seek(b, 0);
15062 return stbtt__buf_get16(b);
15065 static stbtt__buf stbtt__cff_index_get(stbtt__buf b,
int i)
15067 int count, offsize, start, end;
15068 stbtt__buf_seek(&b, 0);
15069 count = stbtt__buf_get16(&b);
15070 offsize = stbtt__buf_get8(&b);
15071 STBTT_assert(i >= 0 && i < count);
15072 STBTT_assert(offsize >= 1 && offsize <= 4);
15073 stbtt__buf_skip(&b, i*offsize);
15074 start = stbtt__buf_get(&b, offsize);
15075 end = stbtt__buf_get(&b, offsize);
15076 return stbtt__buf_range(&b, 2+(count+1)*offsize+start, end - start);
15087 #define ttBYTE(p) (* (stbtt_uint8 *) (p))
15088 #define ttCHAR(p) (* (stbtt_int8 *) (p))
15089 #define ttFixed(p) ttLONG(p)
15091 static stbtt_uint16 ttUSHORT(stbtt_uint8 *p) {
return p[0]*256 + p[1]; }
15092 static stbtt_int16 ttSHORT(stbtt_uint8 *p) {
return p[0]*256 + p[1]; }
15093 static stbtt_uint32 ttULONG(stbtt_uint8 *p) {
return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
15094 static stbtt_int32 ttLONG(stbtt_uint8 *p) {
return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
15096 #define stbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3))
15097 #define stbtt_tag(p,str) stbtt_tag4(p,str[0],str[1],str[2],str[3])
15099 static int stbtt__isfont(stbtt_uint8 *font)
15102 if (stbtt_tag4(font,
'1',0,0,0))
return 1;
15103 if (stbtt_tag(font,
"typ1"))
return 1;
15104 if (stbtt_tag(font,
"OTTO"))
return 1;
15105 if (stbtt_tag4(font, 0,1,0,0))
return 1;
15106 if (stbtt_tag(font,
"true"))
return 1;
15111 static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart,
const char *tag)
15113 stbtt_int32 num_tables = ttUSHORT(data+fontstart+4);
15114 stbtt_uint32 tabledir = fontstart + 12;
15116 for (i=0; i < num_tables; ++i) {
15117 stbtt_uint32 loc = tabledir + 16*i;
15118 if (stbtt_tag(data+loc+0, tag))
15119 return ttULONG(data+loc+8);
15124 static int stbtt_GetFontOffsetForIndex_internal(
unsigned char *font_collection,
int index)
15127 if (stbtt__isfont(font_collection))
15128 return index == 0 ? 0 : -1;
15131 if (stbtt_tag(font_collection,
"ttcf")) {
15133 if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) {
15134 stbtt_int32 n = ttLONG(font_collection+8);
15137 return ttULONG(font_collection+12+index*4);
15143 static int stbtt_GetNumberOfFonts_internal(
unsigned char *font_collection)
15146 if (stbtt__isfont(font_collection))
15150 if (stbtt_tag(font_collection,
"ttcf")) {
15152 if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) {
15153 return ttLONG(font_collection+8);
15159 static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict)
15161 stbtt_uint32 subrsoff = 0, private_loc[2] = { 0, 0 };
15163 stbtt__dict_get_ints(&fontdict, 18, 2, private_loc);
15164 if (!private_loc[1] || !private_loc[0])
return stbtt__new_buf(NULL, 0);
15165 pdict = stbtt__buf_range(&cff, private_loc[1], private_loc[0]);
15166 stbtt__dict_get_ints(&pdict, 19, 1, &subrsoff);
15167 if (!subrsoff)
return stbtt__new_buf(NULL, 0);
15168 stbtt__buf_seek(&cff, private_loc[1]+subrsoff);
15169 return stbtt__cff_get_index(&cff);
15173 static int stbtt__get_svg(stbtt_fontinfo *info)
15176 if (info->svg < 0) {
15177 t = stbtt__find_table(info->data, info->fontstart,
"SVG ");
15179 stbtt_uint32 offset = ttULONG(info->data + t + 2);
15180 info->svg = t + offset;
15188 static int stbtt_InitFont_internal(stbtt_fontinfo *info,
unsigned char *data,
int fontstart)
15190 stbtt_uint32 cmap, t;
15191 stbtt_int32 i,numTables;
15194 info->fontstart = fontstart;
15195 info->cff = stbtt__new_buf(NULL, 0);
15197 cmap = stbtt__find_table(data, fontstart,
"cmap");
15198 info->loca = stbtt__find_table(data, fontstart,
"loca");
15199 info->head = stbtt__find_table(data, fontstart,
"head");
15200 info->glyf = stbtt__find_table(data, fontstart,
"glyf");
15201 info->hhea = stbtt__find_table(data, fontstart,
"hhea");
15202 info->hmtx = stbtt__find_table(data, fontstart,
"hmtx");
15203 info->kern = stbtt__find_table(data, fontstart,
"kern");
15204 info->gpos = stbtt__find_table(data, fontstart,
"GPOS");
15206 if (!cmap || !info->head || !info->hhea || !info->hmtx)
15210 if (!info->loca)
return 0;
15213 stbtt__buf b, topdict, topdictidx;
15214 stbtt_uint32 cstype = 2, charstrings = 0, fdarrayoff = 0, fdselectoff = 0;
15217 cff = stbtt__find_table(data, fontstart,
"CFF ");
15218 if (!cff)
return 0;
15220 info->fontdicts = stbtt__new_buf(NULL, 0);
15221 info->fdselect = stbtt__new_buf(NULL, 0);
15224 info->cff = stbtt__new_buf(data+cff, 512*1024*1024);
15228 stbtt__buf_skip(&b, 2);
15229 stbtt__buf_seek(&b, stbtt__buf_get8(&b));
15233 stbtt__cff_get_index(&b);
15234 topdictidx = stbtt__cff_get_index(&b);
15235 topdict = stbtt__cff_index_get(topdictidx, 0);
15236 stbtt__cff_get_index(&b);
15237 info->gsubrs = stbtt__cff_get_index(&b);
15239 stbtt__dict_get_ints(&topdict, 17, 1, &charstrings);
15240 stbtt__dict_get_ints(&topdict, 0x100 | 6, 1, &cstype);
15241 stbtt__dict_get_ints(&topdict, 0x100 | 36, 1, &fdarrayoff);
15242 stbtt__dict_get_ints(&topdict, 0x100 | 37, 1, &fdselectoff);
15243 info->subrs = stbtt__get_subrs(b, topdict);
15246 if (cstype != 2)
return 0;
15247 if (charstrings == 0)
return 0;
15251 if (!fdselectoff)
return 0;
15252 stbtt__buf_seek(&b, fdarrayoff);
15253 info->fontdicts = stbtt__cff_get_index(&b);
15254 info->fdselect = stbtt__buf_range(&b, fdselectoff, b.size-fdselectoff);
15257 stbtt__buf_seek(&b, charstrings);
15258 info->charstrings = stbtt__cff_get_index(&b);
15261 t = stbtt__find_table(data, fontstart,
"maxp");
15263 info->numGlyphs = ttUSHORT(data+t+4);
15265 info->numGlyphs = 0xffff;
15272 numTables = ttUSHORT(data + cmap + 2);
15273 info->index_map = 0;
15274 for (i=0; i < numTables; ++i) {
15275 stbtt_uint32 encoding_record = cmap + 4 + 8 * i;
15277 switch(ttUSHORT(data+encoding_record)) {
15278 case STBTT_PLATFORM_ID_MICROSOFT:
15279 switch (ttUSHORT(data+encoding_record+2)) {
15280 case STBTT_MS_EID_UNICODE_BMP:
15281 case STBTT_MS_EID_UNICODE_FULL:
15283 info->index_map = cmap + ttULONG(data+encoding_record+4);
15287 case STBTT_PLATFORM_ID_UNICODE:
15290 info->index_map = cmap + ttULONG(data+encoding_record+4);
15294 if (info->index_map == 0)
15297 info->indexToLocFormat = ttUSHORT(data+info->head + 50);
15301 STBTT_DEF
int stbtt_FindGlyphIndex(
const stbtt_fontinfo *info,
int unicode_codepoint)
15303 stbtt_uint8 *data = info->data;
15304 stbtt_uint32 index_map = info->index_map;
15306 stbtt_uint16 format = ttUSHORT(data + index_map + 0);
15308 stbtt_int32 bytes = ttUSHORT(data + index_map + 2);
15309 if (unicode_codepoint < bytes-6)
15310 return ttBYTE(data + index_map + 6 + unicode_codepoint);
15312 }
else if (format == 6) {
15313 stbtt_uint32 first = ttUSHORT(data + index_map + 6);
15314 stbtt_uint32 count = ttUSHORT(data + index_map + 8);
15315 if ((stbtt_uint32) unicode_codepoint >= first && (stbtt_uint32) unicode_codepoint < first+count)
15316 return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first)*2);
15318 }
else if (format == 2) {
15321 }
else if (format == 4) {
15322 stbtt_uint16 segcount = ttUSHORT(data+index_map+6) >> 1;
15323 stbtt_uint16 searchRange = ttUSHORT(data+index_map+8) >> 1;
15324 stbtt_uint16 entrySelector = ttUSHORT(data+index_map+10);
15325 stbtt_uint16 rangeShift = ttUSHORT(data+index_map+12) >> 1;
15328 stbtt_uint32 endCount = index_map + 14;
15329 stbtt_uint32 search = endCount;
15331 if (unicode_codepoint > 0xffff)
15336 if (unicode_codepoint >= ttUSHORT(data + search + rangeShift*2))
15337 search += rangeShift*2;
15341 while (entrySelector) {
15344 end = ttUSHORT(data + search + searchRange*2);
15345 if (unicode_codepoint > end)
15346 search += searchRange*2;
15352 stbtt_uint16 offset, start, last;
15353 stbtt_uint16 item = (stbtt_uint16) ((search - endCount) >> 1);
15355 start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
15356 last = ttUSHORT(data + endCount + 2*item);
15357 if (unicode_codepoint < start || unicode_codepoint > last)
15360 offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item);
15362 return (stbtt_uint16) (unicode_codepoint + ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item));
15364 return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
15366 }
else if (format == 12 || format == 13) {
15367 stbtt_uint32 ngroups = ttULONG(data+index_map+12);
15368 stbtt_int32 low,high;
15369 low = 0; high = (stbtt_int32)ngroups;
15371 while (low < high) {
15372 stbtt_int32 mid = low + ((high-low) >> 1);
15373 stbtt_uint32 start_char = ttULONG(data+index_map+16+mid*12);
15374 stbtt_uint32 end_char = ttULONG(data+index_map+16+mid*12+4);
15375 if ((stbtt_uint32) unicode_codepoint < start_char)
15377 else if ((stbtt_uint32) unicode_codepoint > end_char)
15380 stbtt_uint32 start_glyph = ttULONG(data+index_map+16+mid*12+8);
15382 return start_glyph + unicode_codepoint-start_char;
15384 return start_glyph;
15394 STBTT_DEF
int stbtt_GetCodepointShape(
const stbtt_fontinfo *info,
int unicode_codepoint, stbtt_vertex **vertices)
15396 return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices);
15399 static void stbtt_setvertex(stbtt_vertex *v, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy)
15402 v->x = (stbtt_int16) x;
15403 v->y = (stbtt_int16) y;
15404 v->cx = (stbtt_int16) cx;
15405 v->cy = (stbtt_int16) cy;
15408 static int stbtt__GetGlyfOffset(
const stbtt_fontinfo *info,
int glyph_index)
15412 STBTT_assert(!info->cff.size);
15414 if (glyph_index >= info->numGlyphs)
return -1;
15415 if (info->indexToLocFormat >= 2)
return -1;
15417 if (info->indexToLocFormat == 0) {
15418 g1 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2) * 2;
15419 g2 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2;
15421 g1 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4);
15422 g2 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4 + 4);
15425 return g1==g2 ? -1 : g1;
15428 static int stbtt__GetGlyphInfoT2(
const stbtt_fontinfo *info,
int glyph_index,
int *x0,
int *y0,
int *x1,
int *y1);
15430 STBTT_DEF
int stbtt_GetGlyphBox(
const stbtt_fontinfo *info,
int glyph_index,
int *x0,
int *y0,
int *x1,
int *y1)
15432 if (info->cff.size) {
15433 stbtt__GetGlyphInfoT2(info, glyph_index, x0, y0, x1, y1);
15435 int g = stbtt__GetGlyfOffset(info, glyph_index);
15436 if (g < 0)
return 0;
15438 if (x0) *x0 = ttSHORT(info->data + g + 2);
15439 if (y0) *y0 = ttSHORT(info->data + g + 4);
15440 if (x1) *x1 = ttSHORT(info->data + g + 6);
15441 if (y1) *y1 = ttSHORT(info->data + g + 8);
15446 STBTT_DEF
int stbtt_GetCodepointBox(
const stbtt_fontinfo *info,
int codepoint,
int *x0,
int *y0,
int *x1,
int *y1)
15448 return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info,codepoint), x0,y0,x1,y1);
15451 STBTT_DEF
int stbtt_IsGlyphEmpty(
const stbtt_fontinfo *info,
int glyph_index)
15453 stbtt_int16 numberOfContours;
15455 if (info->cff.size)
15456 return stbtt__GetGlyphInfoT2(info, glyph_index, NULL, NULL, NULL, NULL) == 0;
15457 g = stbtt__GetGlyfOffset(info, glyph_index);
15458 if (g < 0)
return 1;
15459 numberOfContours = ttSHORT(info->data + g);
15460 return numberOfContours == 0;
15463 static int stbtt__close_shape(stbtt_vertex *vertices,
int num_vertices,
int was_off,
int start_off,
15464 stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy)
15468 stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy);
15469 stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx,sy,scx,scy);
15472 stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve,sx,sy,cx,cy);
15474 stbtt_setvertex(&vertices[num_vertices++], STBTT_vline,sx,sy,0,0);
15476 return num_vertices;
15479 static int stbtt__GetGlyphShapeTT(
const stbtt_fontinfo *info,
int glyph_index, stbtt_vertex **pvertices)
15481 stbtt_int16 numberOfContours;
15482 stbtt_uint8 *endPtsOfContours;
15483 stbtt_uint8 *data = info->data;
15484 stbtt_vertex *vertices=0;
15485 int num_vertices=0;
15486 int g = stbtt__GetGlyfOffset(info, glyph_index);
15490 if (g < 0)
return 0;
15492 numberOfContours = ttSHORT(data + g);
15494 if (numberOfContours > 0) {
15495 stbtt_uint8 flags=0,flagcount;
15496 stbtt_int32 ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0;
15497 stbtt_int32 x,y,cx,cy,sx,sy, scx,scy;
15498 stbtt_uint8 *points;
15499 endPtsOfContours = (data + g + 10);
15500 ins = ttUSHORT(data + g + 10 + numberOfContours * 2);
15501 points = data + g + 10 + numberOfContours * 2 + 2 + ins;
15503 n = 1+ttUSHORT(endPtsOfContours + numberOfContours*2-2);
15505 m = n + 2*numberOfContours;
15506 vertices = (stbtt_vertex *) STBTT_malloc(m *
sizeof(vertices[0]), info->userdata);
15521 for (i=0; i < n; ++i) {
15522 if (flagcount == 0) {
15525 flagcount = *points++;
15528 vertices[off+i].type = flags;
15533 for (i=0; i < n; ++i) {
15534 flags = vertices[off+i].type;
15536 stbtt_int16 dx = *points++;
15537 x += (flags & 16) ? dx : -dx;
15539 if (!(flags & 16)) {
15540 x = x + (stbtt_int16) (points[0]*256 + points[1]);
15544 vertices[off+i].x = (stbtt_int16) x;
15549 for (i=0; i < n; ++i) {
15550 flags = vertices[off+i].type;
15552 stbtt_int16 dy = *points++;
15553 y += (flags & 32) ? dy : -dy;
15555 if (!(flags & 32)) {
15556 y = y + (stbtt_int16) (points[0]*256 + points[1]);
15560 vertices[off+i].y = (stbtt_int16) y;
15565 sx = sy = cx = cy = scx = scy = 0;
15566 for (i=0; i < n; ++i) {
15567 flags = vertices[off+i].type;
15568 x = (stbtt_int16) vertices[off+i].x;
15569 y = (stbtt_int16) vertices[off+i].y;
15571 if (next_move == i) {
15573 num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
15576 start_off = !(flags & 1);
15582 if (!(vertices[off+i+1].type & 1)) {
15584 sx = (x + (stbtt_int32) vertices[off+i+1].x) >> 1;
15585 sy = (y + (stbtt_int32) vertices[off+i+1].y) >> 1;
15588 sx = (stbtt_int32) vertices[off+i+1].x;
15589 sy = (stbtt_int32) vertices[off+i+1].y;
15596 stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove,sx,sy,0,0);
15598 next_move = 1 + ttUSHORT(endPtsOfContours+j*2);
15601 if (!(flags & 1)) {
15603 stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy);
15609 stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x,y, cx, cy);
15611 stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x,y,0,0);
15616 num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
15617 }
else if (numberOfContours < 0) {
15620 stbtt_uint8 *comp = data + g + 10;
15624 stbtt_uint16 flags, gidx;
15625 int comp_num_verts = 0, i;
15626 stbtt_vertex *comp_verts = 0, *tmp = 0;
15627 float mtx[6] = {1,0,0,1,0,0}, m, n;
15629 flags = ttSHORT(comp); comp+=2;
15630 gidx = ttSHORT(comp); comp+=2;
15634 mtx[4] = ttSHORT(comp); comp+=2;
15635 mtx[5] = ttSHORT(comp); comp+=2;
15637 mtx[4] = ttCHAR(comp); comp+=1;
15638 mtx[5] = ttCHAR(comp); comp+=1;
15645 if (flags & (1<<3)) {
15646 mtx[0] = mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
15647 mtx[1] = mtx[2] = 0;
15648 }
else if (flags & (1<<6)) {
15649 mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
15650 mtx[1] = mtx[2] = 0;
15651 mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
15652 }
else if (flags & (1<<7)) {
15653 mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
15654 mtx[1] = ttSHORT(comp)/16384.0f; comp+=2;
15655 mtx[2] = ttSHORT(comp)/16384.0f; comp+=2;
15656 mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
15660 m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
15661 n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
15664 comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts);
15665 if (comp_num_verts > 0) {
15667 for (i = 0; i < comp_num_verts; ++i) {
15668 stbtt_vertex* v = &comp_verts[i];
15669 stbtt_vertex_type x,y;
15671 v->x = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
15672 v->y = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
15674 v->cx = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
15675 v->cy = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
15678 tmp = (stbtt_vertex*)STBTT_malloc((num_vertices+comp_num_verts)*
sizeof(stbtt_vertex), info->userdata);
15680 if (vertices) STBTT_free(vertices, info->userdata);
15681 if (comp_verts) STBTT_free(comp_verts, info->userdata);
15684 if (num_vertices > 0 && vertices) STBTT_memcpy(tmp, vertices, num_vertices*
sizeof(stbtt_vertex));
15685 STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*
sizeof(stbtt_vertex));
15686 if (vertices) STBTT_free(vertices, info->userdata);
15688 STBTT_free(comp_verts, info->userdata);
15689 num_vertices += comp_num_verts;
15692 more = flags & (1<<5);
15698 *pvertices = vertices;
15699 return num_vertices;
15706 float first_x, first_y;
15708 stbtt_int32 min_x, max_x, min_y, max_y;
15710 stbtt_vertex *pvertices;
15714 #define STBTT__CSCTX_INIT(bounds) {bounds,0, 0,0, 0,0, 0,0,0,0, NULL, 0}
15716 static void stbtt__track_vertex(stbtt__csctx *c, stbtt_int32 x, stbtt_int32 y)
15718 if (x > c->max_x || !c->started) c->max_x = x;
15719 if (y > c->max_y || !c->started) c->max_y = y;
15720 if (x < c->min_x || !c->started) c->min_x = x;
15721 if (y < c->min_y || !c->started) c->min_y = y;
15725 static void stbtt__csctx_v(stbtt__csctx *c, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy, stbtt_int32 cx1, stbtt_int32 cy1)
15728 stbtt__track_vertex(c, x, y);
15729 if (type == STBTT_vcubic) {
15730 stbtt__track_vertex(c, cx, cy);
15731 stbtt__track_vertex(c, cx1, cy1);
15734 stbtt_setvertex(&c->pvertices[c->num_vertices], type, x, y, cx, cy);
15735 c->pvertices[c->num_vertices].cx1 = (stbtt_int16) cx1;
15736 c->pvertices[c->num_vertices].cy1 = (stbtt_int16) cy1;
15741 static void stbtt__csctx_close_shape(stbtt__csctx *ctx)
15743 if (ctx->first_x != ctx->x || ctx->first_y != ctx->y)
15744 stbtt__csctx_v(ctx, STBTT_vline, (
int)ctx->first_x, (
int)ctx->first_y, 0, 0, 0, 0);
15747 static void stbtt__csctx_rmove_to(stbtt__csctx *ctx,
float dx,
float dy)
15749 stbtt__csctx_close_shape(ctx);
15750 ctx->first_x = ctx->x = ctx->x + dx;
15751 ctx->first_y = ctx->y = ctx->y + dy;
15752 stbtt__csctx_v(ctx, STBTT_vmove, (
int)ctx->x, (
int)ctx->y, 0, 0, 0, 0);
15755 static void stbtt__csctx_rline_to(stbtt__csctx *ctx,
float dx,
float dy)
15759 stbtt__csctx_v(ctx, STBTT_vline, (
int)ctx->x, (
int)ctx->y, 0, 0, 0, 0);
15762 static void stbtt__csctx_rccurve_to(stbtt__csctx *ctx,
float dx1,
float dy1,
float dx2,
float dy2,
float dx3,
float dy3)
15764 float cx1 = ctx->x + dx1;
15765 float cy1 = ctx->y + dy1;
15766 float cx2 = cx1 + dx2;
15767 float cy2 = cy1 + dy2;
15768 ctx->x = cx2 + dx3;
15769 ctx->y = cy2 + dy3;
15770 stbtt__csctx_v(ctx, STBTT_vcubic, (
int)ctx->x, (
int)ctx->y, (
int)cx1, (
int)cy1, (
int)cx2, (
int)cy2);
15773 static stbtt__buf stbtt__get_subr(stbtt__buf idx,
int n)
15775 int count = stbtt__cff_index_count(&idx);
15777 if (count >= 33900)
15779 else if (count >= 1240)
15782 if (n < 0 || n >= count)
15783 return stbtt__new_buf(NULL, 0);
15784 return stbtt__cff_index_get(idx, n);
15787 static stbtt__buf stbtt__cid_get_glyph_subrs(
const stbtt_fontinfo *info,
int glyph_index)
15789 stbtt__buf fdselect = info->fdselect;
15790 int nranges, start, end, v, fmt, fdselector = -1, i;
15792 stbtt__buf_seek(&fdselect, 0);
15793 fmt = stbtt__buf_get8(&fdselect);
15796 stbtt__buf_skip(&fdselect, glyph_index);
15797 fdselector = stbtt__buf_get8(&fdselect);
15798 }
else if (fmt == 3) {
15799 nranges = stbtt__buf_get16(&fdselect);
15800 start = stbtt__buf_get16(&fdselect);
15801 for (i = 0; i < nranges; i++) {
15802 v = stbtt__buf_get8(&fdselect);
15803 end = stbtt__buf_get16(&fdselect);
15804 if (glyph_index >= start && glyph_index < end) {
15811 if (fdselector == -1) stbtt__new_buf(NULL, 0);
15812 return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector));
15815 static int stbtt__run_charstring(
const stbtt_fontinfo *info,
int glyph_index, stbtt__csctx *c)
15817 int in_header = 1, maskbits = 0, subr_stack_height = 0, sp = 0, v, i, b0;
15818 int has_subrs = 0, clear_stack;
15820 stbtt__buf subr_stack[10], subrs = info->subrs, b;
15823 #define STBTT__CSERR(s) (0)
15826 b = stbtt__cff_index_get(info->charstrings, glyph_index);
15827 while (b.cursor < b.size) {
15830 b0 = stbtt__buf_get8(&b);
15836 maskbits += (sp / 2);
15838 stbtt__buf_skip(&b, (maskbits + 7) / 8);
15845 maskbits += (sp / 2);
15850 if (sp < 2)
return STBTT__CSERR(
"rmoveto stack");
15851 stbtt__csctx_rmove_to(c, s[sp-2], s[sp-1]);
15855 if (sp < 1)
return STBTT__CSERR(
"vmoveto stack");
15856 stbtt__csctx_rmove_to(c, 0, s[sp-1]);
15860 if (sp < 1)
return STBTT__CSERR(
"hmoveto stack");
15861 stbtt__csctx_rmove_to(c, s[sp-1], 0);
15865 if (sp < 2)
return STBTT__CSERR(
"rlineto stack");
15866 for (; i + 1 < sp; i += 2)
15867 stbtt__csctx_rline_to(c, s[i], s[i+1]);
15874 if (sp < 1)
return STBTT__CSERR(
"vlineto stack");
15877 if (sp < 1)
return STBTT__CSERR(
"hlineto stack");
15879 if (i >= sp)
break;
15880 stbtt__csctx_rline_to(c, s[i], 0);
15883 if (i >= sp)
break;
15884 stbtt__csctx_rline_to(c, 0, s[i]);
15890 if (sp < 4)
return STBTT__CSERR(
"hvcurveto stack");
15893 if (sp < 4)
return STBTT__CSERR(
"vhcurveto stack");
15895 if (i + 3 >= sp)
break;
15896 stbtt__csctx_rccurve_to(c, 0, s[i], s[i+1], s[i+2], s[i+3], (sp - i == 5) ? s[i + 4] : 0.0f);
15899 if (i + 3 >= sp)
break;
15900 stbtt__csctx_rccurve_to(c, s[i], 0, s[i+1], s[i+2], (sp - i == 5) ? s[i+4] : 0.0f, s[i+3]);
15906 if (sp < 6)
return STBTT__CSERR(
"rcurveline stack");
15907 for (; i + 5 < sp; i += 6)
15908 stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]);
15912 if (sp < 8)
return STBTT__CSERR(
"rcurveline stack");
15913 for (; i + 5 < sp - 2; i += 6)
15914 stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]);
15915 if (i + 1 >= sp)
return STBTT__CSERR(
"rcurveline stack");
15916 stbtt__csctx_rline_to(c, s[i], s[i+1]);
15920 if (sp < 8)
return STBTT__CSERR(
"rlinecurve stack");
15921 for (; i + 1 < sp - 6; i += 2)
15922 stbtt__csctx_rline_to(c, s[i], s[i+1]);
15923 if (i + 5 >= sp)
return STBTT__CSERR(
"rlinecurve stack");
15924 stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]);
15929 if (sp < 4)
return STBTT__CSERR(
"(vv|hh)curveto stack");
15931 if (sp & 1) { f = s[i]; i++; }
15932 for (; i + 3 < sp; i += 4) {
15934 stbtt__csctx_rccurve_to(c, s[i], f, s[i+1], s[i+2], s[i+3], 0.0);
15936 stbtt__csctx_rccurve_to(c, f, s[i], s[i+1], s[i+2], 0.0, s[i+3]);
15943 if (info->fdselect.size)
15944 subrs = stbtt__cid_get_glyph_subrs(info, glyph_index);
15949 if (sp < 1)
return STBTT__CSERR(
"call(g|)subr stack");
15951 if (subr_stack_height >= 10)
return STBTT__CSERR(
"recursion limit");
15952 subr_stack[subr_stack_height++] = b;
15953 b = stbtt__get_subr(b0 == 0x0A ? subrs : info->gsubrs, v);
15954 if (b.size == 0)
return STBTT__CSERR(
"subr not found");
15960 if (subr_stack_height <= 0)
return STBTT__CSERR(
"return outside subr");
15961 b = subr_stack[--subr_stack_height];
15966 stbtt__csctx_close_shape(c);
15970 float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy3, dy4, dy5, dy6;
15972 int b1 = stbtt__buf_get8(&b);
15977 if (sp < 7)
return STBTT__CSERR(
"hflex stack");
15985 stbtt__csctx_rccurve_to(c, dx1, 0, dx2, dy2, dx3, 0);
15986 stbtt__csctx_rccurve_to(c, dx4, 0, dx5, -dy2, dx6, 0);
15990 if (sp < 13)
return STBTT__CSERR(
"flex stack");
16004 stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3);
16005 stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6);
16009 if (sp < 9)
return STBTT__CSERR(
"hflex1 stack");
16019 stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, 0);
16020 stbtt__csctx_rccurve_to(c, dx4, 0, dx5, dy5, dx6, -(dy1+dy2+dy5));
16024 if (sp < 11)
return STBTT__CSERR(
"flex1 stack");
16036 dx = dx1+dx2+dx3+dx4+dx5;
16037 dy = dy1+dy2+dy3+dy4+dy5;
16038 if (STBTT_fabs(dx) > STBTT_fabs(dy))
16042 stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3);
16043 stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6);
16047 return STBTT__CSERR(
"unimplemented");
16052 if (b0 != 255 && b0 != 28 && b0 < 32)
16053 return STBTT__CSERR(
"reserved operator");
16057 f = (float)(stbtt_int32)stbtt__buf_get32(&b) / 0x10000;
16059 stbtt__buf_skip(&b, -1);
16060 f = (float)(stbtt_int16)stbtt__cff_int(&b);
16062 if (sp >= 48)
return STBTT__CSERR(
"push stack overflow");
16067 if (clear_stack) sp = 0;
16069 return STBTT__CSERR(
"no endchar");
16071 #undef STBTT__CSERR
16074 static int stbtt__GetGlyphShapeT2(
const stbtt_fontinfo *info,
int glyph_index, stbtt_vertex **pvertices)
16077 stbtt__csctx count_ctx = STBTT__CSCTX_INIT(1);
16078 stbtt__csctx output_ctx = STBTT__CSCTX_INIT(0);
16079 if (stbtt__run_charstring(info, glyph_index, &count_ctx)) {
16080 *pvertices = (stbtt_vertex*)STBTT_malloc(count_ctx.num_vertices*
sizeof(stbtt_vertex), info->userdata);
16081 output_ctx.pvertices = *pvertices;
16082 if (stbtt__run_charstring(info, glyph_index, &output_ctx)) {
16083 STBTT_assert(output_ctx.num_vertices == count_ctx.num_vertices);
16084 return output_ctx.num_vertices;
16091 static int stbtt__GetGlyphInfoT2(
const stbtt_fontinfo *info,
int glyph_index,
int *x0,
int *y0,
int *x1,
int *y1)
16093 stbtt__csctx c = STBTT__CSCTX_INIT(1);
16094 int r = stbtt__run_charstring(info, glyph_index, &c);
16095 if (x0) *x0 = r ? c.min_x : 0;
16096 if (y0) *y0 = r ? c.min_y : 0;
16097 if (x1) *x1 = r ? c.max_x : 0;
16098 if (y1) *y1 = r ? c.max_y : 0;
16099 return r ? c.num_vertices : 0;
16102 STBTT_DEF
int stbtt_GetGlyphShape(
const stbtt_fontinfo *info,
int glyph_index, stbtt_vertex **pvertices)
16104 if (!info->cff.size)
16105 return stbtt__GetGlyphShapeTT(info, glyph_index, pvertices);
16107 return stbtt__GetGlyphShapeT2(info, glyph_index, pvertices);
16110 STBTT_DEF
void stbtt_GetGlyphHMetrics(
const stbtt_fontinfo *info,
int glyph_index,
int *advanceWidth,
int *leftSideBearing)
16112 stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data+info->hhea + 34);
16113 if (glyph_index < numOfLongHorMetrics) {
16114 if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*glyph_index);
16115 if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*glyph_index + 2);
16117 if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1));
16118 if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics));
16122 STBTT_DEF
int stbtt_GetKerningTableLength(
const stbtt_fontinfo *info)
16124 stbtt_uint8 *data = info->data + info->kern;
16129 if (ttUSHORT(data+2) < 1)
16131 if (ttUSHORT(data+8) != 1)
16134 return ttUSHORT(data+10);
16137 STBTT_DEF
int stbtt_GetKerningTable(
const stbtt_fontinfo *info, stbtt_kerningentry* table,
int table_length)
16139 stbtt_uint8 *data = info->data + info->kern;
16145 if (ttUSHORT(data+2) < 1)
16147 if (ttUSHORT(data+8) != 1)
16150 length = ttUSHORT(data+10);
16151 if (table_length < length)
16152 length = table_length;
16154 for (k = 0; k < length; k++)
16156 table[k].glyph1 = ttUSHORT(data+18+(k*6));
16157 table[k].glyph2 = ttUSHORT(data+20+(k*6));
16158 table[k].advance = ttSHORT(data+22+(k*6));
16164 static int stbtt__GetGlyphKernInfoAdvance(
const stbtt_fontinfo *info,
int glyph1,
int glyph2)
16166 stbtt_uint8 *data = info->data + info->kern;
16167 stbtt_uint32 needle, straw;
16173 if (ttUSHORT(data+2) < 1)
16175 if (ttUSHORT(data+8) != 1)
16179 r = ttUSHORT(data+10) - 1;
16180 needle = glyph1 << 16 | glyph2;
16183 straw = ttULONG(data+18+(m*6));
16184 if (needle < straw)
16186 else if (needle > straw)
16189 return ttSHORT(data+22+(m*6));
16194 static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable,
int glyph)
16196 stbtt_uint16 coverageFormat = ttUSHORT(coverageTable);
16197 switch (coverageFormat) {
16199 stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2);
16202 stbtt_int32 l=0, r=glyphCount-1, m;
16203 int straw, needle=glyph;
16205 stbtt_uint8 *glyphArray = coverageTable + 4;
16206 stbtt_uint16 glyphID;
16208 glyphID = ttUSHORT(glyphArray + 2 * m);
16210 if (needle < straw)
16212 else if (needle > straw)
16222 stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2);
16223 stbtt_uint8 *rangeArray = coverageTable + 4;
16226 stbtt_int32 l=0, r=rangeCount-1, m;
16227 int strawStart, strawEnd, needle=glyph;
16229 stbtt_uint8 *rangeRecord;
16231 rangeRecord = rangeArray + 6 * m;
16232 strawStart = ttUSHORT(rangeRecord);
16233 strawEnd = ttUSHORT(rangeRecord + 2);
16234 if (needle < strawStart)
16236 else if (needle > strawEnd)
16239 stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4);
16240 return startCoverageIndex + glyph - strawStart;
16246 default:
return -1;
16252 static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable,
int glyph)
16254 stbtt_uint16 classDefFormat = ttUSHORT(classDefTable);
16255 switch (classDefFormat)
16258 stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2);
16259 stbtt_uint16 glyphCount = ttUSHORT(classDefTable + 4);
16260 stbtt_uint8 *classDef1ValueArray = classDefTable + 6;
16262 if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount)
16263 return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID));
16268 stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2);
16269 stbtt_uint8 *classRangeRecords = classDefTable + 4;
16272 stbtt_int32 l=0, r=classRangeCount-1, m;
16273 int strawStart, strawEnd, needle=glyph;
16275 stbtt_uint8 *classRangeRecord;
16277 classRangeRecord = classRangeRecords + 6 * m;
16278 strawStart = ttUSHORT(classRangeRecord);
16279 strawEnd = ttUSHORT(classRangeRecord + 2);
16280 if (needle < strawStart)
16282 else if (needle > strawEnd)
16285 return (stbtt_int32)ttUSHORT(classRangeRecord + 4);
16299 #define STBTT_GPOS_TODO_assert(x)
16301 static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(
const stbtt_fontinfo *info,
int glyph1,
int glyph2)
16303 stbtt_uint16 lookupListOffset;
16304 stbtt_uint8 *lookupList;
16305 stbtt_uint16 lookupCount;
16307 stbtt_int32 i, sti;
16309 if (!info->gpos)
return 0;
16311 data = info->data + info->gpos;
16313 if (ttUSHORT(data+0) != 1)
return 0;
16314 if (ttUSHORT(data+2) != 0)
return 0;
16316 lookupListOffset = ttUSHORT(data+8);
16317 lookupList = data + lookupListOffset;
16318 lookupCount = ttUSHORT(lookupList);
16320 for (i=0; i<lookupCount; ++i) {
16321 stbtt_uint16 lookupOffset = ttUSHORT(lookupList + 2 + 2 * i);
16322 stbtt_uint8 *lookupTable = lookupList + lookupOffset;
16324 stbtt_uint16 lookupType = ttUSHORT(lookupTable);
16325 stbtt_uint16 subTableCount = ttUSHORT(lookupTable + 4);
16326 stbtt_uint8 *subTableOffsets = lookupTable + 6;
16327 if (lookupType != 2)
16330 for (sti=0; sti<subTableCount; sti++) {
16331 stbtt_uint16 subtableOffset = ttUSHORT(subTableOffsets + 2 * sti);
16332 stbtt_uint8 *table = lookupTable + subtableOffset;
16333 stbtt_uint16 posFormat = ttUSHORT(table);
16334 stbtt_uint16 coverageOffset = ttUSHORT(table + 2);
16335 stbtt_int32 coverageIndex = stbtt__GetCoverageIndex(table + coverageOffset, glyph1);
16336 if (coverageIndex == -1)
continue;
16338 switch (posFormat) {
16340 stbtt_int32 l, r, m;
16342 stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
16343 stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
16344 if (valueFormat1 == 4 && valueFormat2 == 0) {
16345 stbtt_int32 valueRecordPairSizeInBytes = 2;
16346 stbtt_uint16 pairSetCount = ttUSHORT(table + 8);
16347 stbtt_uint16 pairPosOffset = ttUSHORT(table + 10 + 2 * coverageIndex);
16348 stbtt_uint8 *pairValueTable = table + pairPosOffset;
16349 stbtt_uint16 pairValueCount = ttUSHORT(pairValueTable);
16350 stbtt_uint8 *pairValueArray = pairValueTable + 2;
16352 if (coverageIndex >= pairSetCount)
return 0;
16355 r=pairValueCount-1;
16360 stbtt_uint16 secondGlyph;
16361 stbtt_uint8 *pairValue;
16363 pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m;
16364 secondGlyph = ttUSHORT(pairValue);
16365 straw = secondGlyph;
16366 if (needle < straw)
16368 else if (needle > straw)
16371 stbtt_int16 xAdvance = ttSHORT(pairValue + 2);
16381 stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
16382 stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
16383 if (valueFormat1 == 4 && valueFormat2 == 0) {
16384 stbtt_uint16 classDef1Offset = ttUSHORT(table + 8);
16385 stbtt_uint16 classDef2Offset = ttUSHORT(table + 10);
16386 int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1);
16387 int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2);
16389 stbtt_uint16 class1Count = ttUSHORT(table + 12);
16390 stbtt_uint16 class2Count = ttUSHORT(table + 14);
16391 stbtt_uint8 *class1Records, *class2Records;
16392 stbtt_int16 xAdvance;
16394 if (glyph1class < 0 || glyph1class >= class1Count)
return 0;
16395 if (glyph2class < 0 || glyph2class >= class2Count)
return 0;
16397 class1Records = table + 16;
16398 class2Records = class1Records + 2 * (glyph1class * class2Count);
16399 xAdvance = ttSHORT(class2Records + 2 * glyph2class);
16415 STBTT_DEF
int stbtt_GetGlyphKernAdvance(
const stbtt_fontinfo *info,
int g1,
int g2)
16420 xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2);
16421 else if (info->kern)
16422 xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2);
16427 STBTT_DEF
int stbtt_GetCodepointKernAdvance(
const stbtt_fontinfo *info,
int ch1,
int ch2)
16429 if (!info->kern && !info->gpos)
16431 return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2));
16434 STBTT_DEF
void stbtt_GetCodepointHMetrics(
const stbtt_fontinfo *info,
int codepoint,
int *advanceWidth,
int *leftSideBearing)
16436 stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info,codepoint), advanceWidth, leftSideBearing);
16439 STBTT_DEF
void stbtt_GetFontVMetrics(
const stbtt_fontinfo *info,
int *ascent,
int *descent,
int *lineGap)
16441 if (ascent ) *ascent = ttSHORT(info->data+info->hhea + 4);
16442 if (descent) *descent = ttSHORT(info->data+info->hhea + 6);
16443 if (lineGap) *lineGap = ttSHORT(info->data+info->hhea + 8);
16446 STBTT_DEF
int stbtt_GetFontVMetricsOS2(
const stbtt_fontinfo *info,
int *typoAscent,
int *typoDescent,
int *typoLineGap)
16448 int tab = stbtt__find_table(info->data, info->fontstart,
"OS/2");
16451 if (typoAscent ) *typoAscent = ttSHORT(info->data+tab + 68);
16452 if (typoDescent) *typoDescent = ttSHORT(info->data+tab + 70);
16453 if (typoLineGap) *typoLineGap = ttSHORT(info->data+tab + 72);
16457 STBTT_DEF
void stbtt_GetFontBoundingBox(
const stbtt_fontinfo *info,
int *x0,
int *y0,
int *x1,
int *y1)
16459 *x0 = ttSHORT(info->data + info->head + 36);
16460 *y0 = ttSHORT(info->data + info->head + 38);
16461 *x1 = ttSHORT(info->data + info->head + 40);
16462 *y1 = ttSHORT(info->data + info->head + 42);
16465 STBTT_DEF
float stbtt_ScaleForPixelHeight(
const stbtt_fontinfo *info,
float height)
16467 int fheight = ttSHORT(info->data + info->hhea + 4) - ttSHORT(info->data + info->hhea + 6);
16468 return (
float) height / fheight;
16471 STBTT_DEF
float stbtt_ScaleForMappingEmToPixels(
const stbtt_fontinfo *info,
float pixels)
16473 int unitsPerEm = ttUSHORT(info->data + info->head + 18);
16474 return pixels / unitsPerEm;
16477 STBTT_DEF
void stbtt_FreeShape(
const stbtt_fontinfo *info, stbtt_vertex *v)
16479 STBTT_free(v, info->userdata);
16482 STBTT_DEF stbtt_uint8 *stbtt_FindSVGDoc(
const stbtt_fontinfo *info,
int gl)
16485 stbtt_uint8 *data = info->data;
16486 stbtt_uint8 *svg_doc_list = data + stbtt__get_svg((stbtt_fontinfo *) info);
16488 int numEntries = ttUSHORT(svg_doc_list);
16489 stbtt_uint8 *svg_docs = svg_doc_list + 2;
16491 for(i=0; i<numEntries; i++) {
16492 stbtt_uint8 *svg_doc = svg_docs + (12 * i);
16493 if ((gl >= ttUSHORT(svg_doc)) && (gl <= ttUSHORT(svg_doc + 2)))
16499 STBTT_DEF
int stbtt_GetGlyphSVG(
const stbtt_fontinfo *info,
int gl,
const char **svg)
16501 stbtt_uint8 *data = info->data;
16502 stbtt_uint8 *svg_doc;
16504 if (info->svg == 0)
16507 svg_doc = stbtt_FindSVGDoc(info, gl);
16508 if (svg_doc != NULL) {
16509 *svg = (
char *) data + info->svg + ttULONG(svg_doc + 4);
16510 return ttULONG(svg_doc + 8);
16516 STBTT_DEF
int stbtt_GetCodepointSVG(
const stbtt_fontinfo *info,
int unicode_codepoint,
const char **svg)
16518 return stbtt_GetGlyphSVG(info, stbtt_FindGlyphIndex(info, unicode_codepoint), svg);
16526 STBTT_DEF
void stbtt_GetGlyphBitmapBoxSubpixel(
const stbtt_fontinfo *font,
int glyph,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int *ix0,
int *iy0,
int *ix1,
int *iy1)
16528 int x0=0,y0=0,x1,y1;
16529 if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) {
16537 if (ix0) *ix0 = STBTT_ifloor( x0 * scale_x + shift_x);
16538 if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y);
16539 if (ix1) *ix1 = STBTT_iceil ( x1 * scale_x + shift_x);
16540 if (iy1) *iy1 = STBTT_iceil (-y0 * scale_y + shift_y);
16544 STBTT_DEF
void stbtt_GetGlyphBitmapBox(
const stbtt_fontinfo *font,
int glyph,
float scale_x,
float scale_y,
int *ix0,
int *iy0,
int *ix1,
int *iy1)
16546 stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1);
16549 STBTT_DEF
void stbtt_GetCodepointBitmapBoxSubpixel(
const stbtt_fontinfo *font,
int codepoint,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int *ix0,
int *iy0,
int *ix1,
int *iy1)
16551 stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font,codepoint), scale_x, scale_y,shift_x,shift_y, ix0,iy0,ix1,iy1);
16554 STBTT_DEF
void stbtt_GetCodepointBitmapBox(
const stbtt_fontinfo *font,
int codepoint,
float scale_x,
float scale_y,
int *ix0,
int *iy0,
int *ix1,
int *iy1)
16556 stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y,0.0f,0.0f, ix0,iy0,ix1,iy1);
16563 typedef struct stbtt__hheap_chunk
16565 struct stbtt__hheap_chunk *next;
16566 } stbtt__hheap_chunk;
16568 typedef struct stbtt__hheap
16570 struct stbtt__hheap_chunk *head;
16572 int num_remaining_in_head_chunk;
16575 static void *stbtt__hheap_alloc(stbtt__hheap *hh,
size_t size,
void *userdata)
16577 if (hh->first_free) {
16578 void *p = hh->first_free;
16579 hh->first_free = * (
void **) p;
16582 if (hh->num_remaining_in_head_chunk == 0) {
16583 int count = (size < 32 ? 2000 : size < 128 ? 800 : 100);
16584 stbtt__hheap_chunk *c = (stbtt__hheap_chunk *) STBTT_malloc(
sizeof(stbtt__hheap_chunk) + size * count, userdata);
16587 c->next = hh->head;
16589 hh->num_remaining_in_head_chunk = count;
16591 --hh->num_remaining_in_head_chunk;
16592 return (
char *) (hh->head) +
sizeof(stbtt__hheap_chunk) + size * hh->num_remaining_in_head_chunk;
16596 static void stbtt__hheap_free(stbtt__hheap *hh,
void *p)
16598 *(
void **) p = hh->first_free;
16599 hh->first_free = p;
16602 static void stbtt__hheap_cleanup(stbtt__hheap *hh,
void *userdata)
16604 stbtt__hheap_chunk *c = hh->head;
16606 stbtt__hheap_chunk *n = c->next;
16607 STBTT_free(c, userdata);
16612 typedef struct stbtt__edge {
16613 float x0,y0, x1,y1;
16618 typedef struct stbtt__active_edge
16620 struct stbtt__active_edge *next;
16621 #if STBTT_RASTERIZER_VERSION==1
16625 #elif STBTT_RASTERIZER_VERSION==2
16631 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
16633 } stbtt__active_edge;
16635 #if STBTT_RASTERIZER_VERSION == 1
16636 #define STBTT_FIXSHIFT 10
16637 #define STBTT_FIX (1 << STBTT_FIXSHIFT)
16638 #define STBTT_FIXMASK (STBTT_FIX-1)
16640 static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e,
int off_x,
float start_point,
void *userdata)
16642 stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh,
sizeof(*z), userdata);
16643 float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
16644 STBTT_assert(z != NULL);
16649 z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy);
16651 z->dx = STBTT_ifloor(STBTT_FIX * dxdy);
16653 z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point - e->y0));
16654 z->x -= off_x * STBTT_FIX;
16658 z->direction = e->invert ? 1 : -1;
16661 #elif STBTT_RASTERIZER_VERSION == 2
16662 static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e,
int off_x,
float start_point,
void *userdata)
16664 stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh,
sizeof(*z), userdata);
16665 float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
16666 STBTT_assert(z != NULL);
16670 z->fdy = dxdy != 0.0f ? (1.0f/dxdy) : 0.0f;
16671 z->fx = e->x0 + dxdy * (start_point - e->y0);
16673 z->direction = e->invert ? 1.0f : -1.0f;
16680 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
16683 #if STBTT_RASTERIZER_VERSION == 1
16687 static void stbtt__fill_active_edges(
unsigned char *scanline,
int len, stbtt__active_edge *e,
int max_weight)
16695 x0 = e->x; w += e->direction;
16697 int x1 = e->x; w += e->direction;
16700 int i = x0 >> STBTT_FIXSHIFT;
16701 int j = x1 >> STBTT_FIXSHIFT;
16703 if (i < len && j >= 0) {
16706 scanline[i] = scanline[i] + (stbtt_uint8) ((x1 - x0) * max_weight >> STBTT_FIXSHIFT);
16709 scanline[i] = scanline[i] + (stbtt_uint8) (((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT);
16714 scanline[j] = scanline[j] + (stbtt_uint8) (((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_FIXSHIFT);
16718 for (++i; i < j; ++i)
16719 scanline[i] = scanline[i] + (stbtt_uint8) max_weight;
16729 static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
int n,
int vsubsample,
int off_x,
int off_y,
void *userdata)
16731 stbtt__hheap hh = { 0, 0, 0 };
16732 stbtt__active_edge *active = NULL;
16734 int max_weight = (255 / vsubsample);
16736 unsigned char scanline_data[512], *scanline;
16738 if (result->w > 512)
16739 scanline = (
unsigned char *) STBTT_malloc(result->w, userdata);
16741 scanline = scanline_data;
16743 y = off_y * vsubsample;
16744 e[n].y0 = (off_y + result->h) * (
float) vsubsample + 1;
16746 while (j < result->h) {
16747 STBTT_memset(scanline, 0, result->w);
16748 for (s=0; s < vsubsample; ++s) {
16750 float scan_y = y + 0.5f;
16751 stbtt__active_edge **step = &active;
16756 stbtt__active_edge * z = *step;
16757 if (z->ey <= scan_y) {
16759 STBTT_assert(z->direction);
16761 stbtt__hheap_free(&hh, z);
16764 step = &((*step)->next);
16772 while (*step && (*step)->next) {
16773 if ((*step)->x > (*step)->next->x) {
16774 stbtt__active_edge *t = *step;
16775 stbtt__active_edge *q = t->next;
16782 step = &(*step)->next;
16784 if (!changed)
break;
16788 while (e->y0 <= scan_y) {
16789 if (e->y1 > scan_y) {
16790 stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata);
16793 if (active == NULL)
16795 else if (z->x < active->x) {
16801 stbtt__active_edge *p = active;
16802 while (p->next && p->next->x < z->x)
16815 stbtt__fill_active_edges(scanline, result->w, active, max_weight);
16819 STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w);
16823 stbtt__hheap_cleanup(&hh, userdata);
16825 if (scanline != scanline_data)
16826 STBTT_free(scanline, userdata);
16829 #elif STBTT_RASTERIZER_VERSION == 2
16833 static void stbtt__handle_clipped_edge(
float *scanline,
int x, stbtt__active_edge *e,
float x0,
float y0,
float x1,
float y1)
16835 if (y0 == y1)
return;
16836 STBTT_assert(y0 < y1);
16837 STBTT_assert(e->sy <= e->ey);
16838 if (y0 > e->ey)
return;
16839 if (y1 < e->sy)
return;
16841 x0 += (x1-x0) * (e->sy - y0) / (y1-y0);
16845 x1 += (x1-x0) * (e->ey - y1) / (y1-y0);
16850 STBTT_assert(x1 <= x+1);
16851 else if (x0 == x+1)
16852 STBTT_assert(x1 >= x);
16854 STBTT_assert(x1 <= x);
16855 else if (x0 >= x+1)
16856 STBTT_assert(x1 >= x+1);
16858 STBTT_assert(x1 >= x && x1 <= x+1);
16860 if (x0 <= x && x1 <= x)
16861 scanline[x] += e->direction * (y1-y0);
16862 else if (x0 >= x+1 && x1 >= x+1)
16865 STBTT_assert(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1);
16866 scanline[x] += e->direction * (y1-y0) * (1-((x0-x)+(x1-x))/2);
16870 static float stbtt__sized_trapezoid_area(
float height,
float top_width,
float bottom_width)
16872 STBTT_assert(top_width >= 0);
16873 STBTT_assert(bottom_width >= 0);
16874 return (top_width + bottom_width) / 2.0f * height;
16877 static float stbtt__position_trapezoid_area(
float height,
float tx0,
float tx1,
float bx0,
float bx1)
16879 return stbtt__sized_trapezoid_area(height, tx1 - tx0, bx1 - bx0);
16882 static float stbtt__sized_triangle_area(
float height,
float width)
16884 return height * width / 2;
16887 static void stbtt__fill_active_edges_new(
float *scanline,
float *scanline_fill,
int len, stbtt__active_edge *e,
float y_top)
16889 float y_bottom = y_top+1;
16895 STBTT_assert(e->ey >= y_top);
16901 stbtt__handle_clipped_edge(scanline,(
int) x0,e, x0,y_top, x0,y_bottom);
16902 stbtt__handle_clipped_edge(scanline_fill-1,(
int) x0+1,e, x0,y_top, x0,y_bottom);
16904 stbtt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom);
16910 float xb = x0 + dx;
16911 float x_top, x_bottom;
16914 STBTT_assert(e->sy <= y_bottom && e->ey >= y_top);
16919 if (e->sy > y_top) {
16920 x_top = x0 + dx * (e->sy - y_top);
16926 if (e->ey < y_bottom) {
16927 x_bottom = x0 + dx * (e->ey - y_top);
16934 if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) {
16937 if ((
int) x_top == (int) x_bottom) {
16940 int x = (int) x_top;
16941 height = (sy1 - sy0) * e->direction;
16942 STBTT_assert(x >= 0 && x < len);
16943 scanline[x] += stbtt__position_trapezoid_area(height, x_top, x+1.0f, x_bottom, x+1.0f);
16944 scanline_fill[x] += height;
16947 float y_crossing, y_final, step, sign, area;
16949 if (x_top > x_bottom) {
16952 sy0 = y_bottom - (sy0 - y_top);
16953 sy1 = y_bottom - (sy1 - y_top);
16954 t = sy0, sy0 = sy1, sy1 = t;
16955 t = x_bottom, x_bottom = x_top, x_top = t;
16958 t = x0, x0 = xb, xb = t;
16960 STBTT_assert(dy >= 0);
16961 STBTT_assert(dx >= 0);
16964 x2 = (int) x_bottom;
16966 y_crossing = y_top + dy * (x1+1 - x0);
16969 y_final = y_top + dy * (x2 - x0);
16990 if (y_crossing > y_bottom)
16991 y_crossing = y_bottom;
16993 sign = e->direction;
16996 area = sign * (y_crossing-sy0);
16999 scanline[x1] += stbtt__sized_triangle_area(area, x1+1 - x_top);
17002 if (y_final > y_bottom) {
17003 y_final = y_bottom;
17004 dy = (y_final - y_crossing ) / (x2 - (x1+1));
17017 step = sign * dy * 1;
17021 for (x = x1+1; x < x2; ++x) {
17022 scanline[x] += area + step/2;
17025 STBTT_assert(STBTT_fabs(area) <= 1.01f);
17026 STBTT_assert(sy1 > y_final-0.01f);
17030 scanline[x2] += area + sign * stbtt__position_trapezoid_area(sy1-y_final, (
float) x2, x2+1.0f, x_bottom, x2+1.0f);
17033 scanline_fill[x2] += sign * (sy1-sy0);
17044 for (x=0; x < len; ++x) {
17060 float x1 = (float) (x);
17061 float x2 = (float) (x+1);
17063 float y3 = y_bottom;
17068 float y1 = (x - x0) / dx + y_top;
17069 float y2 = (x+1 - x0) / dx + y_top;
17071 if (x0 < x1 && x3 > x2) {
17072 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
17073 stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x2,y2);
17074 stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
17075 }
else if (x3 < x1 && x0 > x2) {
17076 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
17077 stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x1,y1);
17078 stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
17079 }
else if (x0 < x1 && x3 > x1) {
17080 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
17081 stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
17082 }
else if (x3 < x1 && x0 > x1) {
17083 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
17084 stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
17085 }
else if (x0 < x2 && x3 > x2) {
17086 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
17087 stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
17088 }
else if (x3 < x2 && x0 > x2) {
17089 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
17090 stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
17092 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x3,y3);
17102 static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
int n,
int vsubsample,
int off_x,
int off_y,
void *userdata)
17104 stbtt__hheap hh = { 0, 0, 0 };
17105 stbtt__active_edge *active = NULL;
17107 float scanline_data[129], *scanline, *scanline2;
17109 STBTT__NOTUSED(vsubsample);
17111 if (result->w > 64)
17112 scanline = (
float *) STBTT_malloc((result->w*2+1) *
sizeof(float), userdata);
17114 scanline = scanline_data;
17116 scanline2 = scanline + result->w;
17119 e[n].y0 = (float) (off_y + result->h) + 1;
17121 while (j < result->h) {
17123 float scan_y_top = y + 0.0f;
17124 float scan_y_bottom = y + 1.0f;
17125 stbtt__active_edge **step = &active;
17127 STBTT_memset(scanline , 0, result->w*
sizeof(scanline[0]));
17128 STBTT_memset(scanline2, 0, (result->w+1)*
sizeof(scanline[0]));
17133 stbtt__active_edge * z = *step;
17134 if (z->ey <= scan_y_top) {
17136 STBTT_assert(z->direction);
17138 stbtt__hheap_free(&hh, z);
17140 step = &((*step)->next);
17145 while (e->y0 <= scan_y_bottom) {
17146 if (e->y0 != e->y1) {
17147 stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
17149 if (j == 0 && off_y != 0) {
17150 if (z->ey < scan_y_top) {
17152 z->ey = scan_y_top;
17155 STBTT_assert(z->ey >= scan_y_top);
17166 stbtt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top);
17170 for (i=0; i < result->w; ++i) {
17173 sum += scanline2[i];
17174 k = scanline[i] + sum;
17175 k = (float) STBTT_fabs(k)*255 + 0.5f;
17177 if (m > 255) m = 255;
17178 result->pixels[j*result->stride + i] = (
unsigned char) m;
17184 stbtt__active_edge *z = *step;
17186 step = &((*step)->next);
17193 stbtt__hheap_cleanup(&hh, userdata);
17195 if (scanline != scanline_data)
17196 STBTT_free(scanline, userdata);
17199 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
17202 #define STBTT__COMPARE(a,b) ((a)->y0 < (b)->y0)
17204 static void stbtt__sort_edges_ins_sort(stbtt__edge *p,
int n)
17207 for (i=1; i < n; ++i) {
17208 stbtt__edge t = p[i], *a = &t;
17211 stbtt__edge *b = &p[j-1];
17212 int c = STBTT__COMPARE(a,b);
17222 static void stbtt__sort_edges_quicksort(stbtt__edge *p,
int n)
17227 int c01,c12,c,m,i,j;
17231 c01 = STBTT__COMPARE(&p[0],&p[m]);
17232 c12 = STBTT__COMPARE(&p[m],&p[n-1]);
17237 c = STBTT__COMPARE(&p[0],&p[n-1]);
17240 z = (c == c12) ? 0 : n-1;
17258 if (!STBTT__COMPARE(&p[i], &p[0]))
break;
17261 if (!STBTT__COMPARE(&p[0], &p[j]))
break;
17274 stbtt__sort_edges_quicksort(p,j);
17278 stbtt__sort_edges_quicksort(p+i, n-i);
17284 static void stbtt__sort_edges(stbtt__edge *p,
int n)
17286 stbtt__sort_edges_quicksort(p, n);
17287 stbtt__sort_edges_ins_sort(p, n);
17295 static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts,
int *wcount,
int windings,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int off_x,
int off_y,
int invert,
void *userdata)
17297 float y_scale_inv = invert ? -scale_y : scale_y;
17300 #if STBTT_RASTERIZER_VERSION == 1
17301 int vsubsample = result->h < 8 ? 15 : 5;
17302 #elif STBTT_RASTERIZER_VERSION == 2
17303 int vsubsample = 1;
17305 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
17311 for (i=0; i < windings; ++i)
17314 e = (stbtt__edge *) STBTT_malloc(
sizeof(*e) * (n+1), userdata);
17315 if (e == 0)
return;
17319 for (i=0; i < windings; ++i) {
17320 stbtt__point *p = pts + m;
17323 for (k=0; k < wcount[i]; j=k++) {
17326 if (p[j].y == p[k].y)
17330 if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) {
17334 e[n].x0 = p[a].x * scale_x + shift_x;
17335 e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample;
17336 e[n].x1 = p[b].x * scale_x + shift_x;
17337 e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample;
17344 stbtt__sort_edges(e, n);
17347 stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata);
17349 STBTT_free(e, userdata);
17352 static void stbtt__add_point(stbtt__point *points,
int n,
float x,
float y)
17354 if (!points)
return;
17360 static int stbtt__tesselate_curve(stbtt__point *points,
int *num_points,
float x0,
float y0,
float x1,
float y1,
float x2,
float y2,
float objspace_flatness_squared,
int n)
17363 float mx = (x0 + 2*x1 + x2)/4;
17364 float my = (y0 + 2*y1 + y2)/4;
17366 float dx = (x0+x2)/2 - mx;
17367 float dy = (y0+y2)/2 - my;
17370 if (dx*dx+dy*dy > objspace_flatness_squared) {
17371 stbtt__tesselate_curve(points, num_points, x0,y0, (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1);
17372 stbtt__tesselate_curve(points, num_points, mx,my, (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1);
17374 stbtt__add_point(points, *num_points,x2,y2);
17375 *num_points = *num_points+1;
17380 static void stbtt__tesselate_cubic(stbtt__point *points,
int *num_points,
float x0,
float y0,
float x1,
float y1,
float x2,
float y2,
float x3,
float y3,
float objspace_flatness_squared,
int n)
17391 float longlen = (float) (STBTT_sqrt(dx0*dx0+dy0*dy0)+STBTT_sqrt(dx1*dx1+dy1*dy1)+STBTT_sqrt(dx2*dx2+dy2*dy2));
17392 float shortlen = (float) STBTT_sqrt(dx*dx+dy*dy);
17393 float flatness_squared = longlen*longlen-shortlen*shortlen;
17398 if (flatness_squared > objspace_flatness_squared) {
17399 float x01 = (x0+x1)/2;
17400 float y01 = (y0+y1)/2;
17401 float x12 = (x1+x2)/2;
17402 float y12 = (y1+y2)/2;
17403 float x23 = (x2+x3)/2;
17404 float y23 = (y2+y3)/2;
17406 float xa = (x01+x12)/2;
17407 float ya = (y01+y12)/2;
17408 float xb = (x12+x23)/2;
17409 float yb = (y12+y23)/2;
17411 float mx = (xa+xb)/2;
17412 float my = (ya+yb)/2;
17414 stbtt__tesselate_cubic(points, num_points, x0,y0, x01,y01, xa,ya, mx,my, objspace_flatness_squared,n+1);
17415 stbtt__tesselate_cubic(points, num_points, mx,my, xb,yb, x23,y23, x3,y3, objspace_flatness_squared,n+1);
17417 stbtt__add_point(points, *num_points,x3,y3);
17418 *num_points = *num_points+1;
17423 static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices,
int num_verts,
float objspace_flatness,
int **contour_lengths,
int *num_contours,
void *userdata)
17425 stbtt__point *points=0;
17428 float objspace_flatness_squared = objspace_flatness * objspace_flatness;
17429 int i,n=0,start=0, pass;
17432 for (i=0; i < num_verts; ++i)
17433 if (vertices[i].type == STBTT_vmove)
17437 if (n == 0)
return 0;
17439 *contour_lengths = (
int *) STBTT_malloc(
sizeof(**contour_lengths) * n, userdata);
17441 if (*contour_lengths == 0) {
17447 for (pass=0; pass < 2; ++pass) {
17450 points = (stbtt__point *) STBTT_malloc(num_points *
sizeof(points[0]), userdata);
17451 if (points == NULL)
goto error;
17455 for (i=0; i < num_verts; ++i) {
17456 switch (vertices[i].type) {
17460 (*contour_lengths)[n] = num_points - start;
17462 start = num_points;
17464 x = vertices[i].x, y = vertices[i].y;
17465 stbtt__add_point(points, num_points++, x,y);
17468 x = vertices[i].x, y = vertices[i].y;
17469 stbtt__add_point(points, num_points++, x, y);
17472 stbtt__tesselate_curve(points, &num_points, x,y,
17473 vertices[i].cx, vertices[i].cy,
17474 vertices[i].x, vertices[i].y,
17475 objspace_flatness_squared, 0);
17476 x = vertices[i].x, y = vertices[i].y;
17479 stbtt__tesselate_cubic(points, &num_points, x,y,
17480 vertices[i].cx, vertices[i].cy,
17481 vertices[i].cx1, vertices[i].cy1,
17482 vertices[i].x, vertices[i].y,
17483 objspace_flatness_squared, 0);
17484 x = vertices[i].x, y = vertices[i].y;
17488 (*contour_lengths)[n] = num_points - start;
17493 STBTT_free(points, userdata);
17494 STBTT_free(*contour_lengths, userdata);
17495 *contour_lengths = 0;
17500 STBTT_DEF
void stbtt_Rasterize(stbtt__bitmap *result,
float flatness_in_pixels, stbtt_vertex *vertices,
int num_verts,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int x_off,
int y_off,
int invert,
void *userdata)
17502 float scale = scale_x > scale_y ? scale_y : scale_x;
17503 int winding_count = 0;
17504 int *winding_lengths = NULL;
17505 stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata);
17507 stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata);
17508 STBTT_free(winding_lengths, userdata);
17509 STBTT_free(windings, userdata);
17513 STBTT_DEF
void stbtt_FreeBitmap(
unsigned char *bitmap,
void *userdata)
17515 STBTT_free(bitmap, userdata);
17518 STBTT_DEF
unsigned char *stbtt_GetGlyphBitmapSubpixel(
const stbtt_fontinfo *info,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int glyph,
int *width,
int *height,
int *xoff,
int *yoff)
17520 int ix0,iy0,ix1,iy1;
17522 stbtt_vertex *vertices;
17523 int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
17525 if (scale_x == 0) scale_x = scale_y;
17526 if (scale_y == 0) {
17527 if (scale_x == 0) {
17528 STBTT_free(vertices, info->userdata);
17534 stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,&ix1,&iy1);
17537 gbm.w = (ix1 - ix0);
17538 gbm.h = (iy1 - iy0);
17541 if (width ) *width = gbm.w;
17542 if (height) *height = gbm.h;
17543 if (xoff ) *xoff = ix0;
17544 if (yoff ) *yoff = iy0;
17546 if (gbm.w && gbm.h) {
17547 gbm.pixels = (
unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata);
17549 gbm.stride = gbm.w;
17551 stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata);
17554 STBTT_free(vertices, info->userdata);
17558 STBTT_DEF
unsigned char *stbtt_GetGlyphBitmap(
const stbtt_fontinfo *info,
float scale_x,
float scale_y,
int glyph,
int *width,
int *height,
int *xoff,
int *yoff)
17560 return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff);
17563 STBTT_DEF
void stbtt_MakeGlyphBitmapSubpixel(
const stbtt_fontinfo *info,
unsigned char *output,
int out_w,
int out_h,
int out_stride,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int glyph)
17566 stbtt_vertex *vertices;
17567 int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
17570 stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0);
17571 gbm.pixels = output;
17574 gbm.stride = out_stride;
17576 if (gbm.w && gbm.h)
17577 stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0,iy0, 1, info->userdata);
17579 STBTT_free(vertices, info->userdata);
17582 STBTT_DEF
void stbtt_MakeGlyphBitmap(
const stbtt_fontinfo *info,
unsigned char *output,
int out_w,
int out_h,
int out_stride,
float scale_x,
float scale_y,
int glyph)
17584 stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, glyph);
17587 STBTT_DEF
unsigned char *stbtt_GetCodepointBitmapSubpixel(
const stbtt_fontinfo *info,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int codepoint,
int *width,
int *height,
int *xoff,
int *yoff)
17589 return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff);
17592 STBTT_DEF
void stbtt_MakeCodepointBitmapSubpixelPrefilter(
const stbtt_fontinfo *info,
unsigned char *output,
int out_w,
int out_h,
int out_stride,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int oversample_x,
int oversample_y,
float *sub_x,
float *sub_y,
int codepoint)
17594 stbtt_MakeGlyphBitmapSubpixelPrefilter(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, oversample_x, oversample_y, sub_x, sub_y, stbtt_FindGlyphIndex(info,codepoint));
17597 STBTT_DEF
void stbtt_MakeCodepointBitmapSubpixel(
const stbtt_fontinfo *info,
unsigned char *output,
int out_w,
int out_h,
int out_stride,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int codepoint)
17599 stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint));
17602 STBTT_DEF
unsigned char *stbtt_GetCodepointBitmap(
const stbtt_fontinfo *info,
float scale_x,
float scale_y,
int codepoint,
int *width,
int *height,
int *xoff,
int *yoff)
17604 return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff);
17607 STBTT_DEF
void stbtt_MakeCodepointBitmap(
const stbtt_fontinfo *info,
unsigned char *output,
int out_w,
int out_h,
int out_stride,
float scale_x,
float scale_y,
int codepoint)
17609 stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, codepoint);
17618 static int stbtt_BakeFontBitmap_internal(
unsigned char *data,
int offset,
17619 float pixel_height,
17620 unsigned char *pixels,
int pw,
int ph,
17621 int first_char,
int num_chars,
17622 stbtt_bakedchar *chardata)
17625 int x,y,bottom_y, i;
17628 if (!stbtt_InitFont(&f, data, offset))
17630 STBTT_memset(pixels, 0, pw*ph);
17634 scale = stbtt_ScaleForPixelHeight(&f, pixel_height);
17636 for (i=0; i < num_chars; ++i) {
17637 int advance, lsb, x0,y0,x1,y1,gw,gh;
17638 int g = stbtt_FindGlyphIndex(&f, first_char + i);
17639 stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb);
17640 stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1);
17643 if (x + gw + 1 >= pw)
17644 y = bottom_y, x = 1;
17645 if (y + gh + 1 >= ph)
17647 STBTT_assert(x+gw < pw);
17648 STBTT_assert(y+gh < ph);
17649 stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g);
17650 chardata[i].x0 = (stbtt_int16) x;
17651 chardata[i].y0 = (stbtt_int16) y;
17652 chardata[i].x1 = (stbtt_int16) (x + gw);
17653 chardata[i].y1 = (stbtt_int16) (y + gh);
17654 chardata[i].xadvance = scale * advance;
17655 chardata[i].xoff = (float) x0;
17656 chardata[i].yoff = (float) y0;
17658 if (y+gh+1 > bottom_y)
17664 STBTT_DEF
void stbtt_GetBakedQuad(
const stbtt_bakedchar *chardata,
int pw,
int ph,
int char_index,
float *xpos,
float *ypos, stbtt_aligned_quad *q,
int opengl_fillrule)
17666 float d3d_bias = opengl_fillrule ? 0 : -0.5f;
17667 float ipw = 1.0f / pw, iph = 1.0f / ph;
17668 const stbtt_bakedchar *b = chardata + char_index;
17669 int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f);
17670 int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f);
17672 q->x0 = round_x + d3d_bias;
17673 q->y0 = round_y + d3d_bias;
17674 q->x1 = round_x + b->x1 - b->x0 + d3d_bias;
17675 q->y1 = round_y + b->y1 - b->y0 + d3d_bias;
17677 q->s0 = b->x0 * ipw;
17678 q->t0 = b->y0 * iph;
17679 q->s1 = b->x1 * ipw;
17680 q->t1 = b->y1 * iph;
17682 *xpos += b->xadvance;
17690 #ifndef STB_RECT_PACK_VERSION
17692 typedef int stbrp_coord;
17719 int id,w,h,was_packed;
17722 static void stbrp_init_target(stbrp_context *con,
int pw,
int ph, stbrp_node *nodes,
int num_nodes)
17729 STBTT__NOTUSED(nodes);
17730 STBTT__NOTUSED(num_nodes);
17733 static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects,
int num_rects)
17736 for (i=0; i < num_rects; ++i) {
17737 if (con->x + rects[i].w > con->width) {
17739 con->y = con->bottom_y;
17741 if (con->y + rects[i].h > con->height)
17743 rects[i].x = con->x;
17744 rects[i].y = con->y;
17745 rects[i].was_packed = 1;
17746 con->x += rects[i].w;
17747 if (con->y + rects[i].h > con->bottom_y)
17748 con->bottom_y = con->y + rects[i].h;
17750 for ( ; i < num_rects; ++i)
17751 rects[i].was_packed = 0;
17762 STBTT_DEF
int stbtt_PackBegin(stbtt_pack_context *spc,
unsigned char *pixels,
int pw,
int ph,
int stride_in_bytes,
int padding,
void *alloc_context)
17764 stbrp_context *context = (stbrp_context *) STBTT_malloc(
sizeof(*context) ,alloc_context);
17765 int num_nodes = pw - padding;
17766 stbrp_node *nodes = (stbrp_node *) STBTT_malloc(
sizeof(*nodes ) * num_nodes,alloc_context);
17768 if (context == NULL || nodes == NULL) {
17769 if (context != NULL) STBTT_free(context, alloc_context);
17770 if (nodes != NULL) STBTT_free(nodes , alloc_context);
17774 spc->user_allocator_context = alloc_context;
17777 spc->pixels = pixels;
17778 spc->pack_info = context;
17779 spc->nodes = nodes;
17780 spc->padding = padding;
17781 spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw;
17782 spc->h_oversample = 1;
17783 spc->v_oversample = 1;
17784 spc->skip_missing = 0;
17786 stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
17789 STBTT_memset(pixels, 0, pw*ph);
17794 STBTT_DEF
void stbtt_PackEnd (stbtt_pack_context *spc)
17796 STBTT_free(spc->nodes , spc->user_allocator_context);
17797 STBTT_free(spc->pack_info, spc->user_allocator_context);
17800 STBTT_DEF
void stbtt_PackSetOversampling(stbtt_pack_context *spc,
unsigned int h_oversample,
unsigned int v_oversample)
17802 STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE);
17803 STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE);
17804 if (h_oversample <= STBTT_MAX_OVERSAMPLE)
17805 spc->h_oversample = h_oversample;
17806 if (v_oversample <= STBTT_MAX_OVERSAMPLE)
17807 spc->v_oversample = v_oversample;
17810 STBTT_DEF
void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc,
int skip)
17812 spc->skip_missing = skip;
17815 #define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1)
17817 static void stbtt__h_prefilter(
unsigned char *pixels,
int w,
int h,
int stride_in_bytes,
unsigned int kernel_width)
17819 unsigned char buffer[STBTT_MAX_OVERSAMPLE];
17820 int safe_w = w - kernel_width;
17822 STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE);
17823 for (j=0; j < h; ++j) {
17825 unsigned int total;
17826 STBTT_memset(buffer, 0, kernel_width);
17831 switch (kernel_width) {
17833 for (i=0; i <= safe_w; ++i) {
17834 total += pixels[i] - buffer[i & STBTT__OVER_MASK];
17835 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
17836 pixels[i] = (
unsigned char) (total / 2);
17840 for (i=0; i <= safe_w; ++i) {
17841 total += pixels[i] - buffer[i & STBTT__OVER_MASK];
17842 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
17843 pixels[i] = (
unsigned char) (total / 3);
17847 for (i=0; i <= safe_w; ++i) {
17848 total += pixels[i] - buffer[i & STBTT__OVER_MASK];
17849 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
17850 pixels[i] = (
unsigned char) (total / 4);
17854 for (i=0; i <= safe_w; ++i) {
17855 total += pixels[i] - buffer[i & STBTT__OVER_MASK];
17856 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
17857 pixels[i] = (
unsigned char) (total / 5);
17861 for (i=0; i <= safe_w; ++i) {
17862 total += pixels[i] - buffer[i & STBTT__OVER_MASK];
17863 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
17864 pixels[i] = (
unsigned char) (total / kernel_width);
17869 for (; i < w; ++i) {
17870 STBTT_assert(pixels[i] == 0);
17871 total -= buffer[i & STBTT__OVER_MASK];
17872 pixels[i] = (
unsigned char) (total / kernel_width);
17875 pixels += stride_in_bytes;
17879 static void stbtt__v_prefilter(
unsigned char *pixels,
int w,
int h,
int stride_in_bytes,
unsigned int kernel_width)
17881 unsigned char buffer[STBTT_MAX_OVERSAMPLE];
17882 int safe_h = h - kernel_width;
17884 STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE);
17885 for (j=0; j < w; ++j) {
17887 unsigned int total;
17888 STBTT_memset(buffer, 0, kernel_width);
17893 switch (kernel_width) {
17895 for (i=0; i <= safe_h; ++i) {
17896 total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
17897 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
17898 pixels[i*stride_in_bytes] = (
unsigned char) (total / 2);
17902 for (i=0; i <= safe_h; ++i) {
17903 total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
17904 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
17905 pixels[i*stride_in_bytes] = (
unsigned char) (total / 3);
17909 for (i=0; i <= safe_h; ++i) {
17910 total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
17911 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
17912 pixels[i*stride_in_bytes] = (
unsigned char) (total / 4);
17916 for (i=0; i <= safe_h; ++i) {
17917 total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
17918 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
17919 pixels[i*stride_in_bytes] = (
unsigned char) (total / 5);
17923 for (i=0; i <= safe_h; ++i) {
17924 total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
17925 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
17926 pixels[i*stride_in_bytes] = (
unsigned char) (total / kernel_width);
17931 for (; i < h; ++i) {
17932 STBTT_assert(pixels[i*stride_in_bytes] == 0);
17933 total -= buffer[i & STBTT__OVER_MASK];
17934 pixels[i*stride_in_bytes] = (
unsigned char) (total / kernel_width);
17941 static float stbtt__oversample_shift(
int oversample)
17950 return (
float)-(oversample - 1) / (2.0f * (
float)oversample);
17954 STBTT_DEF
int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc,
const stbtt_fontinfo *info, stbtt_pack_range *ranges,
int num_ranges, stbrp_rect *rects)
17957 int missing_glyph_added = 0;
17960 for (i=0; i < num_ranges; ++i) {
17961 float fh = ranges[i].font_size;
17962 float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh);
17963 ranges[i].h_oversample = (
unsigned char) spc->h_oversample;
17964 ranges[i].v_oversample = (
unsigned char) spc->v_oversample;
17965 for (j=0; j < ranges[i].num_chars; ++j) {
17967 int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
17968 int glyph = stbtt_FindGlyphIndex(info, codepoint);
17969 if (glyph == 0 && (spc->skip_missing || missing_glyph_added)) {
17970 rects[k].w = rects[k].h = 0;
17972 stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
17973 scale * spc->h_oversample,
17974 scale * spc->v_oversample,
17977 rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
17978 rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
17980 missing_glyph_added = 1;
17989 STBTT_DEF
void stbtt_MakeGlyphBitmapSubpixelPrefilter(
const stbtt_fontinfo *info,
unsigned char *output,
int out_w,
int out_h,
int out_stride,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int prefilter_x,
int prefilter_y,
float *sub_x,
float *sub_y,
int glyph)
17991 stbtt_MakeGlyphBitmapSubpixel(info,
17993 out_w - (prefilter_x - 1),
17994 out_h - (prefilter_y - 1),
18002 if (prefilter_x > 1)
18003 stbtt__h_prefilter(output, out_w, out_h, out_stride, prefilter_x);
18005 if (prefilter_y > 1)
18006 stbtt__v_prefilter(output, out_w, out_h, out_stride, prefilter_y);
18008 *sub_x = stbtt__oversample_shift(prefilter_x);
18009 *sub_y = stbtt__oversample_shift(prefilter_y);
18013 STBTT_DEF
int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc,
const stbtt_fontinfo *info, stbtt_pack_range *ranges,
int num_ranges, stbrp_rect *rects)
18015 int i,j,k, missing_glyph = -1, return_value = 1;
18018 int old_h_over = spc->h_oversample;
18019 int old_v_over = spc->v_oversample;
18022 for (i=0; i < num_ranges; ++i) {
18023 float fh = ranges[i].font_size;
18024 float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh);
18025 float recip_h,recip_v,sub_x,sub_y;
18026 spc->h_oversample = ranges[i].h_oversample;
18027 spc->v_oversample = ranges[i].v_oversample;
18028 recip_h = 1.0f / spc->h_oversample;
18029 recip_v = 1.0f / spc->v_oversample;
18030 sub_x = stbtt__oversample_shift(spc->h_oversample);
18031 sub_y = stbtt__oversample_shift(spc->v_oversample);
18032 for (j=0; j < ranges[i].num_chars; ++j) {
18033 stbrp_rect *r = &rects[k];
18034 if (r->was_packed && r->w != 0 && r->h != 0) {
18035 stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
18036 int advance, lsb, x0,y0,x1,y1;
18037 int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
18038 int glyph = stbtt_FindGlyphIndex(info, codepoint);
18039 stbrp_coord pad = (stbrp_coord) spc->padding;
18046 stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb);
18047 stbtt_GetGlyphBitmapBox(info, glyph,
18048 scale * spc->h_oversample,
18049 scale * spc->v_oversample,
18051 stbtt_MakeGlyphBitmapSubpixel(info,
18052 spc->pixels + r->x + r->y*spc->stride_in_bytes,
18053 r->w - spc->h_oversample+1,
18054 r->h - spc->v_oversample+1,
18055 spc->stride_in_bytes,
18056 scale * spc->h_oversample,
18057 scale * spc->v_oversample,
18061 if (spc->h_oversample > 1)
18062 stbtt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
18063 r->w, r->h, spc->stride_in_bytes,
18064 spc->h_oversample);
18066 if (spc->v_oversample > 1)
18067 stbtt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
18068 r->w, r->h, spc->stride_in_bytes,
18069 spc->v_oversample);
18071 bc->x0 = (stbtt_int16) r->x;
18072 bc->y0 = (stbtt_int16) r->y;
18073 bc->x1 = (stbtt_int16) (r->x + r->w);
18074 bc->y1 = (stbtt_int16) (r->y + r->h);
18075 bc->xadvance = scale * advance;
18076 bc->xoff = (float) x0 * recip_h + sub_x;
18077 bc->yoff = (float) y0 * recip_v + sub_y;
18078 bc->xoff2 = (x0 + r->w) * recip_h + sub_x;
18079 bc->yoff2 = (y0 + r->h) * recip_v + sub_y;
18083 }
else if (spc->skip_missing) {
18085 }
else if (r->was_packed && r->w == 0 && r->h == 0 && missing_glyph >= 0) {
18086 ranges[i].chardata_for_range[j] = ranges[i].chardata_for_range[missing_glyph];
18096 spc->h_oversample = old_h_over;
18097 spc->v_oversample = old_v_over;
18099 return return_value;
18102 STBTT_DEF
void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects,
int num_rects)
18104 stbrp_pack_rects((stbrp_context *) spc->pack_info, rects, num_rects);
18107 STBTT_DEF
int stbtt_PackFontRanges(stbtt_pack_context *spc,
const unsigned char *fontdata,
int font_index, stbtt_pack_range *ranges,
int num_ranges)
18109 stbtt_fontinfo info;
18110 int i,j,n, return_value = 1;
18115 for (i=0; i < num_ranges; ++i)
18116 for (j=0; j < ranges[i].num_chars; ++j)
18117 ranges[i].chardata_for_range[j].x0 =
18118 ranges[i].chardata_for_range[j].y0 =
18119 ranges[i].chardata_for_range[j].x1 =
18120 ranges[i].chardata_for_range[j].y1 = 0;
18123 for (i=0; i < num_ranges; ++i)
18124 n += ranges[i].num_chars;
18126 rects = (stbrp_rect *) STBTT_malloc(
sizeof(*rects) * n, spc->user_allocator_context);
18130 info.userdata = spc->user_allocator_context;
18131 stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index));
18133 n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects);
18135 stbtt_PackFontRangesPackRects(spc, rects, n);
18137 return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects);
18139 STBTT_free(rects, spc->user_allocator_context);
18140 return return_value;
18143 STBTT_DEF
int stbtt_PackFontRange(stbtt_pack_context *spc,
const unsigned char *fontdata,
int font_index,
float font_size,
18144 int first_unicode_codepoint_in_range,
int num_chars_in_range, stbtt_packedchar *chardata_for_range)
18146 stbtt_pack_range range;
18147 range.first_unicode_codepoint_in_range = first_unicode_codepoint_in_range;
18148 range.array_of_unicode_codepoints = NULL;
18149 range.num_chars = num_chars_in_range;
18150 range.chardata_for_range = chardata_for_range;
18151 range.font_size = font_size;
18152 return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
18155 STBTT_DEF
void stbtt_GetScaledFontVMetrics(
const unsigned char *fontdata,
int index,
float size,
float *ascent,
float *descent,
float *lineGap)
18157 int i_ascent, i_descent, i_lineGap;
18159 stbtt_fontinfo info;
18160 stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, index));
18161 scale = size > 0 ? stbtt_ScaleForPixelHeight(&info, size) : stbtt_ScaleForMappingEmToPixels(&info, -size);
18162 stbtt_GetFontVMetrics(&info, &i_ascent, &i_descent, &i_lineGap);
18163 *ascent = (float) i_ascent * scale;
18164 *descent = (float) i_descent * scale;
18165 *lineGap = (float) i_lineGap * scale;
18168 STBTT_DEF
void stbtt_GetPackedQuad(
const stbtt_packedchar *chardata,
int pw,
int ph,
int char_index,
float *xpos,
float *ypos, stbtt_aligned_quad *q,
int align_to_integer)
18170 float ipw = 1.0f / pw, iph = 1.0f / ph;
18171 const stbtt_packedchar *b = chardata + char_index;
18173 if (align_to_integer) {
18174 float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5f);
18175 float y = (float) STBTT_ifloor((*ypos + b->yoff) + 0.5f);
18178 q->x1 = x + b->xoff2 - b->xoff;
18179 q->y1 = y + b->yoff2 - b->yoff;
18181 q->x0 = *xpos + b->xoff;
18182 q->y0 = *ypos + b->yoff;
18183 q->x1 = *xpos + b->xoff2;
18184 q->y1 = *ypos + b->yoff2;
18187 q->s0 = b->x0 * ipw;
18188 q->t0 = b->y0 * iph;
18189 q->s1 = b->x1 * ipw;
18190 q->t1 = b->y1 * iph;
18192 *xpos += b->xadvance;
18200 #define STBTT_min(a,b) ((a) < (b) ? (a) : (b))
18201 #define STBTT_max(a,b) ((a) < (b) ? (b) : (a))
18203 static int stbtt__ray_intersect_bezier(
float orig[2],
float ray[2],
float q0[2],
float q1[2],
float q2[2],
float hits[2][2])
18205 float q0perp = q0[1]*ray[0] - q0[0]*ray[1];
18206 float q1perp = q1[1]*ray[0] - q1[0]*ray[1];
18207 float q2perp = q2[1]*ray[0] - q2[0]*ray[1];
18208 float roperp = orig[1]*ray[0] - orig[0]*ray[1];
18210 float a = q0perp - 2*q1perp + q2perp;
18211 float b = q1perp - q0perp;
18212 float c = q0perp - roperp;
18214 float s0 = 0., s1 = 0.;
18218 float discr = b*b - a*c;
18220 float rcpna = -1 / a;
18221 float d = (float) STBTT_sqrt(discr);
18222 s0 = (b+d) * rcpna;
18223 s1 = (b-d) * rcpna;
18224 if (s0 >= 0.0 && s0 <= 1.0)
18226 if (d > 0.0 && s1 >= 0.0 && s1 <= 1.0) {
18227 if (num_s == 0) s0 = s1;
18235 if (s0 >= 0.0 && s0 <= 1.0)
18242 float rcp_len2 = 1 / (ray[0]*ray[0] + ray[1]*ray[1]);
18243 float rayn_x = ray[0] * rcp_len2, rayn_y = ray[1] * rcp_len2;
18245 float q0d = q0[0]*rayn_x + q0[1]*rayn_y;
18246 float q1d = q1[0]*rayn_x + q1[1]*rayn_y;
18247 float q2d = q2[0]*rayn_x + q2[1]*rayn_y;
18248 float rod = orig[0]*rayn_x + orig[1]*rayn_y;
18250 float q10d = q1d - q0d;
18251 float q20d = q2d - q0d;
18252 float q0rd = q0d - rod;
18254 hits[0][0] = q0rd + s0*(2.0f - 2.0f*s0)*q10d + s0*s0*q20d;
18255 hits[0][1] = a*s0+b;
18258 hits[1][0] = q0rd + s1*(2.0f - 2.0f*s1)*q10d + s1*s1*q20d;
18259 hits[1][1] = a*s1+b;
18267 static int equal(
float *a,
float *b)
18269 return (a[0] == b[0] && a[1] == b[1]);
18272 static int stbtt__compute_crossings_x(
float x,
float y,
int nverts, stbtt_vertex *verts)
18275 float orig[2], ray[2] = { 1, 0 };
18280 y_frac = (float) STBTT_fmod(y, 1.0f);
18281 if (y_frac < 0.01f)
18283 else if (y_frac > 0.99f)
18290 for (i=0; i < nverts; ++i) {
18291 if (verts[i].type == STBTT_vline) {
18292 int x0 = (int) verts[i-1].x, y0 = (
int) verts[i-1].y;
18293 int x1 = (int) verts[i ].x, y1 = (
int) verts[i ].y;
18294 if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) {
18295 float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0;
18297 winding += (y0 < y1) ? 1 : -1;
18300 if (verts[i].type == STBTT_vcurve) {
18301 int x0 = (int) verts[i-1].x , y0 = (
int) verts[i-1].y ;
18302 int x1 = (int) verts[i ].cx, y1 = (
int) verts[i ].cy;
18303 int x2 = (int) verts[i ].x , y2 = (
int) verts[i ].y ;
18304 int ax = STBTT_min(x0,STBTT_min(x1,x2)), ay = STBTT_min(y0,STBTT_min(y1,y2));
18305 int by = STBTT_max(y0,STBTT_max(y1,y2));
18306 if (y > ay && y < by && x > ax) {
18307 float q0[2],q1[2],q2[2];
18315 if (equal(q0,q1) || equal(q1,q2)) {
18316 x0 = (int)verts[i-1].x;
18317 y0 = (int)verts[i-1].y;
18318 x1 = (int)verts[i ].x;
18319 y1 = (int)verts[i ].y;
18320 if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) {
18321 float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0;
18323 winding += (y0 < y1) ? 1 : -1;
18326 int num_hits = stbtt__ray_intersect_bezier(orig, ray, q0, q1, q2, hits);
18328 if (hits[0][0] < 0)
18329 winding += (hits[0][1] < 0 ? -1 : 1);
18331 if (hits[1][0] < 0)
18332 winding += (hits[1][1] < 0 ? -1 : 1);
18340 static float stbtt__cuberoot(
float x )
18343 return -(float) STBTT_pow(-x,1.0f/3.0f);
18345 return (
float) STBTT_pow( x,1.0f/3.0f);
18349 static int stbtt__solve_cubic(
float a,
float b,
float c,
float* r)
18352 float p = b - a*a / 3;
18353 float q = a * (2*a*a - 9*b) / 27 + c;
18355 float d = q*q + 4*p3 / 27;
18357 float z = (float) STBTT_sqrt(d);
18358 float u = (-q + z) / 2;
18359 float v = (-q - z) / 2;
18360 u = stbtt__cuberoot(u);
18361 v = stbtt__cuberoot(v);
18365 float u = (float) STBTT_sqrt(-p/3);
18366 float v = (float) STBTT_acos(-STBTT_sqrt(-27/p3) * q / 2) / 3;
18367 float m = (float) STBTT_cos(v);
18368 float n = (float) STBTT_cos(v-3.141592/2)*1.732050808f;
18369 r[0] = s + u * 2 * m;
18370 r[1] = s - u * (m + n);
18371 r[2] = s - u * (m - n);
18380 STBTT_DEF
unsigned char * stbtt_GetGlyphSDF(
const stbtt_fontinfo *info,
float scale,
int glyph,
int padding,
unsigned char onedge_value,
float pixel_dist_scale,
int *width,
int *height,
int *xoff,
int *yoff)
18382 float scale_x = scale, scale_y = scale;
18383 int ix0,iy0,ix1,iy1;
18385 unsigned char *data;
18387 if (scale == 0)
return NULL;
18389 stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f,0.0f, &ix0,&iy0,&ix1,&iy1);
18392 if (ix0 == ix1 || iy0 == iy1)
18403 if (width ) *width = w;
18404 if (height) *height = h;
18405 if (xoff ) *xoff = ix0;
18406 if (yoff ) *yoff = iy0;
18409 scale_y = -scale_y;
18414 stbtt_vertex *verts;
18415 int num_verts = stbtt_GetGlyphShape(info, glyph, &verts);
18416 data = (
unsigned char *) STBTT_malloc(w * h, info->userdata);
18417 precompute = (
float *) STBTT_malloc(num_verts *
sizeof(
float), info->userdata);
18419 for (i=0,j=num_verts-1; i < num_verts; j=i++) {
18420 if (verts[i].type == STBTT_vline) {
18421 float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y;
18422 float x1 = verts[j].x*scale_x, y1 = verts[j].y*scale_y;
18423 float dist = (float) STBTT_sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));
18424 precompute[i] = (dist == 0) ? 0.0f : 1.0f / dist;
18425 }
else if (verts[i].type == STBTT_vcurve) {
18426 float x2 = verts[j].x *scale_x, y2 = verts[j].y *scale_y;
18427 float x1 = verts[i].cx*scale_x, y1 = verts[i].cy*scale_y;
18428 float x0 = verts[i].x *scale_x, y0 = verts[i].y *scale_y;
18429 float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
18430 float len2 = bx*bx + by*by;
18432 precompute[i] = 1.0f / (bx*bx + by*by);
18434 precompute[i] = 0.0f;
18436 precompute[i] = 0.0f;
18439 for (y=iy0; y < iy1; ++y) {
18440 for (x=ix0; x < ix1; ++x) {
18442 float min_dist = 999999.0f;
18443 float sx = (float) x + 0.5f;
18444 float sy = (float) y + 0.5f;
18445 float x_gspace = (sx / scale_x);
18446 float y_gspace = (sy / scale_y);
18448 int winding = stbtt__compute_crossings_x(x_gspace, y_gspace, num_verts, verts);
18450 for (i=0; i < num_verts; ++i) {
18451 float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y;
18453 if (verts[i].type == STBTT_vline && precompute[i] != 0.0f) {
18454 float x1 = verts[i-1].x*scale_x, y1 = verts[i-1].y*scale_y;
18456 float dist,dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy);
18457 if (dist2 < min_dist*min_dist)
18458 min_dist = (float) STBTT_sqrt(dist2);
18463 dist = (float) STBTT_fabs((x1-x0)*(y0-sy) - (y1-y0)*(x0-sx)) * precompute[i];
18464 STBTT_assert(i != 0);
18465 if (dist < min_dist) {
18469 float dx = x1-x0, dy = y1-y0;
18470 float px = x0-sx, py = y0-sy;
18473 float t = -(px*dx + py*dy) / (dx*dx + dy*dy);
18474 if (t >= 0.0f && t <= 1.0f)
18477 }
else if (verts[i].type == STBTT_vcurve) {
18478 float x2 = verts[i-1].x *scale_x, y2 = verts[i-1].y *scale_y;
18479 float x1 = verts[i ].cx*scale_x, y1 = verts[i ].cy*scale_y;
18480 float box_x0 = STBTT_min(STBTT_min(x0,x1),x2);
18481 float box_y0 = STBTT_min(STBTT_min(y0,y1),y2);
18482 float box_x1 = STBTT_max(STBTT_max(x0,x1),x2);
18483 float box_y1 = STBTT_max(STBTT_max(y0,y1),y2);
18485 if (sx > box_x0-min_dist && sx < box_x1+min_dist && sy > box_y0-min_dist && sy < box_y1+min_dist) {
18487 float ax = x1-x0, ay = y1-y0;
18488 float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
18489 float mx = x0 - sx, my = y0 - sy;
18490 float res[3] = {0.f,0.f,0.f};
18491 float px,py,t,it,dist2;
18492 float a_inv = precompute[i];
18493 if (a_inv == 0.0) {
18494 float a = 3*(ax*bx + ay*by);
18495 float b = 2*(ax*ax + ay*ay) + (mx*bx+my*by);
18496 float c = mx*ax+my*ay;
18502 float discriminant = b*b - 4*a*c;
18503 if (discriminant < 0)
18506 float root = (float) STBTT_sqrt(discriminant);
18507 res[0] = (-b - root)/(2*a);
18508 res[1] = (-b + root)/(2*a);
18513 float b = 3*(ax*bx + ay*by) * a_inv;
18514 float c = (2*(ax*ax + ay*ay) + (mx*bx+my*by)) * a_inv;
18515 float d = (mx*ax+my*ay) * a_inv;
18516 num = stbtt__solve_cubic(b, c, d, res);
18518 dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy);
18519 if (dist2 < min_dist*min_dist)
18520 min_dist = (float) STBTT_sqrt(dist2);
18522 if (num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) {
18523 t = res[0], it = 1.0f - t;
18524 px = it*it*x0 + 2*t*it*x1 + t*t*x2;
18525 py = it*it*y0 + 2*t*it*y1 + t*t*y2;
18526 dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
18527 if (dist2 < min_dist * min_dist)
18528 min_dist = (float) STBTT_sqrt(dist2);
18530 if (num >= 2 && res[1] >= 0.0f && res[1] <= 1.0f) {
18531 t = res[1], it = 1.0f - t;
18532 px = it*it*x0 + 2*t*it*x1 + t*t*x2;
18533 py = it*it*y0 + 2*t*it*y1 + t*t*y2;
18534 dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
18535 if (dist2 < min_dist * min_dist)
18536 min_dist = (float) STBTT_sqrt(dist2);
18538 if (num >= 3 && res[2] >= 0.0f && res[2] <= 1.0f) {
18539 t = res[2], it = 1.0f - t;
18540 px = it*it*x0 + 2*t*it*x1 + t*t*x2;
18541 py = it*it*y0 + 2*t*it*y1 + t*t*y2;
18542 dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
18543 if (dist2 < min_dist * min_dist)
18544 min_dist = (float) STBTT_sqrt(dist2);
18550 min_dist = -min_dist;
18551 val = onedge_value + pixel_dist_scale * min_dist;
18554 else if (val > 255)
18556 data[(y-iy0)*w+(x-ix0)] = (
unsigned char) val;
18559 STBTT_free(precompute, info->userdata);
18560 STBTT_free(verts, info->userdata);
18565 STBTT_DEF
unsigned char * stbtt_GetCodepointSDF(
const stbtt_fontinfo *info,
float scale,
int codepoint,
int padding,
unsigned char onedge_value,
float pixel_dist_scale,
int *width,
int *height,
int *xoff,
int *yoff)
18567 return stbtt_GetGlyphSDF(info, scale, stbtt_FindGlyphIndex(info, codepoint), padding, onedge_value, pixel_dist_scale, width, height, xoff, yoff);
18570 STBTT_DEF
void stbtt_FreeSDF(
unsigned char *bitmap,
void *userdata)
18572 STBTT_free(bitmap, userdata);
18581 static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2)
18587 stbtt_uint16 ch = s2[0]*256 + s2[1];
18589 if (i >= len1)
return -1;
18590 if (s1[i++] != ch)
return -1;
18591 }
else if (ch < 0x800) {
18592 if (i+1 >= len1)
return -1;
18593 if (s1[i++] != 0xc0 + (ch >> 6))
return -1;
18594 if (s1[i++] != 0x80 + (ch & 0x3f))
return -1;
18595 }
else if (ch >= 0xd800 && ch < 0xdc00) {
18597 stbtt_uint16 ch2 = s2[2]*256 + s2[3];
18598 if (i+3 >= len1)
return -1;
18599 c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000;
18600 if (s1[i++] != 0xf0 + (c >> 18))
return -1;
18601 if (s1[i++] != 0x80 + ((c >> 12) & 0x3f))
return -1;
18602 if (s1[i++] != 0x80 + ((c >> 6) & 0x3f))
return -1;
18603 if (s1[i++] != 0x80 + ((c ) & 0x3f))
return -1;
18606 }
else if (ch >= 0xdc00 && ch < 0xe000) {
18609 if (i+2 >= len1)
return -1;
18610 if (s1[i++] != 0xe0 + (ch >> 12))
return -1;
18611 if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f))
return -1;
18612 if (s1[i++] != 0x80 + ((ch ) & 0x3f))
return -1;
18620 static int stbtt_CompareUTF8toUTF16_bigendian_internal(
char *s1,
int len1,
char *s2,
int len2)
18622 return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8*) s1, len1, (stbtt_uint8*) s2, len2);
18627 STBTT_DEF
const char *stbtt_GetFontNameString(
const stbtt_fontinfo *font,
int *length,
int platformID,
int encodingID,
int languageID,
int nameID)
18629 stbtt_int32 i,count,stringOffset;
18630 stbtt_uint8 *fc = font->data;
18631 stbtt_uint32 offset = font->fontstart;
18632 stbtt_uint32 nm = stbtt__find_table(fc, offset,
"name");
18633 if (!nm)
return NULL;
18635 count = ttUSHORT(fc+nm+2);
18636 stringOffset = nm + ttUSHORT(fc+nm+4);
18637 for (i=0; i < count; ++i) {
18638 stbtt_uint32 loc = nm + 6 + 12 * i;
18639 if (platformID == ttUSHORT(fc+loc+0) && encodingID == ttUSHORT(fc+loc+2)
18640 && languageID == ttUSHORT(fc+loc+4) && nameID == ttUSHORT(fc+loc+6)) {
18641 *length = ttUSHORT(fc+loc+8);
18642 return (
const char *) (fc+stringOffset+ttUSHORT(fc+loc+10));
18648 static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id)
18651 stbtt_int32 count = ttUSHORT(fc+nm+2);
18652 stbtt_int32 stringOffset = nm + ttUSHORT(fc+nm+4);
18654 for (i=0; i < count; ++i) {
18655 stbtt_uint32 loc = nm + 6 + 12 * i;
18656 stbtt_int32
id = ttUSHORT(fc+loc+6);
18657 if (
id == target_id) {
18659 stbtt_int32 platform = ttUSHORT(fc+loc+0), encoding = ttUSHORT(fc+loc+2), language = ttUSHORT(fc+loc+4);
18662 if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) {
18663 stbtt_int32 slen = ttUSHORT(fc+loc+8);
18664 stbtt_int32 off = ttUSHORT(fc+loc+10);
18667 stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen);
18668 if (matchlen >= 0) {
18670 if (i+1 < count && ttUSHORT(fc+loc+12+6) == next_id && ttUSHORT(fc+loc+12) == platform && ttUSHORT(fc+loc+12+2) == encoding && ttUSHORT(fc+loc+12+4) == language) {
18671 slen = ttUSHORT(fc+loc+12+8);
18672 off = ttUSHORT(fc+loc+12+10);
18674 if (matchlen == nlen)
18676 }
else if (matchlen < nlen && name[matchlen] ==
' ') {
18678 if (stbtt_CompareUTF8toUTF16_bigendian_internal((
char*) (name+matchlen), nlen-matchlen, (
char*)(fc+stringOffset+off),slen))
18683 if (matchlen == nlen)
18695 static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags)
18697 stbtt_int32 nlen = (stbtt_int32) STBTT_strlen((
char *) name);
18698 stbtt_uint32 nm,hd;
18699 if (!stbtt__isfont(fc+offset))
return 0;
18703 hd = stbtt__find_table(fc, offset,
"head");
18704 if ((ttUSHORT(fc+hd+44) & 7) != (flags & 7))
return 0;
18707 nm = stbtt__find_table(fc, offset,
"name");
18712 if (stbtt__matchpair(fc, nm, name, nlen, 16, -1))
return 1;
18713 if (stbtt__matchpair(fc, nm, name, nlen, 1, -1))
return 1;
18714 if (stbtt__matchpair(fc, nm, name, nlen, 3, -1))
return 1;
18716 if (stbtt__matchpair(fc, nm, name, nlen, 16, 17))
return 1;
18717 if (stbtt__matchpair(fc, nm, name, nlen, 1, 2))
return 1;
18718 if (stbtt__matchpair(fc, nm, name, nlen, 3, -1))
return 1;
18724 static int stbtt_FindMatchingFont_internal(
unsigned char *font_collection,
char *name_utf8, stbtt_int32 flags)
18728 stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i);
18729 if (off < 0)
return off;
18730 if (stbtt__matches((stbtt_uint8 *) font_collection, off, (stbtt_uint8*) name_utf8, flags))
18735 #if defined(__GNUC__) || defined(__clang__)
18736 #pragma GCC diagnostic push
18737 #pragma GCC diagnostic ignored "-Wcast-qual"
18740 STBTT_DEF
int stbtt_BakeFontBitmap(
const unsigned char *data,
int offset,
18741 float pixel_height,
unsigned char *pixels,
int pw,
int ph,
18742 int first_char,
int num_chars, stbtt_bakedchar *chardata)
18744 return stbtt_BakeFontBitmap_internal((
unsigned char *) data, offset, pixel_height, pixels, pw, ph, first_char, num_chars, chardata);
18747 STBTT_DEF
int stbtt_GetFontOffsetForIndex(
const unsigned char *data,
int index)
18749 return stbtt_GetFontOffsetForIndex_internal((
unsigned char *) data, index);
18752 STBTT_DEF
int stbtt_GetNumberOfFonts(
const unsigned char *data)
18754 return stbtt_GetNumberOfFonts_internal((
unsigned char *) data);
18757 STBTT_DEF
int stbtt_InitFont(stbtt_fontinfo *info,
const unsigned char *data,
int offset)
18759 return stbtt_InitFont_internal(info, (
unsigned char *) data, offset);
18762 STBTT_DEF
int stbtt_FindMatchingFont(
const unsigned char *fontdata,
const char *name,
int flags)
18764 return stbtt_FindMatchingFont_internal((
unsigned char *) fontdata, (
char *) name, flags);
18767 STBTT_DEF
int stbtt_CompareUTF8toUTF16_bigendian(
const char *s1,
int len1,
const char *s2,
int len2)
18769 return stbtt_CompareUTF8toUTF16_bigendian_internal((
char *) s1, len1, (
char *) s2, len2);
18772 #if defined(__GNUC__) || defined(__clang__)
18773 #pragma GCC diagnostic pop
18887 #ifdef NK_INCLUDE_FONT_BAKING
18903 #define STBTT_MAX_OVERSAMPLE 8
18911 struct nk_font_bake_data {
18912 struct stbtt_fontinfo info;
18913 struct stbrp_rect *rects;
18914 stbtt_pack_range *ranges;
18915 nk_rune range_count;
18918 struct nk_font_baker {
18920 struct stbtt_pack_context spc;
18921 struct nk_font_bake_data *build;
18922 stbtt_packedchar *packed_chars;
18923 struct stbrp_rect *rects;
18924 stbtt_pack_range *ranges;
18927 NK_GLOBAL
const nk_size nk_rect_align = NK_ALIGNOF(
struct stbrp_rect);
18928 NK_GLOBAL
const nk_size nk_range_align = NK_ALIGNOF(stbtt_pack_range);
18929 NK_GLOBAL
const nk_size nk_char_align = NK_ALIGNOF(stbtt_packedchar);
18930 NK_GLOBAL
const nk_size nk_build_align = NK_ALIGNOF(
struct nk_font_bake_data);
18931 NK_GLOBAL
const nk_size nk_baker_align = NK_ALIGNOF(
struct nk_font_baker);
18944 nk_range_count(
const nk_rune *range)
18946 const nk_rune *iter = range;
18948 if (!range)
return 0;
18949 while (*(iter++) != 0);
18950 return (iter == range) ? 0 : (int)((iter - range)/2);
18964 nk_range_glyph_count(
const nk_rune *range,
int count)
18967 int total_glyphs = 0;
18968 for (i = 0; i < count; ++i) {
18970 nk_rune f = range[(i*2)+0];
18971 nk_rune t = range[(i*2)+1];
18973 diff = (int)((t - f) + 1);
18974 total_glyphs += diff;
18976 return total_glyphs;
18988 NK_API
const nk_rune*
18989 nk_font_default_glyph_ranges(
void)
18991 NK_STORAGE
const nk_rune ranges[] = {0x0020, 0x00FF, 0};
19004 NK_API
const nk_rune*
19005 nk_font_chinese_glyph_ranges(
void)
19007 NK_STORAGE
const nk_rune ranges[] = {
19027 NK_API
const nk_rune*
19028 nk_font_cyrillic_glyph_ranges(
void)
19030 NK_STORAGE
const nk_rune ranges[] = {
19049 NK_API
const nk_rune*
19050 nk_font_korean_glyph_ranges(
void)
19052 NK_STORAGE
const nk_rune ranges[] = {
19072 nk_font_baker_memory(nk_size *temp,
int *glyph_count,
19073 struct nk_font_config *config_list,
int count)
19075 int range_count = 0;
19076 int total_range_count = 0;
19077 struct nk_font_config *iter, *i;
19079 NK_ASSERT(config_list);
19080 NK_ASSERT(glyph_count);
19081 if (!config_list) {
19087 for (iter = config_list; iter; iter = iter->next) {
19089 do {
if (!i->range) iter->range = nk_font_default_glyph_ranges();
19090 range_count = nk_range_count(i->range);
19091 total_range_count += range_count;
19092 *glyph_count += nk_range_glyph_count(i->range, range_count);
19093 }
while ((i = i->n) != iter);
19095 *temp = (nk_size)*glyph_count *
sizeof(
struct stbrp_rect);
19096 *temp += (nk_size)total_range_count *
sizeof(stbtt_pack_range);
19097 *temp += (nk_size)*glyph_count *
sizeof(stbtt_packedchar);
19098 *temp += (nk_size)count *
sizeof(
struct nk_font_bake_data);
19099 *temp +=
sizeof(
struct nk_font_baker);
19100 *temp += nk_rect_align + nk_range_align + nk_char_align;
19101 *temp += nk_build_align + nk_baker_align;
19116 NK_INTERN
struct nk_font_baker*
19117 nk_font_baker(
void *memory,
int glyph_count,
int count,
const struct nk_allocator *alloc)
19119 struct nk_font_baker *baker;
19120 if (!memory)
return 0;
19122 baker = (
struct nk_font_baker*)NK_ALIGN_PTR(memory, nk_baker_align);
19123 baker->build = (
struct nk_font_bake_data*)NK_ALIGN_PTR((baker + 1), nk_build_align);
19124 baker->packed_chars = (stbtt_packedchar*)NK_ALIGN_PTR((baker->build + count), nk_char_align);
19125 baker->rects = (
struct stbrp_rect*)NK_ALIGN_PTR((baker->packed_chars + glyph_count), nk_rect_align);
19126 baker->ranges = (stbtt_pack_range*)NK_ALIGN_PTR((baker->rects + glyph_count), nk_range_align);
19127 baker->alloc = *alloc;
19141 nk_font_bake_pack(
struct nk_font_baker *baker,
19142 nk_size *image_memory,
int *width,
int *height,
struct nk_recti *custom,
19143 const struct nk_font_config *config_list,
int count,
19146 NK_STORAGE
const nk_size max_height = 1024 * 32;
19147 const struct nk_font_config *config_iter, *it;
19148 int total_glyph_count = 0;
19149 int total_range_count = 0;
19150 int range_count = 0;
19153 NK_ASSERT(image_memory);
19156 NK_ASSERT(config_list);
19160 if (!image_memory || !width || !height || !config_list || !count)
return nk_false;
19161 for (config_iter = config_list; config_iter; config_iter = config_iter->next) {
19163 do {range_count = nk_range_count(it->range);
19164 total_range_count += range_count;
19165 total_glyph_count += nk_range_glyph_count(it->range, range_count);
19166 }
while ((it = it->n) != config_iter);
19169 for (config_iter = config_list; config_iter; config_iter = config_iter->next) {
19172 struct stbtt_fontinfo *font_info = &baker->build[i++].info;
19173 font_info->userdata = (
void*)alloc;
19175 if (!stbtt_InitFont(font_info, (
const unsigned char*)it->ttf_blob, stbtt_GetFontOffsetForIndex((
const unsigned char*)it->ttf_blob, 0)))
19177 }
while ((it = it->n) != config_iter);
19180 *width = (total_glyph_count > 1000) ? 1024 : 512;
19181 stbtt_PackBegin(&baker->spc, 0, (
int)*width, (
int)max_height, 0, 1, (
void*)alloc);
19190 struct stbrp_rect custom_space;
19191 nk_zero(&custom_space,
sizeof(custom_space));
19192 custom_space.w = (stbrp_coord)(custom->w);
19193 custom_space.h = (stbrp_coord)(custom->h);
19195 stbtt_PackSetOversampling(&baker->spc, 1, 1);
19196 stbrp_pack_rects((
struct stbrp_context*)baker->spc.pack_info, &custom_space, 1);
19197 *height = NK_MAX(*height, (
int)(custom_space.y + custom_space.h));
19199 custom->x = (short)custom_space.x;
19200 custom->y = (
short)custom_space.y;
19201 custom->w = (short)custom_space.w;
19202 custom->h = (
short)custom_space.h;
19206 for (input_i = 0, config_iter = config_list; input_i < count && config_iter;
19207 config_iter = config_iter->next) {
19211 const nk_rune *in_range;
19212 const struct nk_font_config *cfg = it;
19213 struct nk_font_bake_data *tmp = &baker->build[input_i++];
19216 glyph_count = 0; range_count = 0;
19217 for (in_range = cfg->range; in_range[0] && in_range[1]; in_range += 2) {
19218 glyph_count += (int)(in_range[1] - in_range[0]) + 1;
19223 tmp->ranges = baker->ranges + range_n;
19224 tmp->range_count = (nk_rune)range_count;
19225 range_n += range_count;
19226 for (i = 0; i < range_count; ++i) {
19227 in_range = &cfg->range[i * 2];
19228 tmp->ranges[i].font_size = cfg->size;
19229 tmp->ranges[i].first_unicode_codepoint_in_range = (int)in_range[0];
19230 tmp->ranges[i].num_chars = (int)(in_range[1]- in_range[0]) + 1;
19231 tmp->ranges[i].chardata_for_range = baker->packed_chars + char_n;
19232 char_n += tmp->ranges[i].num_chars;
19236 tmp->rects = baker->rects + rect_n;
19237 rect_n += glyph_count;
19238 stbtt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v);
19239 n = stbtt_PackFontRangesGatherRects(&baker->spc, &tmp->info,
19240 tmp->ranges, (
int)tmp->range_count, tmp->rects);
19241 stbrp_pack_rects((
struct stbrp_context*)baker->spc.pack_info, tmp->rects, (
int)n);
19244 for (i = 0; i < n; ++i) {
19245 if (tmp->rects[i].was_packed)
19246 *height = NK_MAX(*height, tmp->rects[i].y + tmp->rects[i].h);
19248 }
while ((it = it->n) != config_iter);
19250 NK_ASSERT(rect_n == total_glyph_count);
19251 NK_ASSERT(char_n == total_glyph_count);
19252 NK_ASSERT(range_n == total_range_count);
19254 *height = (int)nk_round_up_pow2((nk_uint)*height);
19255 *image_memory = (nk_size)(*width) * (nk_size)(*height);
19272 nk_font_bake(
struct nk_font_baker *baker,
void *image_memory,
int width,
int height,
19273 struct nk_font_glyph *glyphs,
int glyphs_count,
19274 const struct nk_font_config *config_list,
int font_count)
19277 nk_rune glyph_n = 0;
19278 const struct nk_font_config *config_iter;
19279 const struct nk_font_config *it;
19281 NK_ASSERT(image_memory);
19284 NK_ASSERT(config_list);
19286 NK_ASSERT(font_count);
19287 NK_ASSERT(glyphs_count);
19288 if (!image_memory || !width || !height || !config_list ||
19289 !font_count || !glyphs || !glyphs_count)
19293 nk_zero(image_memory, (nk_size)((nk_size)width * (nk_size)height));
19294 baker->spc.pixels = (
unsigned char*)image_memory;
19295 baker->spc.height = (int)height;
19296 for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter;
19297 config_iter = config_iter->next) {
19299 do {
const struct nk_font_config *cfg = it;
19300 struct nk_font_bake_data *tmp = &baker->build[input_i++];
19301 stbtt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v);
19302 stbtt_PackFontRangesRenderIntoRects(&baker->spc, &tmp->info, tmp->ranges, (
int)tmp->range_count, tmp->rects);
19303 }
while ((it = it->n) != config_iter);
19304 } stbtt_PackEnd(&baker->spc);
19307 for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter;
19308 config_iter = config_iter->next) {
19312 nk_rune glyph_count = 0;
19313 const struct nk_font_config *cfg = it;
19314 struct nk_font_bake_data *tmp = &baker->build[input_i++];
19315 struct nk_baked_font *dst_font = cfg->font;
19317 float font_scale = stbtt_ScaleForPixelHeight(&tmp->info, cfg->size);
19318 int unscaled_ascent, unscaled_descent, unscaled_line_gap;
19319 stbtt_GetFontVMetrics(&tmp->info, &unscaled_ascent, &unscaled_descent,
19320 &unscaled_line_gap);
19323 if (!cfg->merge_mode) {
19324 dst_font->ranges = cfg->range;
19325 dst_font->height = cfg->size;
19326 dst_font->ascent = ((float)unscaled_ascent * font_scale);
19327 dst_font->descent = ((float)unscaled_descent * font_scale);
19328 dst_font->glyph_offset = glyph_n;
19333 dst_font->glyph_count = 0;
19337 for (i = 0; i < tmp->range_count; ++i) {
19338 stbtt_pack_range *range = &tmp->ranges[i];
19339 for (char_idx = 0; char_idx < range->num_chars; char_idx++)
19341 nk_rune codepoint = 0;
19342 float dummy_x = 0, dummy_y = 0;
19343 stbtt_aligned_quad q;
19344 struct nk_font_glyph *glyph;
19347 const stbtt_packedchar *pc = &range->chardata_for_range[char_idx];
19348 codepoint = (nk_rune)(range->first_unicode_codepoint_in_range + char_idx);
19349 stbtt_GetPackedQuad(range->chardata_for_range, (
int)width,
19350 (
int)height, char_idx, &dummy_x, &dummy_y, &q, 0);
19353 glyph = &glyphs[dst_font->glyph_offset + dst_font->glyph_count + (
unsigned int)glyph_count];
19354 glyph->codepoint = codepoint;
19355 glyph->x0 = q.x0; glyph->y0 = q.y0;
19356 glyph->x1 = q.x1; glyph->y1 = q.y1;
19357 glyph->y0 += (dst_font->ascent + 0.5f);
19358 glyph->y1 += (dst_font->ascent + 0.5f);
19359 glyph->w = glyph->x1 - glyph->x0 + 0.5f;
19360 glyph->h = glyph->y1 - glyph->y0;
19362 if (cfg->coord_type == NK_COORD_PIXEL) {
19363 glyph->u0 = q.s0 * (float)width;
19364 glyph->v0 = q.t0 * (float)height;
19365 glyph->u1 = q.s1 * (float)width;
19366 glyph->v1 = q.t1 * (float)height;
19373 glyph->xadvance = (pc->xadvance + cfg->spacing.x);
19374 if (cfg->pixel_snap)
19375 glyph->xadvance = (float)(
int)(glyph->xadvance + 0.5f);
19379 dst_font->glyph_count += glyph_count;
19380 glyph_n += glyph_count;
19381 }
while ((it = it->n) != config_iter);
19397 nk_font_bake_custom_data(
void *img_memory,
int img_width,
int img_height,
19398 struct nk_recti img_dst,
const char *texture_data_mask,
int tex_width,
19399 int tex_height,
char white,
char black)
19406 NK_ASSERT(img_memory);
19407 NK_ASSERT(img_width);
19408 NK_ASSERT(img_height);
19409 NK_ASSERT(texture_data_mask);
19410 NK_UNUSED(tex_height);
19411 if (!img_memory || !img_width || !img_height || !texture_data_mask)
19414 pixels = (nk_byte*)img_memory;
19415 for (y = 0, n = 0; y < tex_height; ++y) {
19416 for (x = 0; x < tex_width; ++x, ++n) {
19417 const int off0 = ((img_dst.x + x) + (img_dst.y + y) * img_width);
19418 const int off1 = off0 + 1 + tex_width;
19419 pixels[off0] = (texture_data_mask[n] == white) ? 0xFF : 0x00;
19420 pixels[off1] = (texture_data_mask[n] == black) ? 0xFF : 0x00;
19437 nk_font_bake_convert(
void *out_memory,
int img_width,
int img_height,
19438 const void *in_memory)
19442 const nk_byte *src;
19444 NK_ASSERT(out_memory);
19445 NK_ASSERT(in_memory);
19446 NK_ASSERT(img_width);
19447 NK_ASSERT(img_height);
19448 if (!out_memory || !in_memory || !img_height || !img_width)
return;
19450 dst = (nk_rune*)out_memory;
19451 src = (
const nk_byte*)in_memory;
19452 for (n = (
int)(img_width * img_height); n > 0; n--)
19453 *dst++ = ((nk_rune)(*src++) << 24) | 0x00FFFFFF;
19475 nk_font_text_width(
nk_handle handle,
float height,
const char *text,
int len)
19479 float text_width = 0;
19483 struct nk_font *font = (
struct nk_font*)handle.ptr;
19485 NK_ASSERT(font->glyphs);
19486 if (!font || !text || !len)
19489 scale = height/font->info.height;
19490 glyph_len = text_len = nk_utf_decode(text, &unicode, (
int)len);
19491 if (!glyph_len)
return 0;
19492 while (text_len <= (
int)len && glyph_len) {
19493 const struct nk_font_glyph *g;
19497 g = nk_font_find_glyph(font, unicode);
19498 text_width += g->xadvance * scale;
19501 glyph_len = nk_utf_decode(text + text_len, &unicode, (
int)len - text_len);
19502 text_len += glyph_len;
19506 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
19519 nk_font_query_font_glyph(
nk_handle handle,
float height,
19520 struct nk_user_font_glyph *glyph, nk_rune codepoint, nk_rune next_codepoint)
19523 const struct nk_font_glyph *g;
19524 struct nk_font *font;
19527 NK_UNUSED(next_codepoint);
19529 font = (
struct nk_font*)handle.ptr;
19531 NK_ASSERT(font->glyphs);
19532 if (!font || !glyph)
19535 scale = height/font->info.height;
19536 g = nk_font_find_glyph(font, codepoint);
19537 glyph->width = (g->x1 - g->x0) * scale;
19538 glyph->height = (g->y1 - g->y0) * scale;
19539 glyph->offset =
nk_vec2(g->x0 * scale, g->y0 * scale);
19540 glyph->xadvance = (g->xadvance * scale);
19541 glyph->uv[0] =
nk_vec2(g->u0, g->v0);
19542 glyph->uv[1] =
nk_vec2(g->u1, g->v1);
19556 NK_API
const struct nk_font_glyph*
19557 nk_font_find_glyph(
const struct nk_font *font, nk_rune unicode)
19561 int total_glyphs = 0;
19562 const struct nk_font_glyph *glyph = 0;
19563 const struct nk_font_config *iter = 0;
19566 NK_ASSERT(font->glyphs);
19567 NK_ASSERT(font->info.ranges);
19568 if (!font || !font->glyphs)
return 0;
19570 glyph = font->fallback;
19571 iter = font->config;
19572 do {count = nk_range_count(iter->range);
19573 for (i = 0; i < count; ++i) {
19574 nk_rune f = iter->range[(i*2)+0];
19575 nk_rune t = iter->range[(i*2)+1];
19576 int diff = (int)((t - f) + 1);
19577 if (unicode >= f && unicode <= t)
19578 return &font->glyphs[((nk_rune)total_glyphs + (unicode - f))];
19579 total_glyphs += diff;
19581 }
while ((iter = iter->n) != font->config);
19596 nk_font_init(
struct nk_font *font,
float pixel_height,
19597 nk_rune fallback_codepoint,
struct nk_font_glyph *glyphs,
19598 const struct nk_baked_font *baked_font,
nk_handle atlas)
19600 struct nk_baked_font baked;
19603 NK_ASSERT(baked_font);
19604 if (!font || !glyphs || !baked_font)
19607 baked = *baked_font;
19608 font->fallback = 0;
19609 font->info = baked;
19610 font->scale = (float)pixel_height / (
float)font->info.height;
19611 font->glyphs = &glyphs[baked_font->glyph_offset];
19612 font->texture = atlas;
19613 font->fallback_codepoint = fallback_codepoint;
19614 font->fallback = nk_font_find_glyph(font, fallback_codepoint);
19616 font->handle.height = font->info.height * font->scale;
19617 font->handle.width = nk_font_text_width;
19618 font->handle.userdata.ptr = font;
19619 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
19620 font->handle.query = nk_font_query_font_glyph;
19621 font->handle.texture = font->texture;
19635 #pragma clang diagnostic push
19636 #pragma clang diagnostic ignored "-Woverlength-strings"
19637 #elif defined(__GNUC__) || defined(__GNUG__)
19638 #pragma GCC diagnostic push
19639 #pragma GCC diagnostic ignored "-Woverlength-strings"
19642 #ifdef NK_INCLUDE_DEFAULT_FONT
19644 NK_GLOBAL
const char nk_proggy_clean_ttf_compressed_data_base85[11980+1] =
19645 "7])#######hV0qs'/###[),##/l:$#Q6>##5[n42>c-TH`->>#/e>11NNV=Bv(*:.F?uu#(gRU.o0XGH`$vhLG1hxt9?W`#,5LsCp#-i>.r$<$6pD>Lb';9Crc6tgXmKVeU2cD4Eo3R/"
19646 "2*>]b(MC;$jPfY.;h^`IWM9<Lh2TlS+f-s$o6Q<BWH`YiU.xfLq$N;$0iR/GX:U(jcW2p/W*q?-qmnUCI;jHSAiFWM.R*kU@C=GH?a9wp8f$e.-4^Qg1)Q-GL(lf(r/7GrRgwV%MS=C#"
19647 "`8ND>Qo#t'X#(v#Y9w0#1D$CIf;W'#pWUPXOuxXuU(H9M(1<q-UE31#^-V'8IRUo7Qf./L>=Ke$$'5F%)]0^#0X@U.a<r:QLtFsLcL6##lOj)#.Y5<-R&KgLwqJfLgN&;Q?gI^#DY2uL"
19648 "i@^rMl9t=cWq6##weg>$FBjVQTSDgEKnIS7EM9>ZY9w0#L;>>#Mx&4Mvt//L[MkA#W@lK.N'[0#7RL_&#w+F%HtG9M#XL`N&.,GM4Pg;-<nLENhvx>-VsM.M0rJfLH2eTM`*oJMHRC`N"
19649 "kfimM2J,W-jXS:)r0wK#@Fge$U>`w'N7G#$#fB#$E^$#:9:hk+eOe--6x)F7*E%?76%^GMHePW-Z5l'&GiF#$956:rS?dA#fiK:)Yr+`�j@'DbG&#^$PG.Ll+DNa<XCMKEV*N)LN/N"
19650 "*b=%Q6pia-Xg8I$<MR&,VdJe$<(7G;Ckl'&hF;;$<_=X(b.RS%%)###MPBuuE1V:v&cXm#(&cV]`k9OhLMbn%s$G2,B$BfD3X*sp5#l,$R#]x_X1xKX%b5U*[r5iMfUo9U`N99hG)"
19651 "tm+/Us9pG)XPu`<0s-)WTt(gCRxIg(%6sfh=ktMKn3j)<6<b5Sk_/0(^]AaN#(p/L>&VZ>1i%h1S9u5o@YaaW$e+b<TWFn/Z:Oh(Cx2$lNEoN^e)#CFY@@I;BOQ*sRwZtZxRcU7uW6CX"
19652 "ow0i(?$Q[cjOd[P4d)]>ROPOpxTO7Stwi1::iB1q)C_=dV26J;2,]7op$]uQr@_V7$q^%lQwtuHY]=DX,n3L#0PHDO4f9>dC@O>HBuKPpP*E,N+b3L#lpR/MrTEH.IAQk.a>D[.e;mc."
19653 "x]Ip.PH^'/aqUO/$1WxLoW0[iLA<QT;5HKD+@qQ'NQ(3_PLhE48R.qAPSwQ0/WK?Z,[x?-J;jQTWA0X@KJ(_Y8N-:/M74:/-ZpKrUss?d#dZq]DAbkU*JqkL+nwX@@47`5>w=4h(9.`G"
19654 "CRUxHPeR`5Mjol(dUWxZa(>STrPkrJiWx`5U7F#.g*jrohGg`cg:lSTvEY/EV_7H4Q9[Z%cnv;JQYZ5q.l7Zeas:HOIZOB?G<Nald$qs]@]L<J7bR*>gv:[7MI2k).'2($5FNP&EQ(,)"
19655 "U]W]+fh18.vsai00);D3@4ku5P?DP8aJt+;qUM]=+b'8@;mViBKx0DE[-auGl8:PJ&Dj+M6OC]O^((##]`0i)drT;-7X`=-H3[igUnPG-NZlo.#k@h#=Ork$m>a>$-?Tm$UV(?#P6YY#"
19656 "'/###xe7q.73rI3*pP/$1>s9)W,JrM7SN]'/4C#v$U`0#V.[0>xQsH$fEmPMgY2u7Kh(G%siIfLSoS+MK2eTM$=5,M8p`A.;_R%#u[K#$x4AG8.kK/HSB==-'Ie/QTtG?-.*^N-4B/ZM"
19657 "_3YlQC7(p7q)&](`6_c)$/*JL(L-^(]$wIM`dPtOdGA,U3:w2M-0<q-]L_?^)1vw'.,MRsqVr.L;aN&#/EgJ)PBc[-f>+WomX2u7lqM2iEumMTcsF?-aT=Z-97UEnXglEn1K-bnEO`gu"
19658 "Ft(c%=;Am_Qs@jLooI&NX;]0#j4#F14;gl8-GQpgwhrq8'=l_f-b49'UOqkLu7-##oDY2L(te+Mch&gLYtJ,MEtJfLh'x'M=$CS-ZZ%P]8bZ>#S?YY#%Q&q'3^Fw&?D)UDNrocM3A76/"
19659 "/oL?#h7gl85[qW/NDOk%16ij;+:1a'iNIdb-ou8.P*w,v5#EI$TWS>Pot-R*H'-SEpA:g)f+O$%%`kA#G=8RMmG1&O`>to8bC]T&$,n.LoO>29sp3dt-52U%VM#q7'DHpg+#Z9%H[K<L"
19660 "%a2E-grWVM3@2=-k22tL]4$##6We'8UJCKE[d_=%wI;'6X-GsLX4j^SgJ$##R*w,vP3wK#iiW&#*h^D&R?jp7+/u&#(AP##XU8c$fSYW-J95_-Dp[g9wcO&#M-h1OcJlc-*vpw0xUX&#"
19661 "OQFKNX@QI'IoPp7nb,QU//MQ&ZDkKP)X<WSVL(68uVl&#c'[0#(s1X&xm$Y%B7*K:eDA323j998GXbA#pwMs-jgD$9QISB-A_(aN4xoFM^@C58D0+Q+q3n0#3U1InDjF682-SjMXJK)("
19662 "h$hxua_K]ul92%'BOU&#BRRh-slg8KDlr:%L71Ka:.A;%YULjDPmL<LYs8i#XwJOYaKPKc1h:'9Ke,g)b),78=I39B;xiY$bgGw-&.Zi9InXDuYa%G*f2Bq7mn9^#p1vv%#(Wi-;/Z5h"
19663 "o;#2:;%d	v68C5g?ntX0X)pT`;%pB3q7mgGN)3%(P8nTd5L7GeA-GL@+%J3u2:(Yf>et`e;)f#Km8&+DC$I46>#Kr]]u-[=99tts1.qb#q72g1WJO81q+eN'03'eM>&1XxY-caEnO"
19664 "j%2n8)),?ILR5^.Ibn<-X-Mq7[a82Lq:F&#ce+S9wsCK*x`569E8ew'He]h:sI[2LM$[guka3ZRd6:t%IG:;$%YiJ:Nq=?eAw;/:nnDq0(CYcMpG)qLN4$##&J<j$UpK<Q4a1]MupW^-"
19665 "sj_$%[HK%'F####QRZJ::Y3EGl4'@%FkiAOg#p[##O`gukTfBHagL<LHw%q&OV0##F=6/:chIm0@eCP8X]:kFI%hl8hgO@RcBhS-@Qb$%+m=hPDLg*%K8ln(wcf3/'DW-$.lR?n[nCH-"
19666 "eXOONTJlh:.RYF%3'p6sq:UIMA945&^HFS87@$EP2iG<-lCO$%c`uKGD3rC$x0BL8aFn--`ke%#HMP'vh1/R&O_J9'um,.<tx[@%wsJk&bUT2`0uMv7gg#qp/ij.L56'hl;.s5CUrxjO"
19667 "M7-##.l+Au'A&O:-T72L]P`&=;ctp'XScX*rU.>-XTt,%OVU4)S1+R-#dg0/Nn?Ku1^0f$B*P:Rowwm-`0PKjYDDM'3]d39VZHEl4,.j']Pk-M.h^&:0FACm$maq-&sgw0t7/6(^xtk%"
19668 "LuH88Fj-ekm>GA#_>568x6(OFRl-IZp`&b,_P'$M<Jnq79VsJW/mWS*PUiq76;]/NM_>hLbxfc$mj`,O;&%W2m`Zh:/)Uetw:aJ%]K9h:TcF]u_-Sj9,VK3M.*'&0D[Ca]J9gp8,kAW]"
19669 "%(?A%R$f<->Zts'^kn=-^@c4%-pY6qI%J%1IGxfLU9CP8cbPlXv);C=b),<2mOvP8up,UVf3839acAWAW-W?#ao/^#%KYo8fRULNd2.>%m]UK:n%r$'sw]J;5pAoO_#2mO3n,'=H5(et"
19670 "Hg*`+RLgv>=4U8guD$I%D:W>-r5V*%j*W:Kvej.Lp$<M-SGZ':+Q_k+uvOSLiEo(<aD/K<CCc`'Lx>'?;++O'>()jLR-^u68PHm8ZFWe+ej8h:9r6L*0//c&iH&R8pRbA#Kjm%upV1g:"
19671 "a_#Ur7FuA#(tRh#.Y5K+@?3<-8m0$PEn;J:rh6?I6uG<-`wMU'ircp0LaE_OtlMb&1#6T.#FDKu#1Lw%u%+GM+X'e?YLfjM[VO0MbuFp7;>Q&#WIo)0@F%q7c#4XAXN-U&VB<HFF*qL("
19672 "$/V,;(kXZejWO`<[5?\?ewY(*9=%wDc;,u<'9t3W-(H1th3+G]ucQ]kLs7df($/*JL]@*t7Bu_G3_7mp7<iaQjO@.kLg;x3B0lqp7Hf,^Ze7-##@/c58Mo(3;knp0%)A7?-W+eI'o8)b<"
19673 "nKnw'Ho8C=Y>pqB>0ie&jhZ[?iLR@@_AvA-iQC(=ksRZRVp7`.=+NpBC%rh&3]R:8XDmE5^V8O(x<<aG/1N$#FX$0V5Y6x'aErI3I$7x%E`v<-BY,)%-?Psf*l?%C3.mM(=/M0:JxG'?"
19674 "7WhH%o'a<-80g0NBxoO(GH<dM]n.+%q@jH?f.UsJ2Ggs&4<-e47&Kl+f//9@`b+?.TeN_&B8Ss?v;^Trk;f#YvJkl&w$]>-+k?'(<S:68tq*WoDfZu';mM?8X[ma8W%*`-=;D.(nc7/;"
19675 ")g:T1=^J$&BRV(-lTmNB6xqB[@0*o.erM*<SWF]u2=st-*(6v>^](H.aREZSi,#1:[IXaZFOm<-ui#qUq2$##Ri;u75OK#(RtaW-K-F`S+cF]uN`-KMQ%rP/Xri.LRcB##=YL3BgM/3M"
19676 "D?@f&1'BW-)Ju<L25gl8uhVm1hL$##*8###'A3/LkKW+(^rWX?5W_8g)a(m&K8P>#bmmWCMkk&#TR`C,5d>g)F;t,4:@_l8G/5h4vUd%&%950:VXD'QdWoY-F$BtUwmfe$YqL'8(PWX("
19677 "P?^@Po3$##`MSs?DWBZ/S>+4%>fX,VWv/w'KD`LP5IbH;rTV>n3cEK8U#bX]l-/V+^lj3;vlMb&[5YQ8#pekX9JP3XUC72L,,?+Ni&co7ApnO*5NK,((W-i:$,kp'UDAO(G0Sq7MVjJs"
19678 "bIu)'Z,*[>br5fX^:FPAWr-m2KgL<LUN098kTF&#lvo58=/vjDo;.;)Ka*hLR#/k=rKbxuV`>Q_nN6'8uTGT5g)uLv:873UpTLgH+#FgpH'_o1780Ph8KmxQJ8#H72L4@768@Tm&Q"
19679 "h4CB/5OvmA&,Q&QbUoi$a_%3M01H)4x7I^&KQVgtFnV+;[Pc>[m4k//,]1?#`VY[Jr*3&&slRfLiVZJ:]?=K3Sw=[$=uRB?3xk48@aeg<Z'<$#4H)6,>e0jT6'N#(q%.O=?2S]u*(m<-"
19680 "V8J'(1)G][68hW$5'q[GC&5j`TE?m'esFGNRM)j,ffZ?-qx8;->g4t*:CIP/[Qap7/9'#(1sao7w-.qNUdkJ)tCF&#B^;xGvn2r9FEPFFFcL@.iFNkTve$m%#QvQS8U@)2Z+3K:AKM5i"
19681 "sZ88+dKQ)W6>J%CL<KE>`.d*(B`-n8D9oK<Up]c$X$(,)M8Zt7/[rdkqTgl-0cuGMv'?>-XV1q['-5k'cAZ69e;D_?$ZPP&s^+7])$*$#@QYi9,5P	r+$%CE=68>K8r0=dSC%%(@p7"
19682 ".m7jilQ02'0-VWAg<a/''3u.=4L$Y)6k/K:_[3=&jvL<L0C/2'v:^;-DIBW,B4E68:kZ;%?8(Q8BH=kO65BW?xSG&#@uU,DS*,?.+(o(#1vCS8#CHF>TlGW'b)Tq7VT9q^*^$$.:&N@@"
19683 "$&)WHtPm*5_rO0&e%K&#-30j(E4#'Zb.o/(Tpm$>K'f@[PvFl,hfINTNU6u'0pao7%XUp9]5.>%h`8_=VYbxuel.NTSsJfLacFu3B'lQSu/m6-Oqem8T+oE--$0a/k]uj9EwsG>%veR*"
19684 "hv^BFpQj:K'#SJ,sB-'#](j.Lg92rTw-*n%@/;39rrJF,l#qV%OrtBeC6/,;qB3ebNW[?,Hqj2L.1NP&GjUR=1D8QaS3Up&@*9wP?+lo7b?@%'k4`p0Z$22%K3+iCZj?XJN4Nm&+YF]u"
19685 "@-W$U%VEQ/,,>>#)D<h#`)h0:<Q6909ua+&VU%n2:cG3FJ-%@Bj-DgLr`Hw&HAKjKjseK</xKT*)B,N9X3]krc12t'pgTV(Lv-tL[xg_%=M_q7a^x?7Ubd>#%8cY#YZ?=,`Wdxu/ae&#"
19686 "w6)R89tI#6@s'(6Bf7a&?S=^ZI_kS&ai`&=tE72L_D,;^R)7[$s<Eh#c&)q.MXI%#v9ROa5FZO%sF7q7Nwb&#ptUJ:aqJe$Sl68%.D###EC><?-aF&#RNQv>o8lKN%5/$(vdfq7+ebA#"
19687 "u1p]ovUKW&Y%q]'>$1@-[xfn$7ZTp7mM,G,Ko7a&Gu%G[RMxJs[0MM%wci.LFDK)(<c`Q8N)jEIF*+?P2a8g%)$q]o2aH8C&<SibC/q,(e:v;-b#6[$NtDZ84Je2KNvB#$P5?tQ3nt(0"
19688 "d=j.LQf./Ll33+(;q3L-w=8dX$#WF&uIJ@-bfI>%:_i2B5CsR8&9Z&#=mPEnm0f`<&c)QL5uJ#%u%lJj+D-r;BoFDoS97h5g)E#o:&S4weDF,9^Hoe`h*L+_a*NrLW-1pG_&2UdB8"
19689 "6e%B/:=>)N4xeW.*wft-;$'58-ESqr<b?UI(_%@[P46>#U`'6AQ]m&6/`Z>#S?YY#Vc;r7U2&326d=w&H####?TZ`*4?&.MK?LP8Vxg>$[QXc%QJv92.(Db*B)gb*BM9dM*hJMAo*c&#"
19690 "b0v=Pjer]$gG&JXDf->'StvU7505l9$AFvgYRI^&<^b68?j#q9QX4SM'RO#&sL1IM.rJfLUAj221]d##DW=m83u5;'bYx,*Sl0hL(W;;$doB&O/TQ:(Z^xBdLjL<Lni;''X.`$#8+1GD"
19691 ":k$YUWsbn8ogh6rxZ2Z9]%nd+>V#*8U_72Lh+2Q8Cj0i:6hp&$C/:p(HK>T8Y[gHQ4`4)'$Ab(Nof%V'8hL&#<NEdtg(n'=S1A(Q1/I&4([%dM`,Iu'1:_hL>SfD07&6D<fp8dHM7/g+"
19692 "tlPN9J*rKaPct&?'uBCem^jn%9_K)<,C5K3s=5g&GmJb*[SYq7K;TRLGCsM-$$;S%:Y@r7AK0pprpL<Lrh,q7e/%KWK:50I^+m'vi`3?%Zp+<-d+$L-Sv:@.o19n$s0&39;kn;S%BSq*"
19693 "$3WoJSCLweV[aZ'MQIjO<7;X-X;&+dMLvu#^UsGEC9WEc[X(wI7#2.(F0jV*eZf<-Qv3J-c+J5AlrB#$p(H68LvEA'q3n0#m,[`*8Ft)FcYgEud]CWfm68,(aLA$@EFTgLXoBq/UPlp7"
19694 ":d[/;r_ix=:TF`S5H-b<LI&HY(K=h#)]Lk$K14lVfm:x$H<3^Ql<M`$OhapBnkup'D#L$Pb_`N*g]2e;X/Dtg,bsj&K#2[-:iYr'_wgH)NUIR8a1n#S?Yej'h8^58UbZd+^FKD*T@;6A"
19695 "7aQC[K8d-(v6GI$x:T<&'Gp5Uf>@M.*J:;$-rv29'M]8qMv-tLp,'886iaC=Hb*YJoKJ,(j%K=H`K.v9HggqBIiZu'QvBT.#=)0ukruV&.)3=(^1`o*Pj4<-<aN((^7('#Z0wK#5GX@7"
19696 "u][`*S^43933A4rl][`*O4CgLEl]v$1Q3AeF37dbXk,.)vj#x'd`;qgbQR%FW,2(?LO=s%Sc68%NP'##Aotl8x=BE#j1UD([3$M(]UI2LX3RpKN@;/#f'f/&_mt&F)XdF<9t4)Qa.*kT"
19697 "LwQ'(TTB9.xH'>#MJ+gLq9-##@HuZPN0]u:h7.T..G:;$/Usj(T7`Q8tT72LnYl<-qx8;-HV7Q-&Xdx%1a,hC=0u+HlsV>nuIQL-5<N?)NBS)QN*_I,?&)2'IM%L3I)X((e/dl2&8'<M"
19698 ":^#M*Q+[T.Xri.LYS3v%fF`68h;b-X[/En'CR.q7E)p'/kle2HM,u;^%OKC-N+Ll%F9CF<Nf'^#t2L,;27W:0O@6##U6W7:$rJfLWHj$#)woqBefIZ.PK<b*t7ed;p*_m;4ExK#h@&]>"
19699 "_>@kXQtMacfD.m-VAb8;IReM3$wf0''hra*so568'Ip&vRs849'MRYSp%:t:h5qSgwpEr$B>Q,;s(C#$)`svQuF$##-D,##,g68@2[T;.XSdN9Qe)rpt._K-#5wF)sP'##p#C0c%-Gb%"
19700 "hd+<-j'Ai*x&&HMkT]C'OSl##5RG[JXaHN;d'uA#x._U;.`PU@(Z3dt4r152@:v,'R.Sj'w#0<-;kPI)FfJ&#AYJ&#//)>-k=m=*XnK$>=)72L]0I%>.G690a:$##<,);?;72#?x9+d;"
19701 "^V'9;jY@;)br#q^YQpx:X#Te$Z^'=-=bGhLf:D6&bNwZ9-ZD#n^9HhLMr5G;']d&6'wYmTFmL<LD)F^%[tC'8;+9E#C$g%#5Y>q9wI>P(9mI[>kC-ekLC/R&CH+s'B;K-M6$EB%is00:"
19702 "+A4[7xks.LrNk0&E)wILYF@2L'0Nb$+pv<(2.768/FrY&h$^3i&@+G%JT'<-,v`3;_)I9M^AE]CN?Cl2AZg+%4iTpT3<n-&%H%b<FDj2M<hH=&Eh<2Len$b*aTX=-8QxN)k11IM1c^j%"
19703 "9s<L<NFSo)B?+<-(GxsF,^-Eh@$4dXhN$+#rxK8'je'D7k`e;)2pYwPA'_p9&@^18ml1^[@g4t*[JOa*[=Qp7(qJ_oOL^('7fB&Hq-:sf,sNj8xq^>$U4O]GKx'm9)b@p7YsvK3w^YR-"
19704 "CdQ*:Ir<($u&)#(&?L9Rg3H)4fiEp^iI9O8KnTj,]H?D*r7'M;PwZ9K0E^k&-cpI;.p/6_vwoFMV<->#%Xi.LxVnrU(4&8/P+:hLSKj$#U%]49t'I:rgMi'FL@a:0Y-uA[39',(vbma*"
19705 "hU%<-SRF`Tt:542R_VV$p@[p8DV[A,?1839FWdF<TddF<9Ah-6&9tWoDlh]&1SpGMq>Ti1O*H&#(AL8[_P%.M>v^-))qOT*F5Cq0`Ye%+$B6i:7@0IX<N+T+0MlMBPQ*Vj>SsD<U4JHY"
19706 "8kD2)2fU/M#$e.)T4,_=8hLim[&);?UkK'-x?'(:siIfL<$pFM`i<?%W(mGDHM%>iWP,##P`%/L<eXi:@Z9C.7o=@(pXdAO/NLQ8lPl+HPOQa8wD8=^GlPa8TKI1CjhsCTSLJM'/Wl>-"
19707 "S(qw%sf/@%#B6;/U7K]uZbi^Oc^2n<bhPmUkMw>%t<)'mEVE''n`WnJra$^TKvX5B>;_aSEK',(hwa0:i4G?.Bci.(X[?b*($,=-n<.Q%`(X=?+@Am*Js0&=3bh8K]mL<LoNs'6,'85`"
19708 "0?t/'_U59@]ddF<#LdF<eWdF<OuN/45rY<-L@&#+fm>69=Lb,OcZV/);TTm8VI;?%OtJ<(b4mq7M6:u?KRdF<gR@2L=FNU-<b[(9c/ML3m;Z[$oF3g)GAWqpARc=<ROu7cL5l;-[A]%/"
19709 "+fsd;l#SafT/f*W]0=O'$(Tb<[)*@e775R-:Yob%g*>l*:xP?Yb.5)%w_I?7uk5JC+FS(m#i'k.'a0i)9<7b'fs'59hq$*5Uhv##pi^8+hIEBF`nvo`;'l0.^S1<-wUK2/Coh58KKhLj"
19710 "M=SO*rfO`+qC`W-On.=AJ56>>i2@2LH6A:&5q`?9I3@@'04&p2/LVa*T-4<-i3;M9UvZd+N7>b*eIwg:CC)c<>nO&#<IGe;__.thjZl<%w(Wk2xmp4Q@I#I9,DF]u7-P=.-_:YJ]aS@V"
19711 "?6*C()dOp7:WL,b&3Rg/.cmM9&r^>$(>.Z-I&J(Q0Hd5Q%7Co-b`-c<N(6r@ip+AurK<m86QIth*#v;-OBqi+L7wDE-Ir8K['m+DDSLwK&/.?-V%U_%3:qKNu$_b*B-kp7NaD'QdWQPK"
19712 "Yq[@>P)hI;*_F]u`Rb[.j8_Q/<&>uu+VsH$sM9TA%?)(vmJ80),P7E>)tjD%2L=-t#fK[%`v=Q8<FfNkgg^oIbah*#8/Qt$F&:K*-(N/'+1vMB,u()-a.VUU*#[e%gAAO(S>WlA2);Sa"
19713 ">gXm8YB`1d@K#n]76-a$U,mF<fX]idqd)<3,]J7JmW4`6]uks=4-72L(jEk+:bJ0M^q-8Dm_Z?0olP1C9Sa&H[d&c$ooQUj]Exd*3ZM@-WGW2%s',B-_M%>%Ul:#/'xoFM9QX-$.QN'>"
19714 "[%$Z$uF6pA6Ki2O5:8w*vP1<-1`[G,)-m#>0`P&#eb#.3i)rtB61(o'$?X3B</R90;eZ]%Ncq;-Tl]#F>2Qft^ae_5tKL9MUe9b*sLEQ95C&`=G?@Mj=wh*'3E>=-<)Gt*Iw)'QG:`@I"
19715 "wOf7&]1i'S01B+Ev/Nac#9S;=;YQpg_6U`*kVY39xK,[/6Aj7:'1Bm-_1EYfa1+o&o4hp7KN_Q(OlIo@S%;jVdn0'1<Vc52=u`3^o-n1'g4v58Hj&6_t7$##?M)c<$bgQ_'SY((-xkA#"
19716 "Y(,p'H9rIVY-b,'%bCPF7.J<Up^,(dU1VY*5#WkTU>h19w,WQhLI)3S#f$2(eb,jr*b;3Vw]*7NH%$c4Vs,eD9>XW8?N]o+(*pgC%/72LV-u<Hp,3@e^9UB1J+ak9-TN/mhKPg+AJYd$"
19717 "MlvAF_jCK*.O-^(63adMT->W%iewS8W6m2rtCpo'RS1R84=@paTKt)>=%&1[)*vp'u+x,VrwN;&]kuO9JDbg=pO$J*.jVe;u'm0dr9l,<*wMK*Oe=g8lV_KEBFkO'oU]^=[-792#ok,)"
19718 "i]lR8qQ2oA8wcRCZ^7w/Njh;?.stX?Q1>S1q4Bn$)K1<-rGdO'$Wr.Lc.CG)$/*JL4tNR/,SVO3,aUw'DJN:)Ss;wGn9A32ijw%FL+Z0Fn.U9;reSq)bmI32U==5ALuG&#Vf1398/pVo"
19719 "1*c-(aY168o<`JsSbk-,1N;$>0:OUas(3:8Z972LSfF8eb=c-;>SPw7.6hn3m`9^Xkn(r.qS[0;T%&Qc=+STRxX'q1BNk3&*eu2;&8q$&x>Q#Q7^Tf+6<(d%ZVmj2bDi%.3L2n+4W'$P"
19720 "iDDG)g,r%+?,$@?uou5tSe2aN_AQU*<h`e-GI7)?OK2A.d7_c)?wQ5AS@DL3r#7fSkgl6-++D:'A,uq7SvlB$pcpH'q3n0#_%dY#xCpr-l<F0NR@-##FEV6NTF6##$l84N1w?AO>'IAO"
19721 "URQ##V^Fv-XFbGM7Fl(N<3DhLGF%q.1rC$#:T__&Pi68%0xi_&[qFJ(77j_&JWoF.V735&T,[R*:xFR*K5>>#`bW-?4Ne_&6Ne_&6Ne_&n`kr-#GJcM6X;uM6X;uM(.a..^2TkL%oR(#"
19722 ";u.T%fAr%4tJ8&><1=GHZ_+m9/#H1F^R#SC#*N=BA9(D?v[UiFY>>^8p,KKF.W]L29uLkLlu/+4T<XoIB&hx=T1PcDaB&;HH+-AFr?(m9HZV)FKS8JCw;SD=6[^/DZUL`EUDf]GGlG&>"
19723 "w$)F./^n3+rlo+DB;5sIYGNk+i1t-69Jg--0pao7Sm#K)pdHW&;LuDNH@H>#/X-TI(;P>#,Gc>#0Su>#4`1?#8lC?#<xU?#@.i?#D:%@#HF7@#LRI@#P_[@#Tkn@#Xw*A#]-=A#a9OA#"
19724 "d<F&#*;G##.GY##2Sl##6`($#:l:$#>xL$#B.`$#F:r$#JF.%#NR@%#R_R%#Vke%#Zww%#_-4^Rh%Sflr-k'MS.o?.5/sWel/wpEM0%3'/1)K^f1-d>G21&v(35>V`39V7A4=onx4"
19725 "A1OY5EI0;6Ibgr6M$HS7Q<)58C5w,;WoA*#[%T*#`1g*#d=#+#hI5+#lUG+#pbY+#tnl+#x$),#&1;,#*=M,#.I`,#2Ur,#6b.-#;w[H#iQtA#m^0B#qjBB#uvTB##-hB#'9$C#+E6C#"
19726 "/QHC#3^ZC#7jmC#;v)D#?,<D#C8ND#GDaD#KPsD#O]/E#g1A5#KA*1#gC17#MGd;#8(02#L-d3#rWM4#Hga1#,<w0#T.j<#O#'2#CYN1#qa^:#_4m3#o@/=#eG8=#t8J5#`+78#4uI-#"
19727 "m3B2#SB[8#Q0@8#i[*9#iOn8#1Nm;#^sN9#qh<9#:=x-#P;K2#$%X9#bC+.#Rg;<#mN=.#MTF.#RZO.#2?)4#Y#(/#[)1/#b;L/#dAU/#0Sv;#lY$0#n`-0#sf60#(F24#wrH0#%/e0#"
19728 "TmD<#%JSMFove:CTBEXI:<eh2g)B,3h2^G3i;#d3jD>)4kMYD4lVu`4m`:&5niUA5@(A5BA1]PBB:xlBCC=2CDLXMCEUtiCf&0g2'tN?PGT4CPGT4CPGT4CPGT4CPGT4CPGT4CPGT4CP"
19729 "GT4CPGT4CPGT4CPGT4CPGT4CPGT4CP-qekC`.9kEg^+F$kwViFJTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5o,^<-28ZI'O?;xp"
19730 "O?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xp;7q-#lLYI:xvD=#";
19734 #define NK_CURSOR_DATA_W 90
19735 #define NK_CURSOR_DATA_H 27
19736 NK_GLOBAL
const char nk_custom_cursor_data[NK_CURSOR_DATA_W * NK_CURSOR_DATA_H + 1] =
19738 "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX"
19739 "..- -X.....X- X.X - X.X -X.....X - X.....X"
19740 "--- -XXX.XXX- X...X - X...X -X....X - X....X"
19741 "X - X.X - X.....X - X.....X -X...X - X...X"
19742 "XX - X.X -X.......X- X.......X -X..X.X - X.X..X"
19743 "X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X"
19744 "X..X - X.X - X.X - X.X -XX X.X - X.X XX"
19745 "X...X - X.X - X.X - XX X.X XX - X.X - X.X "
19746 "X....X - X.X - X.X - X.X X.X X.X - X.X - X.X "
19747 "X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X "
19748 "X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X "
19749 "X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X "
19750 "X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X "
19751 "X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X "
19752 "X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X "
19753 "X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X "
19754 "X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX "
19755 "X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------"
19756 "X.X X..X - -X.......X- X.......X - XX XX - "
19757 "XX X..X - - X.....X - X.....X - X.X X.X - "
19758 " X..X - X...X - X...X - X..X X..X - "
19759 " XX - X.X - X.X - X...XXXXXXXXXXXXX...X - "
19760 "------------ - X - X -X.....................X- "
19761 " ----------------------------------- X...XXXXXXXXXXXXX...X - "
19768 #pragma clang diagnostic pop
19769 #elif defined(__GNUC__) || defined(__GNUG__)
19770 #pragma GCC diagnostic pop
19773 NK_GLOBAL
unsigned char *nk__barrier;
19774 NK_GLOBAL
unsigned char *nk__barrier2;
19775 NK_GLOBAL
unsigned char *nk__barrier3;
19776 NK_GLOBAL
unsigned char *nk__barrier4;
19777 NK_GLOBAL
unsigned char *nk__dout;
19789 NK_INTERN
unsigned int
19790 nk_decompress_length(
unsigned char *input)
19792 return (
unsigned int)((input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11]);
19806 nk__match(
unsigned char *data,
unsigned int length)
19809 NK_ASSERT (nk__dout + length <= nk__barrier);
19810 if (nk__dout + length > nk__barrier) { nk__dout += length;
return; }
19811 if (data < nk__barrier4) { nk__dout = nk__barrier+1;
return; }
19812 while (length--) *nk__dout++ = *data++;
19826 nk__lit(
unsigned char *data,
unsigned int length)
19828 NK_ASSERT (nk__dout + length <= nk__barrier);
19829 if (nk__dout + length > nk__barrier) { nk__dout += length;
return; }
19830 if (data < nk__barrier2) { nk__dout = nk__barrier+1;
return; }
19831 NK_MEMCPY(nk__dout, data, length);
19832 nk__dout += length;
19844 NK_INTERN
unsigned char*
19845 nk_decompress_token(
unsigned char *i)
19847 #define nk__in2(x) ((i[x] << 8) + i[(x)+1])
19848 #define nk__in3(x) ((i[x] << 16) + nk__in2((x)+1))
19849 #define nk__in4(x) ((i[x] << 24) + nk__in3((x)+1))
19852 if (*i >= 0x80) nk__match(nk__dout-i[1]-1, (
unsigned int)i[0] - 0x80 + 1), i += 2;
19853 else if (*i >= 0x40) nk__match(nk__dout-(nk__in2(0) - 0x4000 + 1), (
unsigned int)i[2]+1), i += 3;
19854 else nk__lit(i+1, (
unsigned int)i[0] - 0x20 + 1), i += 1 + (i[0] - 0x20 + 1);
19856 if (*i >= 0x18) nk__match(nk__dout-(
unsigned int)(nk__in3(0) - 0x180000 + 1), (
unsigned int)i[3]+1), i += 4;
19857 else if (*i >= 0x10) nk__match(nk__dout-(
unsigned int)(nk__in3(0) - 0x100000 + 1), (
unsigned int)nk__in2(3)+1), i += 5;
19858 else if (*i >= 0x08) nk__lit(i+2, (
unsigned int)nk__in2(0) - 0x0800 + 1), i += 2 + (nk__in2(0) - 0x0800 + 1);
19859 else if (*i == 0x07) nk__lit(i+3, (
unsigned int)nk__in2(1) + 1), i += 3 + (nk__in2(1) + 1);
19860 else if (*i == 0x06) nk__match(nk__dout-(
unsigned int)(nk__in3(1)+1), i[4]+1u), i += 5;
19861 else if (*i == 0x04) nk__match(nk__dout-(
unsigned int)(nk__in3(1)+1), (
unsigned int)nk__in2(4)+1u), i += 6;
19877 NK_INTERN
unsigned int
19878 nk_adler32(
unsigned int adler32,
unsigned char *buffer,
unsigned int buflen)
19880 const unsigned long ADLER_MOD = 65521;
19881 unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16;
19882 unsigned long blocklen, i;
19884 blocklen = buflen % 5552;
19886 for (i=0; i + 7 < blocklen; i += 8) {
19887 s1 += buffer[0]; s2 += s1;
19888 s1 += buffer[1]; s2 += s1;
19889 s1 += buffer[2]; s2 += s1;
19890 s1 += buffer[3]; s2 += s1;
19891 s1 += buffer[4]; s2 += s1;
19892 s1 += buffer[5]; s2 += s1;
19893 s1 += buffer[6]; s2 += s1;
19894 s1 += buffer[7]; s2 += s1;
19897 for (; i < blocklen; ++i) {
19898 s1 += *buffer++; s2 += s1;
19901 s1 %= ADLER_MOD; s2 %= ADLER_MOD;
19902 buflen -= (
unsigned int)blocklen;
19905 return (
unsigned int)(s2 << 16) + (
unsigned int)s1;
19919 NK_INTERN
unsigned int
19920 nk_decompress(
unsigned char *output,
unsigned char *i,
unsigned int length)
19923 if (nk__in4(0) != 0x57bC0000)
return 0;
19924 if (nk__in4(4) != 0)
return 0;
19925 olen = nk_decompress_length(i);
19927 nk__barrier3 = i+length;
19928 nk__barrier = output + olen;
19929 nk__barrier4 = output;
19934 unsigned char *old_i = i;
19935 i = nk_decompress_token(i);
19937 if (*i == 0x05 && i[1] == 0xfa) {
19938 NK_ASSERT(nk__dout == output + olen);
19939 if (nk__dout != output + olen)
return 0;
19940 if (nk_adler32(1, output, olen) != (
unsigned int) nk__in4(2))
19948 NK_ASSERT(nk__dout <= output + olen);
19949 if (nk__dout > output + olen)
19963 NK_INTERN
unsigned int
19964 nk_decode_85_byte(
char c)
19966 return (
unsigned int)((c >=
'\\') ? c-36 : c-35);
19980 nk_decode_85(
unsigned char* dst,
const unsigned char* src)
19985 nk_decode_85_byte((
char)src[0]) +
19986 85 * (nk_decode_85_byte((
char)src[1]) +
19987 85 * (nk_decode_85_byte((
char)src[2]) +
19988 85 * (nk_decode_85_byte((
char)src[3]) +
19989 85 * nk_decode_85_byte((
char)src[4]))));
19992 dst[0] = (
unsigned char)((tmp >> 0) & 0xFF);
19993 dst[1] = (
unsigned char)((tmp >> 8) & 0xFF);
19994 dst[2] = (
unsigned char)((tmp >> 16) & 0xFF);
19995 dst[3] = (
unsigned char)((tmp >> 24) & 0xFF);
20017 NK_API
struct nk_font_config
20018 nk_font_config(float pixel_height)
20020 struct nk_font_config cfg;
20021 nk_zero_struct(cfg);
20024 cfg.ttf_data_owned_by_atlas = 0;
20025 cfg.size = pixel_height;
20026 cfg.oversample_h = 3;
20027 cfg.oversample_v = 1;
20028 cfg.pixel_snap = 0;
20029 cfg.coord_type = NK_COORD_UV;
20031 cfg.range = nk_font_default_glyph_ranges();
20032 cfg.merge_mode = 0;
20033 cfg.fallback_glyph =
'?';
20038 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
20050 nk_font_atlas_init_default(
struct nk_font_atlas *atlas)
20053 if (!atlas)
return;
20054 nk_zero_struct(*atlas);
20055 atlas->temporary.userdata.ptr = 0;
20056 atlas->temporary.alloc = nk_malloc;
20057 atlas->temporary.free = nk_mfree;
20058 atlas->permanent.userdata.ptr = 0;
20059 atlas->permanent.alloc = nk_malloc;
20060 atlas->permanent.free = nk_mfree;
20075 nk_font_atlas_init(
struct nk_font_atlas *atlas,
const struct nk_allocator *alloc)
20079 if (!atlas || !alloc)
return;
20080 nk_zero_struct(*atlas);
20081 atlas->permanent = *alloc;
20082 atlas->temporary = *alloc;
20095 nk_font_atlas_init_custom(
struct nk_font_atlas *atlas,
20099 NK_ASSERT(permanent);
20100 NK_ASSERT(temporary);
20101 if (!atlas || !permanent || !temporary)
return;
20102 nk_zero_struct(*atlas);
20103 atlas->permanent = *permanent;
20104 atlas->temporary = *temporary;
20117 nk_font_atlas_begin(
struct nk_font_atlas *atlas)
20120 NK_ASSERT(atlas->temporary.alloc && atlas->temporary.free);
20121 NK_ASSERT(atlas->permanent.alloc && atlas->permanent.free);
20122 if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free ||
20123 !atlas->temporary.alloc || !atlas->temporary.free)
return;
20124 if (atlas->glyphs) {
20125 atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
20128 if (atlas->pixel) {
20129 atlas->permanent.free(atlas->permanent.userdata, atlas->pixel);
20144 NK_API
struct nk_font*
20145 nk_font_atlas_add(
struct nk_font_atlas *atlas,
const struct nk_font_config *config)
20147 struct nk_font *font = 0;
20148 struct nk_font_config *cfg;
20151 NK_ASSERT(atlas->permanent.alloc);
20152 NK_ASSERT(atlas->permanent.free);
20153 NK_ASSERT(atlas->temporary.alloc);
20154 NK_ASSERT(atlas->temporary.free);
20157 NK_ASSERT(config->ttf_blob);
20158 NK_ASSERT(config->ttf_size);
20159 NK_ASSERT(config->size > 0.0f);
20161 if (!atlas || !config || !config->ttf_blob || !config->ttf_size || config->size <= 0.0f||
20162 !atlas->permanent.alloc || !atlas->permanent.free ||
20163 !atlas->temporary.alloc || !atlas->temporary.free)
20167 cfg = (
struct nk_font_config*)
20168 atlas->permanent.alloc(atlas->permanent.userdata,0,
sizeof(
struct nk_font_config));
20169 NK_MEMCPY(cfg, config,
sizeof(*config));
20173 if (!config->merge_mode) {
20175 if (!atlas->config) {
20176 atlas->config = cfg;
20179 struct nk_font_config *i = atlas->config;
20180 while (i->next) i = i->next;
20185 font = (
struct nk_font*)
20186 atlas->permanent.alloc(atlas->permanent.userdata,0,
sizeof(
struct nk_font));
20188 nk_zero(font,
sizeof(*font));
20189 if (!font)
return 0;
20190 font->config = cfg;
20193 if (!atlas->fonts) {
20194 atlas->fonts = font;
20197 struct nk_font *i = atlas->fonts;
20198 while (i->next) i = i->next;
20202 cfg->font = &font->info;
20205 struct nk_font *f = 0;
20206 struct nk_font_config *c = 0;
20207 NK_ASSERT(atlas->font_num);
20210 cfg->font = &f->info;
20218 if (!config->ttf_data_owned_by_atlas) {
20219 cfg->ttf_blob = atlas->permanent.alloc(atlas->permanent.userdata,0, cfg->ttf_size);
20220 NK_ASSERT(cfg->ttf_blob);
20221 if (!cfg->ttf_blob) {
20225 NK_MEMCPY(cfg->ttf_blob, config->ttf_blob, cfg->ttf_size);
20226 cfg->ttf_data_owned_by_atlas = 1;
20242 NK_API
struct nk_font*
20243 nk_font_atlas_add_from_memory(
struct nk_font_atlas *atlas,
void *memory,
20244 nk_size size,
float height,
const struct nk_font_config *config)
20246 struct nk_font_config cfg;
20251 NK_ASSERT(atlas->temporary.alloc);
20252 NK_ASSERT(atlas->temporary.free);
20253 NK_ASSERT(atlas->permanent.alloc);
20254 NK_ASSERT(atlas->permanent.free);
20255 if (!atlas || !atlas->temporary.alloc || !atlas->temporary.free || !memory || !size ||
20256 !atlas->permanent.alloc || !atlas->permanent.free)
20259 cfg = (config) ? *config: nk_font_config(height);
20260 cfg.ttf_blob = memory;
20261 cfg.ttf_size = size;
20263 cfg.ttf_data_owned_by_atlas = 0;
20264 return nk_font_atlas_add(atlas, &cfg);
20266 #ifdef NK_INCLUDE_STANDARD_IO
20278 NK_API
struct nk_font*
20279 nk_font_atlas_add_from_file(
struct nk_font_atlas *atlas,
const char *file_path,
20280 float height,
const struct nk_font_config *config)
20284 struct nk_font_config cfg;
20287 NK_ASSERT(atlas->temporary.alloc);
20288 NK_ASSERT(atlas->temporary.free);
20289 NK_ASSERT(atlas->permanent.alloc);
20290 NK_ASSERT(atlas->permanent.free);
20292 if (!atlas || !file_path)
return 0;
20293 memory = nk_file_load(file_path, &size, &atlas->permanent);
20294 if (!memory)
return 0;
20296 cfg = (config) ? *config: nk_font_config(height);
20297 cfg.ttf_blob = memory;
20298 cfg.ttf_size = size;
20300 cfg.ttf_data_owned_by_atlas = 1;
20301 return nk_font_atlas_add(atlas, &cfg);
20314 NK_API
struct nk_font*
20315 nk_font_atlas_add_compressed(
struct nk_font_atlas *atlas,
20316 void *compressed_data, nk_size compressed_size,
float height,
20317 const struct nk_font_config *config)
20319 unsigned int decompressed_size;
20320 void *decompressed_data;
20321 struct nk_font_config cfg;
20324 NK_ASSERT(atlas->temporary.alloc);
20325 NK_ASSERT(atlas->temporary.free);
20326 NK_ASSERT(atlas->permanent.alloc);
20327 NK_ASSERT(atlas->permanent.free);
20329 NK_ASSERT(compressed_data);
20330 NK_ASSERT(compressed_size);
20331 if (!atlas || !compressed_data || !atlas->temporary.alloc || !atlas->temporary.free ||
20332 !atlas->permanent.alloc || !atlas->permanent.free)
20335 decompressed_size = nk_decompress_length((
unsigned char*)compressed_data);
20336 decompressed_data = atlas->permanent.alloc(atlas->permanent.userdata,0,decompressed_size);
20337 NK_ASSERT(decompressed_data);
20338 if (!decompressed_data)
return 0;
20339 nk_decompress((
unsigned char*)decompressed_data, (
unsigned char*)compressed_data,
20340 (
unsigned int)compressed_size);
20342 cfg = (config) ? *config: nk_font_config(height);
20343 cfg.ttf_blob = decompressed_data;
20344 cfg.ttf_size = decompressed_size;
20346 cfg.ttf_data_owned_by_atlas = 1;
20347 return nk_font_atlas_add(atlas, &cfg);
20359 NK_API
struct nk_font*
20360 nk_font_atlas_add_compressed_base85(
struct nk_font_atlas *atlas,
20361 const char *data_base85,
float height,
const struct nk_font_config *config)
20363 int compressed_size;
20364 void *compressed_data;
20365 struct nk_font *font;
20368 NK_ASSERT(atlas->temporary.alloc);
20369 NK_ASSERT(atlas->temporary.free);
20370 NK_ASSERT(atlas->permanent.alloc);
20371 NK_ASSERT(atlas->permanent.free);
20373 NK_ASSERT(data_base85);
20374 if (!atlas || !data_base85 || !atlas->temporary.alloc || !atlas->temporary.free ||
20375 !atlas->permanent.alloc || !atlas->permanent.free)
20378 compressed_size = (((int)nk_strlen(data_base85) + 4) / 5) * 4;
20379 compressed_data = atlas->temporary.alloc(atlas->temporary.userdata,0, (nk_size)compressed_size);
20380 NK_ASSERT(compressed_data);
20381 if (!compressed_data)
return 0;
20382 nk_decode_85((
unsigned char*)compressed_data, (
const unsigned char*)data_base85);
20383 font = nk_font_atlas_add_compressed(atlas, compressed_data,
20384 (nk_size)compressed_size, height, config);
20385 atlas->temporary.free(atlas->temporary.userdata, compressed_data);
20389 #ifdef NK_INCLUDE_DEFAULT_FONT
20400 NK_API
struct nk_font*
20401 nk_font_atlas_add_default(
struct nk_font_atlas *atlas,
20402 float pixel_height,
const struct nk_font_config *config)
20405 NK_ASSERT(atlas->temporary.alloc);
20406 NK_ASSERT(atlas->temporary.free);
20407 NK_ASSERT(atlas->permanent.alloc);
20408 NK_ASSERT(atlas->permanent.free);
20409 return nk_font_atlas_add_compressed_base85(atlas,
20410 nk_proggy_clean_ttf_compressed_data_base85, pixel_height, config);
20426 nk_font_atlas_bake(
struct nk_font_atlas *atlas,
int *width,
int *height,
20427 enum nk_font_atlas_format fmt)
20431 nk_size tmp_size, img_size;
20432 struct nk_font *font_iter;
20433 struct nk_font_baker *baker;
20436 NK_ASSERT(atlas->temporary.alloc);
20437 NK_ASSERT(atlas->temporary.free);
20438 NK_ASSERT(atlas->permanent.alloc);
20439 NK_ASSERT(atlas->permanent.free);
20443 if (!atlas || !width || !height ||
20444 !atlas->temporary.alloc || !atlas->temporary.free ||
20445 !atlas->permanent.alloc || !atlas->permanent.free)
20448 #ifdef NK_INCLUDE_DEFAULT_FONT
20450 if (!atlas->font_num)
20451 atlas->default_font = nk_font_atlas_add_default(atlas, 13.0f, 0);
20453 NK_ASSERT(atlas->font_num);
20454 if (!atlas->font_num)
return 0;
20457 nk_font_baker_memory(&tmp_size, &atlas->glyph_count, atlas->config, atlas->font_num);
20458 tmp = atlas->temporary.alloc(atlas->temporary.userdata,0, tmp_size);
20460 if (!tmp)
goto failed;
20461 NK_MEMSET(tmp,0,tmp_size);
20464 baker = nk_font_baker(tmp, atlas->glyph_count, atlas->font_num, &atlas->temporary);
20465 atlas->glyphs = (
struct nk_font_glyph*)atlas->permanent.alloc(
20466 atlas->permanent.userdata,0,
sizeof(
struct nk_font_glyph)*(nk_size)atlas->glyph_count);
20467 NK_ASSERT(atlas->glyphs);
20468 if (!atlas->glyphs)
20472 atlas->custom.w = (NK_CURSOR_DATA_W*2)+1;
20473 atlas->custom.h = NK_CURSOR_DATA_H + 1;
20474 if (!nk_font_bake_pack(baker, &img_size, width, height, &atlas->custom,
20475 atlas->config, atlas->font_num, &atlas->temporary))
20479 atlas->pixel = atlas->temporary.alloc(atlas->temporary.userdata,0, img_size);
20480 NK_ASSERT(atlas->pixel);
20485 nk_font_bake(baker, atlas->pixel, *width, *height,
20486 atlas->glyphs, atlas->glyph_count, atlas->config, atlas->font_num);
20487 nk_font_bake_custom_data(atlas->pixel, *width, *height, atlas->custom,
20488 nk_custom_cursor_data, NK_CURSOR_DATA_W, NK_CURSOR_DATA_H,
'.',
'X');
20490 if (fmt == NK_FONT_ATLAS_RGBA32) {
20492 void *img_rgba = atlas->temporary.alloc(atlas->temporary.userdata,0,
20493 (nk_size)(*width * *height * 4));
20494 NK_ASSERT(img_rgba);
20495 if (!img_rgba)
goto failed;
20496 nk_font_bake_convert(img_rgba, *width, *height, atlas->pixel);
20497 atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
20498 atlas->pixel = img_rgba;
20500 atlas->tex_width = *width;
20501 atlas->tex_height = *height;
20504 for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) {
20505 struct nk_font *font = font_iter;
20506 struct nk_font_config *config = font->config;
20507 nk_font_init(font, config->size, config->fallback_glyph, atlas->glyphs,
20508 config->font, nk_handle_ptr(0));
20512 {NK_STORAGE
const struct nk_vec2 nk_cursor_data[NK_CURSOR_COUNT][3] = {
20514 {{ 0, 3}, {12,19}, { 0, 0}},
20515 {{13, 0}, { 7,16}, { 4, 8}},
20516 {{31, 0}, {23,23}, {11,11}},
20517 {{21, 0}, { 9, 23}, { 5,11}},
20518 {{55,18}, {23, 9}, {11, 5}},
20519 {{73, 0}, {17,17}, { 9, 9}},
20520 {{55, 0}, {17,17}, { 9, 9}}
20522 for (i = 0; i < NK_CURSOR_COUNT; ++i) {
20523 struct nk_cursor *cursor = &atlas->cursors[i];
20524 cursor->img.w = (
unsigned short)*width;
20525 cursor->img.h = (
unsigned short)*height;
20526 cursor->img.region[0] = (
unsigned short)(atlas->custom.x + nk_cursor_data[i][0].x);
20527 cursor->img.region[1] = (
unsigned short)(atlas->custom.y + nk_cursor_data[i][0].y);
20528 cursor->img.region[2] = (
unsigned short)nk_cursor_data[i][1].x;
20529 cursor->img.region[3] = (
unsigned short)nk_cursor_data[i][1].y;
20530 cursor->size = nk_cursor_data[i][1];
20531 cursor->offset = nk_cursor_data[i][2];
20534 atlas->temporary.free(atlas->temporary.userdata, tmp);
20535 return atlas->pixel;
20539 if (tmp) atlas->temporary.free(atlas->temporary.userdata, tmp);
20540 if (atlas->glyphs) {
20541 atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
20544 if (atlas->pixel) {
20545 atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
20562 nk_font_atlas_end(
struct nk_font_atlas *atlas,
nk_handle texture,
20566 struct nk_font *font_iter;
20569 if (!tex_null)
return;
20570 tex_null->texture = texture;
20574 tex_null->texture = texture;
20575 tex_null->
uv.x = (atlas->custom.x + 0.5f)/(
float)atlas->tex_width;
20576 tex_null->
uv.y = (atlas->custom.y + 0.5f)/(
float)atlas->tex_height;
20578 for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) {
20579 font_iter->texture = texture;
20580 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
20581 font_iter->handle.texture = texture;
20584 for (i = 0; i < NK_CURSOR_COUNT; ++i)
20585 atlas->cursors[i].img.handle = texture;
20587 atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
20589 atlas->tex_width = 0;
20590 atlas->tex_height = 0;
20591 atlas->custom.x = 0;
20592 atlas->custom.y = 0;
20593 atlas->custom.w = 0;
20594 atlas->custom.h = 0;
20607 nk_font_atlas_cleanup(
struct nk_font_atlas *atlas)
20610 NK_ASSERT(atlas->temporary.alloc);
20611 NK_ASSERT(atlas->temporary.free);
20612 NK_ASSERT(atlas->permanent.alloc);
20613 NK_ASSERT(atlas->permanent.free);
20614 if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free)
return;
20615 if (atlas->config) {
20616 struct nk_font_config *iter;
20617 for (iter = atlas->config; iter; iter = iter->next) {
20618 struct nk_font_config *i;
20619 for (i = iter->n; i != iter; i = i->n) {
20620 atlas->permanent.free(atlas->permanent.userdata, i->ttf_blob);
20623 atlas->permanent.free(atlas->permanent.userdata, iter->ttf_blob);
20624 iter->ttf_blob = 0;
20639 nk_font_atlas_clear(
struct nk_font_atlas *atlas)
20642 NK_ASSERT(atlas->temporary.alloc);
20643 NK_ASSERT(atlas->temporary.free);
20644 NK_ASSERT(atlas->permanent.alloc);
20645 NK_ASSERT(atlas->permanent.free);
20646 if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free)
return;
20648 if (atlas->config) {
20649 struct nk_font_config *iter, *next;
20650 for (iter = atlas->config; iter; iter = next) {
20651 struct nk_font_config *i, *n;
20652 for (i = iter->n; i != iter; i = n) {
20655 atlas->permanent.free(atlas->permanent.userdata, i->ttf_blob);
20656 atlas->permanent.free(atlas->permanent.userdata, i);
20660 atlas->permanent.free(atlas->permanent.userdata, iter->ttf_blob);
20661 atlas->permanent.free(atlas->permanent.userdata, iter);
20665 if (atlas->fonts) {
20666 struct nk_font *iter, *next;
20667 for (iter = atlas->fonts; iter; iter = next) {
20669 atlas->permanent.free(atlas->permanent.userdata, iter);
20674 atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
20675 nk_zero_struct(*atlas);
20705 for (i = 0; i < NK_BUTTON_MAX; ++i)
20706 in->mouse.buttons[i].clicked = 0;
20708 in->keyboard.text_len = 0;
20709 in->mouse.scroll_delta =
nk_vec2(0,0);
20710 in->mouse.prev.x = in->mouse.pos.x;
20711 in->mouse.prev.y = in->mouse.pos.y;
20712 in->mouse.delta.x = 0;
20713 in->mouse.delta.y = 0;
20714 for (i = 0; i < NK_KEY_MAX; i++)
20715 in->keyboard.keys[i].clicked = 0;
20734 if (in->mouse.grab)
20735 in->mouse.grab = 0;
20736 if (in->mouse.ungrab) {
20737 in->mouse.grabbed = 0;
20738 in->mouse.ungrab = 0;
20739 in->mouse.grab = 0;
20761 in->mouse.pos.x = (float)x;
20762 in->mouse.pos.y = (float)y;
20763 in->mouse.delta.x = in->mouse.pos.x - in->mouse.prev.x;
20764 in->mouse.delta.y = in->mouse.pos.y - in->mouse.prev.y;
20785 #ifdef NK_KEYSTATE_BASED_INPUT
20786 if (in->keyboard.keys[key].down != down)
20787 in->keyboard.keys[key].clicked++;
20789 in->keyboard.keys[key].clicked++;
20791 in->keyboard.keys[key].down = down;
20815 if (in->mouse.buttons[
id].down == down)
return;
20817 btn = &in->mouse.buttons[id];
20818 btn->clicked_pos.x = (float)x;
20819 btn->clicked_pos.y = (float)y;
20824 in->mouse.delta.x = 0;
20825 in->mouse.delta.y = 0;
20826 #ifdef NK_BUTTON_TRIGGER_ON_RELEASE
20827 if (down == 1 &&
id == NK_BUTTON_LEFT)
20829 in->mouse.down_pos.x = btn->clicked_pos.x;
20830 in->mouse.down_pos.y = btn->clicked_pos.y;
20850 ctx->input.mouse.scroll_delta.x += val.x;
20851 ctx->input.mouse.scroll_delta.y += val.y;
20875 len = nk_utf_decode(glyph, &unicode,
NK_UTF_SIZE);
20876 if (len && ((in->keyboard.text_len + len) < NK_INPUT_MAX)) {
20877 nk_utf_encode(unicode, &in->keyboard.text[in->keyboard.text_len],
20878 NK_INPUT_MAX - in->keyboard.text_len);
20879 in->keyboard.text_len += len;
20934 nk_input_has_mouse_click(
const struct nk_input *i,
enum nk_buttons
id)
20937 if (!i)
return nk_false;
20938 btn = &i->mouse.buttons[id];
20939 return (btn->clicked && btn->down == nk_false) ? nk_true : nk_false;
20953 nk_input_has_mouse_click_in_rect(
const struct nk_input *i,
enum nk_buttons
id,
20957 if (!i)
return nk_false;
20958 btn = &i->mouse.buttons[id];
20959 if (!NK_INBOX(btn->clicked_pos.x,btn->clicked_pos.y,b.x,b.y,b.w,b.h))
20975 nk_input_has_mouse_click_in_button_rect(
const struct nk_input *i,
enum nk_buttons
id,
20979 if (!i)
return nk_false;
20980 btn = &i->mouse.buttons[id];
20981 #ifdef NK_BUTTON_TRIGGER_ON_RELEASE
20982 if (!NK_INBOX(btn->clicked_pos.x,btn->clicked_pos.y,b.x,b.y,b.w,b.h)
20983 || !NK_INBOX(i->mouse.down_pos.x,i->mouse.down_pos.y,b.x,b.y,b.w,b.h))
20985 if (!NK_INBOX(btn->clicked_pos.x,btn->clicked_pos.y,b.x,b.y,b.w,b.h))
21002 nk_input_has_mouse_click_down_in_rect(
const struct nk_input *i,
enum nk_buttons
id,
21003 struct nk_rect b, nk_bool down)
21006 if (!i)
return nk_false;
21007 btn = &i->mouse.buttons[id];
21008 return nk_input_has_mouse_click_in_rect(i,
id, b) && (btn->down == down);
21022 nk_input_is_mouse_click_in_rect(
const struct nk_input *i,
enum nk_buttons
id,
21026 if (!i)
return nk_false;
21027 btn = &i->mouse.buttons[id];
21028 return (nk_input_has_mouse_click_down_in_rect(i,
id, b, nk_false) &&
21029 btn->clicked) ? nk_true : nk_false;
21043 nk_input_is_mouse_click_down_in_rect(
const struct nk_input *i,
enum nk_buttons
id,
21044 struct nk_rect b, nk_bool down)
21047 if (!i)
return nk_false;
21048 btn = &i->mouse.buttons[id];
21049 return (nk_input_has_mouse_click_down_in_rect(i,
id, b, down) &&
21050 btn->clicked) ? nk_true : nk_false;
21064 nk_input_any_mouse_click_in_rect(
const struct nk_input *in,
struct nk_rect b)
21067 for (i = 0; i < NK_BUTTON_MAX; ++i)
21068 down = down || nk_input_is_mouse_click_in_rect(in, (
enum nk_buttons)i, b);
21083 nk_input_is_mouse_hovering_rect(
const struct nk_input *i,
struct nk_rect rect)
21085 if (!i)
return nk_false;
21086 return NK_INBOX(i->mouse.pos.x, i->mouse.pos.y, rect.x, rect.y, rect.w, rect.h);
21100 nk_input_is_mouse_prev_hovering_rect(
const struct nk_input *i,
struct nk_rect rect)
21102 if (!i)
return nk_false;
21103 return NK_INBOX(i->mouse.prev.x, i->mouse.prev.y, rect.x, rect.y, rect.w, rect.h);
21118 nk_input_mouse_clicked(
const struct nk_input *i,
enum nk_buttons
id,
struct nk_rect rect)
21120 if (!i)
return nk_false;
21121 if (!nk_input_is_mouse_hovering_rect(i, rect))
return nk_false;
21122 return nk_input_is_mouse_click_in_rect(i,
id, rect);
21136 nk_input_is_mouse_down(
const struct nk_input *i,
enum nk_buttons
id)
21138 if (!i)
return nk_false;
21139 return i->mouse.buttons[id].down;
21153 nk_input_is_mouse_pressed(
const struct nk_input *i,
enum nk_buttons
id)
21156 if (!i)
return nk_false;
21157 b = &i->mouse.buttons[id];
21158 if (b->down && b->clicked)
21174 nk_input_is_mouse_released(
const struct nk_input *i,
enum nk_buttons
id)
21176 if (!i)
return nk_false;
21177 return (!i->mouse.buttons[
id].down && i->mouse.buttons[
id].clicked);
21191 nk_input_is_key_pressed(
const struct nk_input *i,
enum nk_keys key)
21194 if (!i)
return nk_false;
21195 k = &i->keyboard.keys[key];
21196 if ((k->down && k->clicked) || (!k->down && k->clicked >= 2))
21212 nk_input_is_key_released(
const struct nk_input *i,
enum nk_keys key)
21215 if (!i)
return nk_false;
21216 k = &i->keyboard.keys[key];
21217 if ((!k->down && k->clicked) || (k->down && k->clicked >= 2))
21233 nk_input_is_key_down(
const struct nk_input *i,
enum nk_keys key)
21236 if (!i)
return nk_false;
21237 k = &i->keyboard.keys[key];
21238 if (k->down)
return nk_true;
21263 NK_API
void nk_style_default(
struct nk_context *ctx){nk_style_from_table(ctx, 0);}
21264 #define NK_COLOR_MAP(NK_COLOR)\
21265 NK_COLOR(NK_COLOR_TEXT, 175,175,175,255) \
21266 NK_COLOR(NK_COLOR_WINDOW, 45, 45, 45, 255) \
21267 NK_COLOR(NK_COLOR_HEADER, 40, 40, 40, 255) \
21268 NK_COLOR(NK_COLOR_BORDER, 65, 65, 65, 255) \
21269 NK_COLOR(NK_COLOR_BUTTON, 50, 50, 50, 255) \
21270 NK_COLOR(NK_COLOR_BUTTON_HOVER, 40, 40, 40, 255) \
21271 NK_COLOR(NK_COLOR_BUTTON_ACTIVE, 35, 35, 35, 255) \
21272 NK_COLOR(NK_COLOR_TOGGLE, 100,100,100,255) \
21273 NK_COLOR(NK_COLOR_TOGGLE_HOVER, 120,120,120,255) \
21274 NK_COLOR(NK_COLOR_TOGGLE_CURSOR, 45, 45, 45, 255) \
21275 NK_COLOR(NK_COLOR_SELECT, 45, 45, 45, 255) \
21276 NK_COLOR(NK_COLOR_SELECT_ACTIVE, 35, 35, 35,255) \
21277 NK_COLOR(NK_COLOR_SLIDER, 38, 38, 38, 255) \
21278 NK_COLOR(NK_COLOR_SLIDER_CURSOR, 100,100,100,255) \
21279 NK_COLOR(NK_COLOR_SLIDER_CURSOR_HOVER, 120,120,120,255) \
21280 NK_COLOR(NK_COLOR_SLIDER_CURSOR_ACTIVE, 150,150,150,255) \
21281 NK_COLOR(NK_COLOR_PROPERTY, 38, 38, 38, 255) \
21282 NK_COLOR(NK_COLOR_EDIT, 38, 38, 38, 255) \
21283 NK_COLOR(NK_COLOR_EDIT_CURSOR, 175,175,175,255) \
21284 NK_COLOR(NK_COLOR_COMBO, 45, 45, 45, 255) \
21285 NK_COLOR(NK_COLOR_CHART, 120,120,120,255) \
21286 NK_COLOR(NK_COLOR_CHART_COLOR, 45, 45, 45, 255) \
21287 NK_COLOR(NK_COLOR_CHART_COLOR_HIGHLIGHT, 255, 0, 0, 255) \
21288 NK_COLOR(NK_COLOR_SCROLLBAR, 40, 40, 40, 255) \
21289 NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR, 100,100,100,255) \
21290 NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR_HOVER, 120,120,120,255) \
21291 NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR_ACTIVE, 150,150,150,255) \
21292 NK_COLOR(NK_COLOR_TAB_HEADER, 40, 40, 40,255) \
21293 NK_COLOR(NK_COLOR_KNOB, 38, 38, 38, 255) \
21294 NK_COLOR(NK_COLOR_KNOB_CURSOR, 100,100,100,255) \
21295 NK_COLOR(NK_COLOR_KNOB_CURSOR_HOVER, 120,120,120,255) \
21296 NK_COLOR(NK_COLOR_KNOB_CURSOR_ACTIVE, 150,150,150,255)
21299 nk_default_color_style[NK_COLOR_COUNT] = {
21300 #define NK_COLOR(a,b,c,d,e) {b,c,d,e},
21301 NK_COLOR_MAP(NK_COLOR)
21304 NK_GLOBAL
const char *nk_color_names[NK_COLOR_COUNT] = {
21305 #define NK_COLOR(a,b,c,d,e) #a,
21306 NK_COLOR_MAP(NK_COLOR)
21321 nk_style_get_color_by_name(
enum nk_style_colors c)
21323 return nk_color_names[c];
21336 nk_style_item_color(struct
nk_color col)
21339 i.type = NK_STYLE_ITEM_COLOR;
21340 i.data.color = col;
21354 nk_style_item_image(struct
nk_image img)
21357 i.type = NK_STYLE_ITEM_IMAGE;
21358 i.data.image = img;
21375 i.type = NK_STYLE_ITEM_NINE_SLICE;
21376 i.data.slice = slice;
21390 nk_style_item_hide(void)
21393 i.type = NK_STYLE_ITEM_COLOR;
21394 i.data.color = nk_rgba(0,0,0,0);
21429 style = &ctx->style;
21430 table = (!table) ? nk_default_color_style: table;
21433 text = &style->text;
21434 text->color = table[NK_COLOR_TEXT];
21435 text->padding =
nk_vec2(0,0);
21436 text->color_factor = 1.0f;
21437 text->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21440 button = &style->button;
21441 nk_zero_struct(*button);
21442 button->normal = nk_style_item_color(table[NK_COLOR_BUTTON]);
21443 button->hover = nk_style_item_color(table[NK_COLOR_BUTTON_HOVER]);
21444 button->active = nk_style_item_color(table[NK_COLOR_BUTTON_ACTIVE]);
21445 button->border_color = table[NK_COLOR_BORDER];
21446 button->text_background = table[NK_COLOR_BUTTON];
21447 button->text_normal = table[NK_COLOR_TEXT];
21448 button->text_hover = table[NK_COLOR_TEXT];
21449 button->text_active = table[NK_COLOR_TEXT];
21450 button->padding =
nk_vec2(2.0f,2.0f);
21451 button->image_padding =
nk_vec2(0.0f,0.0f);
21452 button->touch_padding =
nk_vec2(0.0f, 0.0f);
21453 button->userdata = nk_handle_ptr(0);
21454 button->text_alignment = NK_TEXT_CENTERED;
21455 button->border = 1.0f;
21456 button->rounding = 4.0f;
21457 button->color_factor_text = 1.0f;
21458 button->color_factor_background = 1.0f;
21459 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21460 button->draw_begin = 0;
21461 button->draw_end = 0;
21464 button = &style->contextual_button;
21465 nk_zero_struct(*button);
21466 button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]);
21467 button->hover = nk_style_item_color(table[NK_COLOR_BUTTON_HOVER]);
21468 button->active = nk_style_item_color(table[NK_COLOR_BUTTON_ACTIVE]);
21469 button->border_color = table[NK_COLOR_WINDOW];
21470 button->text_background = table[NK_COLOR_WINDOW];
21471 button->text_normal = table[NK_COLOR_TEXT];
21472 button->text_hover = table[NK_COLOR_TEXT];
21473 button->text_active = table[NK_COLOR_TEXT];
21474 button->padding =
nk_vec2(2.0f,2.0f);
21475 button->touch_padding =
nk_vec2(0.0f,0.0f);
21476 button->userdata = nk_handle_ptr(0);
21477 button->text_alignment = NK_TEXT_CENTERED;
21478 button->border = 0.0f;
21479 button->rounding = 0.0f;
21480 button->color_factor_text = 1.0f;
21481 button->color_factor_background = 1.0f;
21482 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21483 button->draw_begin = 0;
21484 button->draw_end = 0;
21487 button = &style->menu_button;
21488 nk_zero_struct(*button);
21489 button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]);
21490 button->hover = nk_style_item_color(table[NK_COLOR_WINDOW]);
21491 button->active = nk_style_item_color(table[NK_COLOR_WINDOW]);
21492 button->border_color = table[NK_COLOR_WINDOW];
21493 button->text_background = table[NK_COLOR_WINDOW];
21494 button->text_normal = table[NK_COLOR_TEXT];
21495 button->text_hover = table[NK_COLOR_TEXT];
21496 button->text_active = table[NK_COLOR_TEXT];
21497 button->padding =
nk_vec2(2.0f,2.0f);
21498 button->touch_padding =
nk_vec2(0.0f,0.0f);
21499 button->userdata = nk_handle_ptr(0);
21500 button->text_alignment = NK_TEXT_CENTERED;
21501 button->border = 0.0f;
21502 button->rounding = 1.0f;
21503 button->color_factor_text = 1.0f;
21504 button->color_factor_background = 1.0f;
21505 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21506 button->draw_begin = 0;
21507 button->draw_end = 0;
21510 toggle = &style->checkbox;
21511 nk_zero_struct(*toggle);
21512 toggle->normal = nk_style_item_color(table[NK_COLOR_TOGGLE]);
21513 toggle->hover = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]);
21514 toggle->active = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]);
21515 toggle->cursor_normal = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]);
21516 toggle->cursor_hover = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]);
21517 toggle->userdata = nk_handle_ptr(0);
21518 toggle->text_background = table[NK_COLOR_WINDOW];
21519 toggle->text_normal = table[NK_COLOR_TEXT];
21520 toggle->text_hover = table[NK_COLOR_TEXT];
21521 toggle->text_active = table[NK_COLOR_TEXT];
21522 toggle->padding =
nk_vec2(2.0f, 2.0f);
21523 toggle->touch_padding =
nk_vec2(0,0);
21524 toggle->border_color = nk_rgba(0,0,0,0);
21525 toggle->border = 0.0f;
21526 toggle->spacing = 4;
21527 toggle->color_factor = 1.0f;
21528 toggle->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21531 toggle = &style->option;
21532 nk_zero_struct(*toggle);
21533 toggle->normal = nk_style_item_color(table[NK_COLOR_TOGGLE]);
21534 toggle->hover = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]);
21535 toggle->active = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]);
21536 toggle->cursor_normal = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]);
21537 toggle->cursor_hover = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]);
21538 toggle->userdata = nk_handle_ptr(0);
21539 toggle->text_background = table[NK_COLOR_WINDOW];
21540 toggle->text_normal = table[NK_COLOR_TEXT];
21541 toggle->text_hover = table[NK_COLOR_TEXT];
21542 toggle->text_active = table[NK_COLOR_TEXT];
21543 toggle->padding =
nk_vec2(3.0f, 3.0f);
21544 toggle->touch_padding =
nk_vec2(0,0);
21545 toggle->border_color = nk_rgba(0,0,0,0);
21546 toggle->border = 0.0f;
21547 toggle->spacing = 4;
21548 toggle->color_factor = 1.0f;
21549 toggle->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21552 select = &style->selectable;
21553 nk_zero_struct(*select);
21554 select->normal = nk_style_item_color(table[NK_COLOR_SELECT]);
21555 select->hover = nk_style_item_color(table[NK_COLOR_SELECT]);
21556 select->pressed = nk_style_item_color(table[NK_COLOR_SELECT]);
21557 select->normal_active = nk_style_item_color(table[NK_COLOR_SELECT_ACTIVE]);
21558 select->hover_active = nk_style_item_color(table[NK_COLOR_SELECT_ACTIVE]);
21559 select->pressed_active = nk_style_item_color(table[NK_COLOR_SELECT_ACTIVE]);
21560 select->text_normal = table[NK_COLOR_TEXT];
21561 select->text_hover = table[NK_COLOR_TEXT];
21562 select->text_pressed = table[NK_COLOR_TEXT];
21563 select->text_normal_active = table[NK_COLOR_TEXT];
21564 select->text_hover_active = table[NK_COLOR_TEXT];
21565 select->text_pressed_active = table[NK_COLOR_TEXT];
21566 select->padding =
nk_vec2(2.0f,2.0f);
21567 select->image_padding =
nk_vec2(2.0f,2.0f);
21568 select->touch_padding =
nk_vec2(0,0);
21569 select->userdata = nk_handle_ptr(0);
21570 select->rounding = 0.0f;
21571 select->color_factor = 1.0f;
21572 select->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21573 select->draw_begin = 0;
21574 select->draw_end = 0;
21577 slider = &style->slider;
21578 nk_zero_struct(*slider);
21579 slider->normal = nk_style_item_hide();
21580 slider->hover = nk_style_item_hide();
21581 slider->active = nk_style_item_hide();
21582 slider->bar_normal = table[NK_COLOR_SLIDER];
21583 slider->bar_hover = table[NK_COLOR_SLIDER];
21584 slider->bar_active = table[NK_COLOR_SLIDER];
21585 slider->bar_filled = table[NK_COLOR_SLIDER_CURSOR];
21586 slider->cursor_normal = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR]);
21587 slider->cursor_hover = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_HOVER]);
21588 slider->cursor_active = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_ACTIVE]);
21589 slider->inc_symbol = NK_SYMBOL_TRIANGLE_RIGHT;
21590 slider->dec_symbol = NK_SYMBOL_TRIANGLE_LEFT;
21591 slider->cursor_size =
nk_vec2(16,16);
21592 slider->padding =
nk_vec2(2,2);
21593 slider->spacing =
nk_vec2(2,2);
21594 slider->userdata = nk_handle_ptr(0);
21595 slider->show_buttons = nk_false;
21596 slider->bar_height = 8;
21597 slider->rounding = 0;
21598 slider->color_factor = 1.0f;
21599 slider->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21600 slider->draw_begin = 0;
21601 slider->draw_end = 0;
21604 button = &style->slider.inc_button;
21605 button->normal = nk_style_item_color(nk_rgb(40,40,40));
21606 button->hover = nk_style_item_color(nk_rgb(42,42,42));
21607 button->active = nk_style_item_color(nk_rgb(44,44,44));
21608 button->border_color = nk_rgb(65,65,65);
21609 button->text_background = nk_rgb(40,40,40);
21610 button->text_normal = nk_rgb(175,175,175);
21611 button->text_hover = nk_rgb(175,175,175);
21612 button->text_active = nk_rgb(175,175,175);
21613 button->padding =
nk_vec2(8.0f,8.0f);
21614 button->touch_padding =
nk_vec2(0.0f,0.0f);
21615 button->userdata = nk_handle_ptr(0);
21616 button->text_alignment = NK_TEXT_CENTERED;
21617 button->border = 1.0f;
21618 button->rounding = 0.0f;
21619 button->color_factor_text = 1.0f;
21620 button->color_factor_background = 1.0f;
21621 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21622 button->draw_begin = 0;
21623 button->draw_end = 0;
21624 style->slider.dec_button = style->slider.inc_button;
21627 knob = &style->knob;
21628 nk_zero_struct(*knob);
21629 knob->normal = nk_style_item_hide();
21630 knob->hover = nk_style_item_hide();
21631 knob->active = nk_style_item_hide();
21632 knob->knob_normal = table[NK_COLOR_KNOB];
21633 knob->knob_hover = table[NK_COLOR_KNOB];
21634 knob->knob_active = table[NK_COLOR_KNOB];
21635 knob->cursor_normal = table[NK_COLOR_KNOB_CURSOR];
21636 knob->cursor_hover = table[NK_COLOR_KNOB_CURSOR_HOVER];
21637 knob->cursor_active = table[NK_COLOR_KNOB_CURSOR_ACTIVE];
21639 knob->knob_border_color = table[NK_COLOR_BORDER];
21640 knob->knob_border = 1.0f;
21642 knob->padding =
nk_vec2(2,2);
21643 knob->spacing =
nk_vec2(2,2);
21644 knob->cursor_width = 2;
21645 knob->color_factor = 1.0f;
21646 knob->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21648 knob->userdata = nk_handle_ptr(0);
21649 knob->draw_begin = 0;
21650 knob->draw_end = 0;
21653 prog = &style->progress;
21654 nk_zero_struct(*prog);
21655 prog->normal = nk_style_item_color(table[NK_COLOR_SLIDER]);
21656 prog->hover = nk_style_item_color(table[NK_COLOR_SLIDER]);
21657 prog->active = nk_style_item_color(table[NK_COLOR_SLIDER]);
21658 prog->cursor_normal = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR]);
21659 prog->cursor_hover = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_HOVER]);
21660 prog->cursor_active = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_ACTIVE]);
21661 prog->border_color = nk_rgba(0,0,0,0);
21662 prog->cursor_border_color = nk_rgba(0,0,0,0);
21663 prog->userdata = nk_handle_ptr(0);
21664 prog->padding =
nk_vec2(4,4);
21665 prog->rounding = 0;
21667 prog->cursor_rounding = 0;
21668 prog->cursor_border = 0;
21669 prog->color_factor = 1.0f;
21670 prog->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21671 prog->draw_begin = 0;
21672 prog->draw_end = 0;
21675 scroll = &style->scrollh;
21676 nk_zero_struct(*scroll);
21677 scroll->normal = nk_style_item_color(table[NK_COLOR_SCROLLBAR]);
21678 scroll->hover = nk_style_item_color(table[NK_COLOR_SCROLLBAR]);
21679 scroll->active = nk_style_item_color(table[NK_COLOR_SCROLLBAR]);
21680 scroll->cursor_normal = nk_style_item_color(table[NK_COLOR_SCROLLBAR_CURSOR]);
21681 scroll->cursor_hover = nk_style_item_color(table[NK_COLOR_SCROLLBAR_CURSOR_HOVER]);
21682 scroll->cursor_active = nk_style_item_color(table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE]);
21683 scroll->dec_symbol = NK_SYMBOL_CIRCLE_SOLID;
21684 scroll->inc_symbol = NK_SYMBOL_CIRCLE_SOLID;
21685 scroll->userdata = nk_handle_ptr(0);
21686 scroll->border_color = table[NK_COLOR_SCROLLBAR];
21687 scroll->cursor_border_color = table[NK_COLOR_SCROLLBAR];
21688 scroll->padding =
nk_vec2(0,0);
21689 scroll->show_buttons = nk_false;
21690 scroll->border = 0;
21691 scroll->rounding = 0;
21692 scroll->border_cursor = 0;
21693 scroll->rounding_cursor = 0;
21694 scroll->color_factor = 1.0f;
21695 scroll->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21696 scroll->draw_begin = 0;
21697 scroll->draw_end = 0;
21698 style->scrollv = style->scrollh;
21701 button = &style->scrollh.inc_button;
21702 button->normal = nk_style_item_color(nk_rgb(40,40,40));
21703 button->hover = nk_style_item_color(nk_rgb(42,42,42));
21704 button->active = nk_style_item_color(nk_rgb(44,44,44));
21705 button->border_color = nk_rgb(65,65,65);
21706 button->text_background = nk_rgb(40,40,40);
21707 button->text_normal = nk_rgb(175,175,175);
21708 button->text_hover = nk_rgb(175,175,175);
21709 button->text_active = nk_rgb(175,175,175);
21710 button->padding =
nk_vec2(4.0f,4.0f);
21711 button->touch_padding =
nk_vec2(0.0f,0.0f);
21712 button->userdata = nk_handle_ptr(0);
21713 button->text_alignment = NK_TEXT_CENTERED;
21714 button->border = 1.0f;
21715 button->rounding = 0.0f;
21716 button->color_factor_text = 1.0f;
21717 button->color_factor_background = 1.0f;
21718 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21719 button->draw_begin = 0;
21720 button->draw_end = 0;
21721 style->scrollh.dec_button = style->scrollh.inc_button;
21722 style->scrollv.inc_button = style->scrollh.inc_button;
21723 style->scrollv.dec_button = style->scrollh.inc_button;
21726 edit = &style->edit;
21727 nk_zero_struct(*edit);
21728 edit->normal = nk_style_item_color(table[NK_COLOR_EDIT]);
21729 edit->hover = nk_style_item_color(table[NK_COLOR_EDIT]);
21730 edit->active = nk_style_item_color(table[NK_COLOR_EDIT]);
21731 edit->cursor_normal = table[NK_COLOR_TEXT];
21732 edit->cursor_hover = table[NK_COLOR_TEXT];
21733 edit->cursor_text_normal= table[NK_COLOR_EDIT];
21734 edit->cursor_text_hover = table[NK_COLOR_EDIT];
21735 edit->border_color = table[NK_COLOR_BORDER];
21736 edit->text_normal = table[NK_COLOR_TEXT];
21737 edit->text_hover = table[NK_COLOR_TEXT];
21738 edit->text_active = table[NK_COLOR_TEXT];
21739 edit->selected_normal = table[NK_COLOR_TEXT];
21740 edit->selected_hover = table[NK_COLOR_TEXT];
21741 edit->selected_text_normal = table[NK_COLOR_EDIT];
21742 edit->selected_text_hover = table[NK_COLOR_EDIT];
21743 edit->scrollbar_size =
nk_vec2(10,10);
21744 edit->scrollbar = style->scrollv;
21745 edit->padding =
nk_vec2(4,4);
21746 edit->row_padding = 2;
21747 edit->cursor_size = 4;
21749 edit->rounding = 0;
21750 edit->color_factor = 1.0f;
21751 edit->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21754 property = &style->property;
21755 nk_zero_struct(*property);
21756 property->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]);
21757 property->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]);
21758 property->active = nk_style_item_color(table[NK_COLOR_PROPERTY]);
21759 property->border_color = table[NK_COLOR_BORDER];
21760 property->label_normal = table[NK_COLOR_TEXT];
21761 property->label_hover = table[NK_COLOR_TEXT];
21762 property->label_active = table[NK_COLOR_TEXT];
21763 property->sym_left = NK_SYMBOL_TRIANGLE_LEFT;
21764 property->sym_right = NK_SYMBOL_TRIANGLE_RIGHT;
21765 property->userdata = nk_handle_ptr(0);
21766 property->padding =
nk_vec2(4,4);
21767 property->border = 1;
21768 property->rounding = 10;
21769 property->draw_begin = 0;
21770 property->draw_end = 0;
21771 property->color_factor = 1.0f;
21772 property->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21775 button = &style->property.dec_button;
21776 nk_zero_struct(*button);
21777 button->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]);
21778 button->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]);
21779 button->active = nk_style_item_color(table[NK_COLOR_PROPERTY]);
21780 button->border_color = nk_rgba(0,0,0,0);
21781 button->text_background = table[NK_COLOR_PROPERTY];
21782 button->text_normal = table[NK_COLOR_TEXT];
21783 button->text_hover = table[NK_COLOR_TEXT];
21784 button->text_active = table[NK_COLOR_TEXT];
21785 button->padding =
nk_vec2(0.0f,0.0f);
21786 button->touch_padding =
nk_vec2(0.0f,0.0f);
21787 button->userdata = nk_handle_ptr(0);
21788 button->text_alignment = NK_TEXT_CENTERED;
21789 button->border = 0.0f;
21790 button->rounding = 0.0f;
21791 button->color_factor_text = 1.0f;
21792 button->color_factor_background = 1.0f;
21793 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21794 button->draw_begin = 0;
21795 button->draw_end = 0;
21796 style->property.inc_button = style->property.dec_button;
21799 edit = &style->property.edit;
21800 nk_zero_struct(*edit);
21801 edit->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]);
21802 edit->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]);
21803 edit->active = nk_style_item_color(table[NK_COLOR_PROPERTY]);
21804 edit->border_color = nk_rgba(0,0,0,0);
21805 edit->cursor_normal = table[NK_COLOR_TEXT];
21806 edit->cursor_hover = table[NK_COLOR_TEXT];
21807 edit->cursor_text_normal= table[NK_COLOR_EDIT];
21808 edit->cursor_text_hover = table[NK_COLOR_EDIT];
21809 edit->text_normal = table[NK_COLOR_TEXT];
21810 edit->text_hover = table[NK_COLOR_TEXT];
21811 edit->text_active = table[NK_COLOR_TEXT];
21812 edit->selected_normal = table[NK_COLOR_TEXT];
21813 edit->selected_hover = table[NK_COLOR_TEXT];
21814 edit->selected_text_normal = table[NK_COLOR_EDIT];
21815 edit->selected_text_hover = table[NK_COLOR_EDIT];
21816 edit->padding =
nk_vec2(0,0);
21817 edit->cursor_size = 8;
21819 edit->rounding = 0;
21820 edit->color_factor = 1.0f;
21821 edit->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21824 chart = &style->chart;
21825 nk_zero_struct(*chart);
21826 chart->background = nk_style_item_color(table[NK_COLOR_CHART]);
21827 chart->border_color = table[NK_COLOR_BORDER];
21828 chart->selected_color = table[NK_COLOR_CHART_COLOR_HIGHLIGHT];
21829 chart->color = table[NK_COLOR_CHART_COLOR];
21830 chart->padding =
nk_vec2(4,4);
21832 chart->rounding = 0;
21833 chart->color_factor = 1.0f;
21834 chart->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21835 chart->show_markers = nk_true;
21838 combo = &style->combo;
21839 combo->normal = nk_style_item_color(table[NK_COLOR_COMBO]);
21840 combo->hover = nk_style_item_color(table[NK_COLOR_COMBO]);
21841 combo->active = nk_style_item_color(table[NK_COLOR_COMBO]);
21842 combo->border_color = table[NK_COLOR_BORDER];
21843 combo->label_normal = table[NK_COLOR_TEXT];
21844 combo->label_hover = table[NK_COLOR_TEXT];
21845 combo->label_active = table[NK_COLOR_TEXT];
21846 combo->sym_normal = NK_SYMBOL_TRIANGLE_DOWN;
21847 combo->sym_hover = NK_SYMBOL_TRIANGLE_DOWN;
21848 combo->sym_active = NK_SYMBOL_TRIANGLE_DOWN;
21849 combo->content_padding =
nk_vec2(4,4);
21850 combo->button_padding =
nk_vec2(0,4);
21851 combo->spacing =
nk_vec2(4,0);
21853 combo->rounding = 0;
21854 combo->color_factor = 1.0f;
21855 combo->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21858 button = &style->combo.button;
21859 nk_zero_struct(*button);
21860 button->normal = nk_style_item_color(table[NK_COLOR_COMBO]);
21861 button->hover = nk_style_item_color(table[NK_COLOR_COMBO]);
21862 button->active = nk_style_item_color(table[NK_COLOR_COMBO]);
21863 button->border_color = nk_rgba(0,0,0,0);
21864 button->text_background = table[NK_COLOR_COMBO];
21865 button->text_normal = table[NK_COLOR_TEXT];
21866 button->text_hover = table[NK_COLOR_TEXT];
21867 button->text_active = table[NK_COLOR_TEXT];
21868 button->padding =
nk_vec2(2.0f,2.0f);
21869 button->touch_padding =
nk_vec2(0.0f,0.0f);
21870 button->userdata = nk_handle_ptr(0);
21871 button->text_alignment = NK_TEXT_CENTERED;
21872 button->border = 0.0f;
21873 button->rounding = 0.0f;
21874 button->color_factor_text = 1.0f;
21875 button->color_factor_background = 1.0f;
21876 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21877 button->draw_begin = 0;
21878 button->draw_end = 0;
21882 tab->background = nk_style_item_color(table[NK_COLOR_TAB_HEADER]);
21883 tab->border_color = table[NK_COLOR_BORDER];
21884 tab->text = table[NK_COLOR_TEXT];
21885 tab->sym_minimize = NK_SYMBOL_TRIANGLE_RIGHT;
21886 tab->sym_maximize = NK_SYMBOL_TRIANGLE_DOWN;
21889 tab->indent = 10.0f;
21892 tab->color_factor = 1.0f;
21893 tab->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21896 button = &style->tab.tab_minimize_button;
21897 nk_zero_struct(*button);
21898 button->normal = nk_style_item_color(table[NK_COLOR_TAB_HEADER]);
21899 button->hover = nk_style_item_color(table[NK_COLOR_TAB_HEADER]);
21900 button->active = nk_style_item_color(table[NK_COLOR_TAB_HEADER]);
21901 button->border_color = nk_rgba(0,0,0,0);
21902 button->text_background = table[NK_COLOR_TAB_HEADER];
21903 button->text_normal = table[NK_COLOR_TEXT];
21904 button->text_hover = table[NK_COLOR_TEXT];
21905 button->text_active = table[NK_COLOR_TEXT];
21906 button->padding =
nk_vec2(2.0f,2.0f);
21907 button->touch_padding =
nk_vec2(0.0f,0.0f);
21908 button->userdata = nk_handle_ptr(0);
21909 button->text_alignment = NK_TEXT_CENTERED;
21910 button->border = 0.0f;
21911 button->rounding = 0.0f;
21912 button->color_factor_text = 1.0f;
21913 button->color_factor_background = 1.0f;
21914 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21915 button->draw_begin = 0;
21916 button->draw_end = 0;
21917 style->tab.tab_maximize_button =*button;
21920 button = &style->tab.node_minimize_button;
21921 nk_zero_struct(*button);
21922 button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]);
21923 button->hover = nk_style_item_color(table[NK_COLOR_WINDOW]);
21924 button->active = nk_style_item_color(table[NK_COLOR_WINDOW]);
21925 button->border_color = nk_rgba(0,0,0,0);
21926 button->text_background = table[NK_COLOR_TAB_HEADER];
21927 button->text_normal = table[NK_COLOR_TEXT];
21928 button->text_hover = table[NK_COLOR_TEXT];
21929 button->text_active = table[NK_COLOR_TEXT];
21930 button->padding =
nk_vec2(2.0f,2.0f);
21931 button->touch_padding =
nk_vec2(0.0f,0.0f);
21932 button->userdata = nk_handle_ptr(0);
21933 button->text_alignment = NK_TEXT_CENTERED;
21934 button->border = 0.0f;
21935 button->rounding = 0.0f;
21936 button->color_factor_text = 1.0f;
21937 button->color_factor_background = 1.0f;
21938 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21939 button->draw_begin = 0;
21940 button->draw_end = 0;
21941 style->tab.node_maximize_button =*button;
21944 win = &style->window;
21945 win->header.align = NK_HEADER_RIGHT;
21946 win->header.close_symbol = NK_SYMBOL_X;
21947 win->header.minimize_symbol = NK_SYMBOL_MINUS;
21948 win->header.maximize_symbol = NK_SYMBOL_PLUS;
21949 win->header.normal = nk_style_item_color(table[NK_COLOR_HEADER]);
21950 win->header.hover = nk_style_item_color(table[NK_COLOR_HEADER]);
21951 win->header.active = nk_style_item_color(table[NK_COLOR_HEADER]);
21952 win->header.label_normal = table[NK_COLOR_TEXT];
21953 win->header.label_hover = table[NK_COLOR_TEXT];
21954 win->header.label_active = table[NK_COLOR_TEXT];
21955 win->header.label_padding =
nk_vec2(4,4);
21956 win->header.padding =
nk_vec2(4,4);
21957 win->header.spacing =
nk_vec2(0,0);
21960 button = &style->window.header.close_button;
21961 nk_zero_struct(*button);
21962 button->normal = nk_style_item_color(table[NK_COLOR_HEADER]);
21963 button->hover = nk_style_item_color(table[NK_COLOR_HEADER]);
21964 button->active = nk_style_item_color(table[NK_COLOR_HEADER]);
21965 button->border_color = nk_rgba(0,0,0,0);
21966 button->text_background = table[NK_COLOR_HEADER];
21967 button->text_normal = table[NK_COLOR_TEXT];
21968 button->text_hover = table[NK_COLOR_TEXT];
21969 button->text_active = table[NK_COLOR_TEXT];
21970 button->padding =
nk_vec2(0.0f,0.0f);
21971 button->touch_padding =
nk_vec2(0.0f,0.0f);
21972 button->userdata = nk_handle_ptr(0);
21973 button->text_alignment = NK_TEXT_CENTERED;
21974 button->border = 0.0f;
21975 button->rounding = 0.0f;
21976 button->color_factor_text = 1.0f;
21977 button->color_factor_background = 1.0f;
21978 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
21979 button->draw_begin = 0;
21980 button->draw_end = 0;
21983 button = &style->window.header.minimize_button;
21984 nk_zero_struct(*button);
21985 button->normal = nk_style_item_color(table[NK_COLOR_HEADER]);
21986 button->hover = nk_style_item_color(table[NK_COLOR_HEADER]);
21987 button->active = nk_style_item_color(table[NK_COLOR_HEADER]);
21988 button->border_color = nk_rgba(0,0,0,0);
21989 button->text_background = table[NK_COLOR_HEADER];
21990 button->text_normal = table[NK_COLOR_TEXT];
21991 button->text_hover = table[NK_COLOR_TEXT];
21992 button->text_active = table[NK_COLOR_TEXT];
21993 button->padding =
nk_vec2(0.0f,0.0f);
21994 button->touch_padding =
nk_vec2(0.0f,0.0f);
21995 button->userdata = nk_handle_ptr(0);
21996 button->text_alignment = NK_TEXT_CENTERED;
21997 button->border = 0.0f;
21998 button->rounding = 0.0f;
21999 button->color_factor_text = 1.0f;
22000 button->color_factor_background = 1.0f;
22001 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
22002 button->draw_begin = 0;
22003 button->draw_end = 0;
22006 win->background = table[NK_COLOR_WINDOW];
22007 win->fixed_background = nk_style_item_color(table[NK_COLOR_WINDOW]);
22008 win->border_color = table[NK_COLOR_BORDER];
22009 win->popup_border_color = table[NK_COLOR_BORDER];
22010 win->combo_border_color = table[NK_COLOR_BORDER];
22011 win->contextual_border_color = table[NK_COLOR_BORDER];
22012 win->menu_border_color = table[NK_COLOR_BORDER];
22013 win->group_border_color = table[NK_COLOR_BORDER];
22014 win->tooltip_border_color = table[NK_COLOR_BORDER];
22015 win->scaler = nk_style_item_color(table[NK_COLOR_TEXT]);
22017 win->rounding = 0.0f;
22019 win->scrollbar_size =
nk_vec2(10,10);
22020 win->min_size =
nk_vec2(64,64);
22022 win->combo_border = 1.0f;
22023 win->contextual_border = 1.0f;
22024 win->menu_border = 1.0f;
22025 win->group_border = 1.0f;
22026 win->tooltip_border = 1.0f;
22027 win->popup_border = 1.0f;
22028 win->border = 2.0f;
22029 win->min_row_height_padding = 8;
22032 win->group_padding =
nk_vec2(4,4);
22033 win->popup_padding =
nk_vec2(4,4);
22034 win->combo_padding =
nk_vec2(4,4);
22035 win->contextual_padding =
nk_vec2(4,4);
22036 win->menu_padding =
nk_vec2(4,4);
22037 win->tooltip_padding =
nk_vec2(4,4);
22057 style = &ctx->style;
22058 style->font = font;
22059 ctx->stacks.fonts.head = 0;
22077 struct nk_config_stack_user_font *font_stack;
22078 struct nk_config_stack_user_font_element *element;
22081 if (!ctx)
return 0;
22083 font_stack = &ctx->stacks.fonts;
22084 NK_ASSERT(font_stack->head < (
int)NK_LEN(font_stack->elements));
22085 if (font_stack->head >= (
int)NK_LEN(font_stack->elements))
22088 element = &font_stack->elements[font_stack->head++];
22089 element->address = &ctx->style.font;
22090 element->old_value = ctx->style.font;
22091 ctx->style.font = font;
22107 struct nk_config_stack_user_font *font_stack;
22108 struct nk_config_stack_user_font_element *element;
22111 if (!ctx)
return 0;
22113 font_stack = &ctx->stacks.fonts;
22114 NK_ASSERT(font_stack->head > 0);
22115 if (font_stack->head < 1)
22118 element = &font_stack->elements[--font_stack->head];
22119 *element->address = element->old_value;
22122 #define NK_STYLE_PUSH_IMPLEMENATION(prefix, type, stack) \
22123 nk_style_push_##type(struct nk_context *ctx, prefix##_##type *address, prefix##_##type value)\
22125 struct nk_config_stack_##type * type_stack;\
22126 struct nk_config_stack_##type##_element *element;\
22128 if (!ctx) return 0;\
22129 type_stack = &ctx->stacks.stack;\
22130 NK_ASSERT(type_stack->head < (int)NK_LEN(type_stack->elements));\
22131 if (type_stack->head >= (int)NK_LEN(type_stack->elements))\
22133 element = &type_stack->elements[type_stack->head++];\
22134 element->address = address;\
22135 element->old_value = *address;\
22139 #define NK_STYLE_POP_IMPLEMENATION(type, stack) \
22140 nk_style_pop_##type(struct nk_context *ctx)\
22142 struct nk_config_stack_##type *type_stack;\
22143 struct nk_config_stack_##type##_element *element;\
22145 if (!ctx) return 0;\
22146 type_stack = &ctx->stacks.stack;\
22147 NK_ASSERT(type_stack->head > 0);\
22148 if (type_stack->head < 1)\
22150 element = &type_stack->elements[--type_stack->head];\
22151 *element->address = element->old_value;\
22166 NK_API nk_bool NK_STYLE_PUSH_IMPLEMENATION(
struct nk, style_item, style_items)
22167 NK_API nk_bool NK_STYLE_PUSH_IMPLEMENATION(nk,
float, floats)
22168 NK_API nk_bool NK_STYLE_PUSH_IMPLEMENATION(
struct nk, vec2, vectors)
22169 NK_API nk_bool NK_STYLE_PUSH_IMPLEMENATION(nk,flags, flags)
22170 NK_API nk_bool NK_STYLE_PUSH_IMPLEMENATION(
struct nk,color, colors)
22172 NK_API nk_bool NK_STYLE_POP_IMPLEMENATION(style_item, style_items)
22173 NK_API nk_bool NK_STYLE_POP_IMPLEMENATION(
float,floats)
22174 NK_API nk_bool NK_STYLE_POP_IMPLEMENATION(vec2, vectors)
22175 NK_API nk_bool NK_STYLE_POP_IMPLEMENATION(flags,flags)
22176 NK_API nk_bool NK_STYLE_POP_IMPLEMENATION(color,colors)
22179 nk_style_set_cursor(
struct nk_context *ctx,
enum nk_style_cursor c)
22183 if (!ctx)
return 0;
22184 style = &ctx->style;
22185 if (style->cursors[c]) {
22186 style->cursor_active = style->cursors[c];
22202 nk_style_show_cursor(
struct nk_context *ctx)
22204 ctx->style.cursor_visible = nk_true;
22217 nk_style_hide_cursor(
struct nk_context *ctx)
22219 ctx->style.cursor_visible = nk_false;
22233 nk_style_load_cursor(
struct nk_context *ctx,
enum nk_style_cursor cursor,
22239 style = &ctx->style;
22240 style->cursors[cursor] = c;
22260 style = &ctx->style;
22261 for (i = 0; i < NK_CURSOR_COUNT; ++i)
22262 style->cursors[i] = &cursors[i];
22263 style->cursor_visible = nk_true;
22290 nk_zero_struct(*ctx);
22291 nk_style_default(ctx);
22293 if (font) ctx->style.font = font;
22294 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
22295 nk_draw_list_init(&ctx->draw_list);
22298 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
22314 alloc.userdata.ptr = 0;
22315 alloc.alloc = nk_malloc;
22316 alloc.free = nk_mfree;
22317 return nk_init(ctx, &alloc, font);
22337 if (!memory)
return 0;
22338 nk_setup(ctx, font);
22339 nk_buffer_init_fixed(&ctx->memory, memory, size);
22340 ctx->use_pool = nk_false;
22360 if (!cmds || !pool)
return 0;
22362 nk_setup(ctx, font);
22363 ctx->memory = *cmds;
22364 if (pool->
type == NK_BUFFER_FIXED) {
22366 nk_pool_init_fixed(&ctx->pool, pool->
memory.ptr, pool->
memory.size);
22370 nk_pool_init(&ctx->pool, alloc, NK_POOL_DEFAULT_CAPACITY);
22372 ctx->use_pool = nk_true;
22391 if (!alloc)
return 0;
22392 nk_setup(ctx, font);
22393 nk_buffer_init(&ctx->memory, alloc, NK_DEFAULT_COMMAND_BUFFER_SIZE);
22394 nk_pool_init(&ctx->pool, alloc, NK_POOL_DEFAULT_CAPACITY);
22395 ctx->use_pool = nk_true;
22398 #ifdef NK_INCLUDE_COMMAND_USERDATA
22414 ctx->userdata = handle;
22416 ctx->current->buffer.userdata = handle;
22434 nk_buffer_free(&ctx->memory);
22436 nk_pool_free(&ctx->pool);
22438 nk_zero(&ctx->input,
sizeof(ctx->input));
22439 nk_zero(&ctx->style,
sizeof(ctx->style));
22440 nk_zero(&ctx->memory,
sizeof(ctx->memory));
22470 nk_buffer_clear(&ctx->memory);
22471 else nk_buffer_reset(&ctx->memory, NK_BUFFER_FRONT);
22474 ctx->memory.
calls = 0;
22475 ctx->last_widget_state = 0;
22476 ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_ARROW];
22485 iter->seq == ctx->seq) {
22492 iter == ctx->active) {
22493 ctx->active = iter->prev;
22494 ctx->end = iter->prev;
22501 if (iter->popup.win && iter->popup.win->seq != ctx->seq) {
22502 nk_free_window(ctx, iter->popup.win);
22503 iter->popup.win = 0;
22506 {
struct nk_table *n, *it = iter->tables;
22509 if (it->seq != ctx->seq) {
22510 nk_remove_table(iter, it);
22512 nk_free_table(ctx, it);
22513 if (it == iter->tables)
22520 nk_remove_window(ctx, iter);
22521 nk_free_window(ctx, iter);
22523 }
else iter = iter->next;
22543 if (!ctx || !buffer)
return;
22545 buffer->end = buffer->begin;
22546 buffer->last = buffer->begin;
22547 buffer->clip = nk_null_rect;
22565 nk_start_buffer(ctx, &win->buffer);
22584 if (!ctx || !win)
return;
22587 buf = &win->popup.buf;
22588 buf->begin = win->buffer.end;
22589 buf->end = win->buffer.end;
22590 buf->parent = win->buffer.last;
22591 buf->last = buf->begin;
22592 buf->active = nk_true;
22611 if (!ctx || !win)
return;
22613 buf = &win->popup.buf;
22614 buf->last = win->buffer.last;
22615 buf->end = win->buffer.end;
22633 if (!ctx || !buffer)
return;
22656 if (!ctx || !win)
return;
22657 nk_finish_buffer(ctx, &win->buffer);
22658 if (!win->popup.buf.active)
return;
22660 buf = &win->popup.buf;
22661 memory = ctx->memory.
memory.ptr;
22662 parent_last = nk_ptr_add(
struct nk_command, memory, buf->parent);
22663 parent_last->next = buf->end;
22680 nk_byte *buffer = 0;
22683 if (!ctx->style.cursor_active)
22684 ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_ARROW];
22685 if (ctx->style.cursor_active && !ctx->input.mouse.grabbed && ctx->style.cursor_visible) {
22687 const struct nk_cursor *cursor = ctx->style.cursor_active;
22688 nk_command_buffer_init(&ctx->
overlay, &ctx->memory, NK_CLIPPING_OFF);
22689 nk_start_buffer(ctx, &ctx->
overlay);
22691 mouse_bounds.x = ctx->input.mouse.pos.x - cursor->offset.x;
22692 mouse_bounds.y = ctx->input.mouse.pos.y - cursor->offset.y;
22693 mouse_bounds.w = cursor->size.x;
22694 mouse_bounds.h = cursor->size.y;
22697 nk_finish_buffer(ctx, &ctx->
overlay);
22701 buffer = (nk_byte*)ctx->memory.
memory.ptr;
22704 if (it->buffer.last == it->buffer.begin || (it->flags &
NK_WINDOW_HIDDEN)||
22705 it->seq != ctx->seq)
22708 cmd = nk_ptr_add(
struct nk_command, buffer, it->buffer.last);
22709 while (next && ((next->buffer.last == next->buffer.begin) ||
22713 if (next) cmd->next = next->buffer.begin;
22721 if (!it->popup.buf.active)
22724 buf = &it->popup.buf;
22725 cmd->next = buf->begin;
22726 cmd = nk_ptr_add(
struct nk_command, buffer, buf->last);
22727 buf->active = nk_false;
22733 cmd->next = ctx->
overlay.begin;
22734 else cmd->next = ctx->memory.
allocated;
22753 if (!ctx)
return 0;
22754 if (!ctx->count)
return 0;
22756 buffer = (nk_byte*)ctx->memory.
memory.ptr;
22759 ctx->
build = nk_true;
22762 while (iter && ((iter->buffer.begin == iter->buffer.end) ||
22765 if (!iter)
return 0;
22766 return nk_ptr_add_const(
struct nk_command, buffer, iter->buffer.begin);
22786 if (!ctx || !cmd || !ctx->count)
return 0;
22787 if (cmd->next >= ctx->memory.
allocated)
return 0;
22788 buffer = (nk_byte*)ctx->memory.
memory.ptr;
22789 next = nk_ptr_add_const(
struct nk_command, buffer, cmd->next);
22816 unsigned int capacity)
22818 NK_ASSERT(capacity >= 1);
22819 nk_zero(pool,
sizeof(*pool));
22820 pool->alloc = *alloc;
22821 pool->capacity = capacity;
22822 pool->type = NK_BUFFER_DYNAMIC;
22836 nk_pool_free(
struct nk_pool *pool)
22840 iter = pool->pages;
22841 if (pool->type == NK_BUFFER_FIXED)
return;
22843 struct nk_page *next = iter->next;
22844 pool->alloc.free(pool->alloc.userdata, iter);
22861 nk_pool_init_fixed(
struct nk_pool *pool,
void *memory, nk_size size)
22863 nk_zero(pool,
sizeof(*pool));
22864 NK_ASSERT(size >=
sizeof(
struct nk_page));
22865 if (size <
sizeof(
struct nk_page))
return;
22868 pool->pages = (
struct nk_page*)memory;
22869 pool->type = NK_BUFFER_FIXED;
22883 nk_pool_alloc(
struct nk_pool *pool)
22885 if (!pool->pages || pool->pages->size >= pool->capacity) {
22888 if (pool->type == NK_BUFFER_FIXED) {
22889 NK_ASSERT(pool->pages);
22890 if (!pool->pages)
return 0;
22891 NK_ASSERT(pool->pages->size < pool->capacity);
22894 nk_size size =
sizeof(
struct nk_page);
22896 page = (
struct nk_page*)pool->alloc.alloc(pool->alloc.userdata,0, size);
22897 page->next = pool->pages;
22898 pool->pages = page;
22901 }
return &pool->pages->win[pool->pages->size++];
22924 nk_create_page_element(
struct nk_context *ctx)
22927 if (ctx->freelist) {
22929 elem = ctx->freelist;
22930 ctx->freelist = elem->next;
22931 }
else if (ctx->use_pool) {
22933 elem = nk_pool_alloc(&ctx->pool);
22935 if (!elem)
return 0;
22940 elem = (
struct nk_page_element*)nk_buffer_alloc(&ctx->memory, NK_BUFFER_BACK, size, align);
22942 if (!elem)
return 0;
22944 nk_zero_struct(*elem);
22960 nk_link_page_element_into_freelist(
struct nk_context *ctx,
22964 if (!ctx->freelist) {
22965 ctx->freelist = elem;
22967 elem->next = ctx->freelist;
22968 ctx->freelist = elem;
22986 if (ctx->use_pool) {
22987 nk_link_page_element_into_freelist(ctx, elem);
22991 {
void *elem_end = (
void*)(elem + 1);
22992 void *buffer_end = (nk_byte*)ctx->memory.
memory.ptr + ctx->memory.
size;
22993 if (elem_end == buffer_end)
22995 else nk_link_page_element_into_freelist(ctx, elem);}
23021 elem = nk_create_page_element(ctx);
23022 if (!elem)
return 0;
23023 nk_zero_struct(*elem);
23024 return &elem->data.tbl;
23042 nk_free_page_element(ctx, pe);
23058 if (!win->tables) {
23063 win->table_count = 1;
23066 win->tables->prev = tbl;
23067 tbl->next = win->tables;
23071 win->table_count++;
23087 if (win->tables == tbl)
23088 win->tables = tbl->next;
23090 tbl->next->prev = tbl->prev;
23092 tbl->prev->next = tbl->next;
23109 nk_hash name, nk_uint value)
23113 if (!win || !ctx)
return 0;
23114 if (!win->tables || win->tables->size >= NK_VALUE_PAGE_CAPACITY) {
23115 struct nk_table *tbl = nk_create_table(ctx);
23117 if (!tbl)
return 0;
23118 nk_push_table(win, tbl);
23120 win->tables->seq = win->seq;
23121 win->tables->keys[win->tables->size] = name;
23122 win->tables->values[win->tables->size] = value;
23123 return &win->tables->values[win->tables->size++];
23137 nk_find_value(
const struct nk_window *win, nk_hash name)
23139 struct nk_table *iter = win->tables;
23141 unsigned int i = 0;
23142 unsigned int size = iter->size;
23143 for (i = 0; i < size; ++i) {
23144 if (iter->keys[i] == name) {
23145 iter->seq = win->seq;
23146 return &iter->values[i];
23148 } size = NK_VALUE_PAGE_CAPACITY;
23176 elem = nk_create_page_element(ctx);
23177 if (!elem)
return 0;
23178 nk_zero_struct(*elem);
23179 return &elem->data.pan;
23197 nk_free_page_element(ctx, pe);
23211 nk_panel_has_header(nk_flags flags,
const char *title)
23213 nk_bool active = 0;
23214 active = (flags & (NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE));
23215 active = active || (flags & NK_WINDOW_TITLE);
23231 nk_panel_get_padding(const struct
nk_style *style,
enum nk_panel_type type)
23235 case NK_PANEL_WINDOW:
return style->window.padding;
23236 case NK_PANEL_GROUP:
return style->window.group_padding;
23237 case NK_PANEL_POPUP:
return style->window.popup_padding;
23238 case NK_PANEL_CONTEXTUAL:
return style->window.contextual_padding;
23239 case NK_PANEL_COMBO:
return style->window.combo_padding;
23240 case NK_PANEL_MENU:
return style->window.menu_padding;
23241 case NK_PANEL_TOOLTIP:
return style->window.menu_padding;}
23255 nk_panel_get_border(
const struct nk_style *style, nk_flags flags,
23256 enum nk_panel_type type)
23258 if (flags & NK_WINDOW_BORDER) {
23261 case NK_PANEL_WINDOW:
return style->window.border;
23262 case NK_PANEL_GROUP:
return style->window.group_border;
23263 case NK_PANEL_POPUP:
return style->window.popup_border;
23264 case NK_PANEL_CONTEXTUAL:
return style->window.contextual_border;
23265 case NK_PANEL_COMBO:
return style->window.combo_border;
23266 case NK_PANEL_MENU:
return style->window.menu_border;
23267 case NK_PANEL_TOOLTIP:
return style->window.menu_border;
23282 nk_panel_get_border_color(const struct
nk_style *style,
enum nk_panel_type type)
23286 case NK_PANEL_WINDOW:
return style->window.border_color;
23287 case NK_PANEL_GROUP:
return style->window.group_border_color;
23288 case NK_PANEL_POPUP:
return style->window.popup_border_color;
23289 case NK_PANEL_CONTEXTUAL:
return style->window.contextual_border_color;
23290 case NK_PANEL_COMBO:
return style->window.combo_border_color;
23291 case NK_PANEL_MENU:
return style->window.menu_border_color;
23292 case NK_PANEL_TOOLTIP:
return style->window.menu_border_color;}
23305 nk_panel_is_sub(
enum nk_panel_type type)
23307 return ((
int)type & (
int)NK_PANEL_SET_SUB)?1:0;
23320 nk_panel_is_nonblock(
enum nk_panel_type type)
23322 return ((
int)type & (
int)NK_PANEL_SET_NONBLOCK)?1:0;
23337 nk_panel_begin(
struct nk_context *ctx,
const char *title,
enum nk_panel_type panel_type)
23346 struct nk_vec2 scrollbar_size;
23347 struct nk_vec2 panel_padding;
23350 NK_ASSERT(ctx->current);
23351 NK_ASSERT(ctx->current->layout);
23352 if (!ctx || !ctx->current || !ctx->current->layout)
return 0;
23353 nk_zero(ctx->current->layout,
sizeof(*ctx->current->layout));
23355 nk_zero(ctx->current->layout,
sizeof(
struct nk_panel));
23356 ctx->current->layout->type = panel_type;
23360 style = &ctx->style;
23361 font = style->font;
23362 win = ctx->current;
23363 layout = win->layout;
23364 out = &win->buffer;
23365 in = (win->flags & NK_WINDOW_NO_INPUT) ? 0: &ctx->input;
23366 #ifdef NK_INCLUDE_COMMAND_USERDATA
23367 win->buffer.userdata = ctx->userdata;
23370 scrollbar_size = style->window.scrollbar_size;
23371 panel_padding = nk_panel_get_padding(style, panel_type);
23374 if ((win->flags & NK_WINDOW_MOVABLE) && !(win->flags &
NK_WINDOW_ROM)) {
23375 nk_bool left_mouse_down;
23376 unsigned int left_mouse_clicked;
23377 int left_mouse_click_in_cursor;
23381 header.x = win->bounds.x;
23382 header.y = win->bounds.y;
23383 header.w = win->bounds.w;
23384 if (nk_panel_has_header(win->flags, title)) {
23385 header.h = font->
height + 2.0f * style->window.header.padding.y;
23386 header.h += 2.0f * style->window.header.label_padding.y;
23387 }
else header.h = panel_padding.y;
23390 left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
23391 left_mouse_clicked = in->mouse.buttons[NK_BUTTON_LEFT].clicked;
23392 left_mouse_click_in_cursor = nk_input_has_mouse_click_down_in_rect(in,
23393 NK_BUTTON_LEFT, header, nk_true);
23394 if (left_mouse_down && left_mouse_click_in_cursor && !left_mouse_clicked) {
23395 win->bounds.x = win->bounds.x + in->mouse.delta.x;
23396 win->bounds.y = win->bounds.y + in->mouse.delta.y;
23397 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x += in->mouse.delta.x;
23398 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y += in->mouse.delta.y;
23399 ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_MOVE];
23404 layout->type = panel_type;
23405 layout->flags = win->flags;
23406 layout->bounds = win->bounds;
23407 layout->bounds.x += panel_padding.x;
23408 layout->bounds.w -= 2*panel_padding.x;
23409 if (win->flags & NK_WINDOW_BORDER) {
23410 layout->border = nk_panel_get_border(style, win->flags, panel_type);
23411 layout->bounds = nk_shrink_rect(layout->bounds, layout->border);
23412 }
else layout->border = 0;
23413 layout->at_y = layout->bounds.y;
23414 layout->at_x = layout->bounds.x;
23416 layout->header_height = 0;
23417 layout->footer_height = 0;
23419 layout->row.index = 0;
23420 layout->row.columns = 0;
23421 layout->row.ratio = 0;
23422 layout->row.item_width = 0;
23423 layout->row.tree_depth = 0;
23424 layout->row.height = panel_padding.y;
23425 layout->has_scrolling = nk_true;
23426 if (!(win->flags & NK_WINDOW_NO_SCROLLBAR))
23427 layout->bounds.w -= scrollbar_size.x;
23428 if (!nk_panel_is_nonblock(panel_type)) {
23429 layout->footer_height = 0;
23430 if (!(win->flags & NK_WINDOW_NO_SCROLLBAR) || win->flags & NK_WINDOW_SCALABLE)
23431 layout->footer_height = scrollbar_size.y;
23432 layout->bounds.h -= layout->footer_height;
23436 if (nk_panel_has_header(win->flags, title))
23438 struct nk_text text;
23443 header.x = win->bounds.x;
23444 header.y = win->bounds.y;
23445 header.w = win->bounds.w;
23446 header.h = font->
height + 2.0f * style->window.header.padding.y;
23447 header.h += (2.0f * style->window.header.label_padding.y);
23450 layout->header_height = header.h;
23451 layout->bounds.y += header.h;
23452 layout->bounds.h -= header.h;
23453 layout->at_y += header.h;
23456 if (ctx->active == win) {
23457 background = &style->window.header.active;
23458 text.text = style->window.header.label_active;
23459 }
else if (nk_input_is_mouse_hovering_rect(&ctx->input, header)) {
23460 background = &style->window.header.hover;
23461 text.text = style->window.header.label_hover;
23463 background = &style->window.header.normal;
23464 text.text = style->window.header.label_normal;
23470 switch(background->type) {
23471 case NK_STYLE_ITEM_IMAGE:
23472 text.background = nk_rgba(0,0,0,0);
23473 nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
23475 case NK_STYLE_ITEM_NINE_SLICE:
23476 text.background = nk_rgba(0, 0, 0, 0);
23477 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_white);
23479 case NK_STYLE_ITEM_COLOR:
23480 text.background = background->data.color;
23487 button.y = header.y + style->window.header.padding.y;
23488 button.h = header.h - 2 * style->window.header.padding.y;
23489 button.w = button.h;
23490 if (win->flags & NK_WINDOW_CLOSABLE) {
23492 if (style->window.header.align == NK_HEADER_RIGHT) {
23493 button.x = (header.w + header.x) - (button.w + style->window.header.padding.x);
23494 header.w -= button.w + style->window.header.spacing.x + style->window.header.padding.x;
23496 button.x = header.x + style->window.header.padding.x;
23497 header.x += button.w + style->window.header.spacing.x + style->window.header.padding.x;
23500 if (nk_do_button_symbol(&ws, &win->buffer, button,
23501 style->window.header.close_symbol, NK_BUTTON_DEFAULT,
23502 &style->window.header.close_button, in, style->font) && !(win->flags &
NK_WINDOW_ROM))
23510 if (win->flags & NK_WINDOW_MINIMIZABLE) {
23512 if (style->window.header.align == NK_HEADER_RIGHT) {
23513 button.x = (header.w + header.x) - button.w;
23514 if (!(win->flags & NK_WINDOW_CLOSABLE)) {
23515 button.x -= style->window.header.padding.x;
23516 header.w -= style->window.header.padding.x;
23518 header.w -= button.w + style->window.header.spacing.x;
23520 button.x = header.x;
23521 header.x += button.w + style->window.header.spacing.x + style->window.header.padding.x;
23523 if (nk_do_button_symbol(&ws, &win->buffer, button, (layout->flags &
NK_WINDOW_MINIMIZED)?
23524 style->window.header.maximize_symbol: style->window.header.minimize_symbol,
23525 NK_BUTTON_DEFAULT, &style->window.header.minimize_button, in, style->font) && !(win->flags &
NK_WINDOW_ROM))
23532 int text_len = nk_strlen(title);
23533 struct nk_rect label = {0,0,0,0};
23534 float t = font->
width(font->userdata, font->
height, title, text_len);
23537 label.x = header.x + style->window.header.padding.x;
23538 label.x += style->window.header.label_padding.x;
23539 label.y = header.y + style->window.header.label_padding.y;
23540 label.h = font->
height + 2 * style->window.header.label_padding.y;
23541 label.w = t + 2 * style->window.header.spacing.x;
23542 label.w = NK_CLAMP(0, label.w, header.x + header.w - label.x);
23543 nk_widget_text(out, label, (
const char*)title, text_len, &text, NK_TEXT_LEFT, font);}
23549 body.x = win->bounds.x;
23550 body.w = win->bounds.w;
23551 body.y = (win->bounds.y + layout->header_height);
23552 body.h = (win->bounds.h - layout->header_height);
23554 switch(style->window.fixed_background.type) {
23555 case NK_STYLE_ITEM_IMAGE:
23556 nk_draw_image(out, body, &style->window.fixed_background.data.image, nk_white);
23558 case NK_STYLE_ITEM_NINE_SLICE:
23559 nk_draw_nine_slice(out, body, &style->window.fixed_background.data.slice, nk_white);
23561 case NK_STYLE_ITEM_COLOR:
23562 nk_fill_rect(out, body, style->window.rounding, style->window.fixed_background.data.color);
23569 layout->clip = layout->bounds;
23570 nk_unify(&clip, &win->buffer.clip, layout->clip.x, layout->clip.y,
23571 layout->clip.x + layout->clip.w, layout->clip.y + layout->clip.h);
23572 nk_push_scissor(out, clip);
23573 layout->clip = clip;}
23595 struct nk_vec2 scrollbar_size;
23596 struct nk_vec2 panel_padding;
23599 NK_ASSERT(ctx->current);
23600 NK_ASSERT(ctx->current->layout);
23601 if (!ctx || !ctx->current || !ctx->current->layout)
23604 window = ctx->current;
23605 layout = window->layout;
23606 style = &ctx->style;
23607 out = &window->buffer;
23608 in = (layout->flags &
NK_WINDOW_ROM || layout->flags & NK_WINDOW_NO_INPUT) ? 0 :&ctx->input;
23609 if (!nk_panel_is_sub(layout->type))
23610 nk_push_scissor(out, nk_null_rect);
23613 scrollbar_size = style->window.scrollbar_size;
23614 panel_padding = nk_panel_get_padding(style, layout->type);
23617 layout->at_y += layout->row.height;
23624 if (layout->at_y < (layout->bounds.y + layout->bounds.h))
23625 layout->bounds.h = layout->at_y - layout->bounds.y;
23628 empty_space.x = window->bounds.x;
23629 empty_space.y = layout->bounds.y;
23630 empty_space.h = panel_padding.y;
23631 empty_space.w = window->bounds.w;
23632 nk_fill_rect(out, empty_space, 0, style->window.background);
23635 empty_space.x = window->bounds.x;
23636 empty_space.y = layout->bounds.y;
23637 empty_space.w = panel_padding.x + layout->border;
23638 empty_space.h = layout->bounds.h;
23639 nk_fill_rect(out, empty_space, 0, style->window.background);
23642 empty_space.x = layout->bounds.x + layout->bounds.w;
23643 empty_space.y = layout->bounds.y;
23644 empty_space.w = panel_padding.x + layout->border;
23645 empty_space.h = layout->bounds.h;
23646 if (*layout->offset_y == 0 && !(layout->flags & NK_WINDOW_NO_SCROLLBAR))
23647 empty_space.w += scrollbar_size.x;
23648 nk_fill_rect(out, empty_space, 0, style->window.background);
23651 if (layout->footer_height > 0) {
23652 empty_space.x = window->bounds.x;
23653 empty_space.y = layout->bounds.y + layout->bounds.h;
23654 empty_space.w = window->bounds.w;
23655 empty_space.h = layout->footer_height;
23656 nk_fill_rect(out, empty_space, 0, style->window.background);
23661 if (!(layout->flags & NK_WINDOW_NO_SCROLLBAR) &&
23663 window->scrollbar_hiding_timer < NK_SCROLLBAR_HIDING_TIMEOUT)
23666 int scroll_has_scrolling;
23667 float scroll_target;
23668 float scroll_offset;
23673 if (nk_panel_is_sub(layout->type))
23676 struct nk_window *root_window = window;
23677 struct nk_panel *root_panel = window->layout;
23678 while (root_panel->parent)
23679 root_panel = root_panel->parent;
23680 while (root_window->parent)
23681 root_window = root_window->parent;
23684 scroll_has_scrolling = 0;
23685 if ((root_window == ctx->active) && layout->has_scrolling) {
23687 if (nk_input_is_mouse_hovering_rect(in, layout->bounds) &&
23688 NK_INTERSECT(layout->bounds.x, layout->bounds.y, layout->bounds.w, layout->bounds.h,
23689 root_panel->clip.x, root_panel->clip.y, root_panel->clip.w, root_panel->clip.h))
23692 root_panel = window->layout;
23693 while (root_panel->parent) {
23694 root_panel->has_scrolling = nk_false;
23695 root_panel = root_panel->parent;
23697 root_panel->has_scrolling = nk_false;
23698 scroll_has_scrolling = nk_true;
23701 }
else if (!nk_panel_is_sub(layout->type)) {
23703 scroll_has_scrolling = (window == ctx->active) && layout->has_scrolling;
23704 if (in && (in->mouse.scroll_delta.y > 0 || in->mouse.scroll_delta.x > 0) && scroll_has_scrolling)
23705 window->scrolled = nk_true;
23706 else window->scrolled = nk_false;
23707 }
else scroll_has_scrolling = nk_false;
23711 nk_flags state = 0;
23712 scroll.x = layout->bounds.x + layout->bounds.w + panel_padding.x;
23713 scroll.y = layout->bounds.y;
23714 scroll.w = scrollbar_size.x;
23715 scroll.h = layout->bounds.h;
23717 scroll_offset = (float)*layout->offset_y;
23718 scroll_step = scroll.h * 0.10f;
23719 scroll_inc = scroll.h * 0.01f;
23720 scroll_target = (
float)(int)(layout->at_y - scroll.y);
23721 scroll_offset = nk_do_scrollbarv(&state, out, scroll, scroll_has_scrolling,
23722 scroll_offset, scroll_target, scroll_step, scroll_inc,
23723 &ctx->style.scrollv, in, style->font);
23724 *layout->offset_y = (nk_uint)scroll_offset;
23725 if (in && scroll_has_scrolling)
23726 in->mouse.scroll_delta.y = 0;
23730 nk_flags state = 0;
23731 scroll.x = layout->bounds.x;
23732 scroll.y = layout->bounds.y + layout->bounds.h;
23733 scroll.w = layout->bounds.w;
23734 scroll.h = scrollbar_size.y;
23736 scroll_offset = (float)*layout->offset_x;
23737 scroll_target = (
float)(int)(layout->max_x - scroll.x);
23738 scroll_step = layout->max_x * 0.05f;
23739 scroll_inc = layout->max_x * 0.005f;
23740 scroll_offset = nk_do_scrollbarh(&state, out, scroll, scroll_has_scrolling,
23741 scroll_offset, scroll_target, scroll_step, scroll_inc,
23742 &ctx->style.scrollh, in, style->font);
23743 *layout->offset_x = (nk_uint)scroll_offset;
23748 if (window->flags & NK_WINDOW_SCROLL_AUTO_HIDE) {
23749 int has_input = ctx->input.mouse.delta.x != 0 || ctx->input.mouse.delta.y != 0 || ctx->input.mouse.scroll_delta.y != 0;
23751 int any_item_active = (ctx->last_widget_state & NK_WIDGET_STATE_MODIFIED);
23752 if ((!has_input && is_window_hovered) || (!is_window_hovered && !any_item_active))
23753 window->scrollbar_hiding_timer += ctx->delta_time_seconds;
23754 else window->scrollbar_hiding_timer = 0;
23755 }
else window->scrollbar_hiding_timer = 0;
23758 if (layout->flags & NK_WINDOW_BORDER)
23760 struct nk_color border_color = nk_panel_get_border_color(style, layout->type);
23762 ? (style->window.border + window->bounds.y + layout->header_height)
23764 ? (layout->bounds.y + layout->bounds.h + layout->footer_height)
23765 : (window->bounds.y + window->bounds.h));
23766 struct nk_rect b = window->bounds;
23767 b.h = padding_y - window->bounds.y;
23768 nk_stroke_rect(out, b, style->window.rounding, layout->border, border_color);
23772 if ((layout->flags & NK_WINDOW_SCALABLE) && in && !(layout->flags &
NK_WINDOW_MINIMIZED))
23776 scaler.w = scrollbar_size.x;
23777 scaler.h = scrollbar_size.y;
23778 scaler.y = layout->bounds.y + layout->bounds.h;
23779 if (layout->flags & NK_WINDOW_SCALE_LEFT)
23780 scaler.x = layout->bounds.x - panel_padding.x * 0.5f;
23781 else scaler.x = layout->bounds.x + layout->bounds.w + panel_padding.x;
23782 if (layout->flags & NK_WINDOW_NO_SCROLLBAR)
23783 scaler.x -= scaler.w;
23787 if (item->type == NK_STYLE_ITEM_IMAGE)
23790 if (layout->flags & NK_WINDOW_SCALE_LEFT) {
23791 nk_fill_triangle(out, scaler.x, scaler.y, scaler.x,
23792 scaler.y + scaler.h, scaler.x + scaler.w,
23793 scaler.y + scaler.h, item->data.color);
23795 nk_fill_triangle(out, scaler.x + scaler.w, scaler.y, scaler.x + scaler.w,
23796 scaler.y + scaler.h, scaler.x, scaler.y + scaler.h, item->data.color);
23802 struct nk_vec2 window_size = style->window.min_size;
23803 int left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
23804 int left_mouse_click_in_scaler = nk_input_has_mouse_click_down_in_rect(in,
23805 NK_BUTTON_LEFT, scaler, nk_true);
23807 if (left_mouse_down && left_mouse_click_in_scaler) {
23808 float delta_x = in->mouse.delta.x;
23809 if (layout->flags & NK_WINDOW_SCALE_LEFT) {
23810 delta_x = -delta_x;
23811 window->bounds.x += in->mouse.delta.x;
23814 if (window->bounds.w + delta_x >= window_size.x) {
23815 if ((delta_x < 0) || (delta_x > 0 && in->mouse.pos.x >= scaler.x)) {
23816 window->bounds.w = window->bounds.w + delta_x;
23817 scaler.x += in->mouse.delta.x;
23822 if (window_size.y < window->bounds.h + in->mouse.delta.y) {
23823 if ((in->mouse.delta.y < 0) || (in->mouse.delta.y > 0 && in->mouse.pos.y >= scaler.y)) {
23824 window->bounds.h = window->bounds.h + in->mouse.delta.y;
23825 scaler.y += in->mouse.delta.y;
23829 ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_RESIZE_TOP_RIGHT_DOWN_LEFT];
23830 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = scaler.x + scaler.w/2.0f;
23831 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y = scaler.y + scaler.h/2.0f;
23835 if (!nk_panel_is_sub(layout->type)) {
23838 nk_command_buffer_reset(&window->buffer);
23840 else nk_finish(ctx, window);
23848 window->flags = layout->flags;
23851 if (window->property.active && window->property.old != window->property.seq &&
23852 window->property.active == window->property.prev) {
23853 nk_zero(&window->property,
sizeof(window->property));
23855 window->property.old = window->property.seq;
23856 window->property.prev = window->property.active;
23857 window->property.seq = 0;
23860 if (window->edit.active && window->edit.old != window->edit.seq &&
23861 window->edit.active == window->edit.prev) {
23862 nk_zero(&window->edit,
sizeof(window->edit));
23864 window->edit.old = window->edit.seq;
23865 window->edit.prev = window->edit.active;
23866 window->edit.seq = 0;
23869 if (window->popup.active_con && window->popup.con_old != window->popup.con_count) {
23870 window->popup.con_count = 0;
23871 window->popup.con_old = 0;
23872 window->popup.active_con = 0;
23874 window->popup.con_old = window->popup.con_count;
23875 window->popup.con_count = 0;
23877 window->popup.combo_count = 0;
23879 NK_ASSERT(!layout->row.tree_depth);
23905 elem = nk_create_page_element(ctx);
23906 if (!elem)
return 0;
23907 elem->data.win.seq = ctx->seq;
23908 return &elem->data.win;
23925 struct nk_table *it = win->tables;
23926 if (win->popup.win) {
23927 nk_free_window(ctx, win->popup.win);
23928 win->popup.win = 0;
23936 nk_remove_table(win, it);
23937 nk_free_table(ctx, it);
23938 if (it == win->tables)
23946 nk_free_page_element(ctx, pe);}
23961 nk_find_window(
const struct nk_context *ctx, nk_hash hash,
const char *name)
23966 NK_ASSERT(iter != iter->next);
23967 if (iter->name == hash) {
23968 int max_len = nk_strlen(iter->name_string);
23969 if (!nk_stricmpn(iter->name_string, name, max_len))
23989 enum nk_window_insert_location loc)
23994 if (!win || !ctx)
return;
23998 NK_ASSERT(iter != iter->next);
23999 NK_ASSERT(iter != win);
24000 if (iter == win)
return;
24012 if (loc == NK_INSERT_BACK) {
24017 win->prev = ctx->end;
24020 ctx->active = ctx->end;
24024 ctx->begin->prev = win;
24025 win->next = ctx->begin;
24046 if (win == ctx->begin || win == ctx->end) {
24047 if (win == ctx->begin) {
24048 ctx->begin = win->next;
24050 win->next->prev = 0;
24052 if (win == ctx->end) {
24053 ctx->end = win->prev;
24055 win->prev->next = 0;
24059 win->next->prev = win->prev;
24061 win->prev->next = win->next;
24063 if (win == ctx->active || !ctx->active) {
24064 ctx->active = ctx->end;
24085 struct nk_rect bounds, nk_flags flags)
24103 struct nk_rect bounds, nk_flags flags)
24114 NK_ASSERT(ctx->style.font && ctx->style.font->
width &&
"if this triggers you forgot to add a font");
24115 NK_ASSERT(!ctx->current &&
"if this triggers you missed a `nk_end` call");
24116 if (!ctx || ctx->current || !title || !name)
24120 style = &ctx->style;
24121 name_len = (int)nk_strlen(name);
24122 name_hash = nk_murmur_hash(name, (
int)name_len, NK_WINDOW_TITLE);
24123 win = nk_find_window(ctx, name_hash, name);
24126 nk_size name_length = (nk_size)name_len;
24127 win = (
struct nk_window*)nk_create_window(ctx);
24129 if (!win)
return 0;
24131 if (flags & NK_WINDOW_BACKGROUND)
24132 nk_insert_window(ctx, win, NK_INSERT_FRONT);
24133 else nk_insert_window(ctx, win, NK_INSERT_BACK);
24134 nk_command_buffer_init(&win->buffer, &ctx->memory, NK_CLIPPING_ON);
24136 win->flags = flags;
24137 win->bounds = bounds;
24138 win->name = name_hash;
24139 name_length = NK_MIN(name_length, NK_WINDOW_MAX_NAME-1);
24140 NK_MEMCPY(win->name_string, name, name_length);
24141 win->name_string[name_length] = 0;
24142 win->popup.win = 0;
24143 win->widgets_disabled = nk_false;
24148 win->flags &= ~(nk_flags)(NK_WINDOW_PRIVATE-1);
24149 win->flags |= flags;
24150 if (!(win->flags & (NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE)))
24151 win->bounds = bounds;
24159 NK_ASSERT(win->seq != ctx->seq);
24160 win->seq = ctx->seq;
24167 ctx->current = win;
24170 }
else nk_start(ctx, win);
24173 if (!(win->flags &
NK_WINDOW_HIDDEN) && !(win->flags & NK_WINDOW_NO_INPUT))
24175 int inpanel, ishovered;
24177 float h = ctx->style.font->
height + 2.0f * style->window.header.padding.y +
24178 (2.0f * style->window.header.label_padding.y);
24180 win->bounds:
nk_rect(win->bounds.x, win->bounds.y, win->bounds.w, h);
24183 inpanel = nk_input_has_mouse_click_down_in_rect(&ctx->input, NK_BUTTON_LEFT, win_bounds, nk_true);
24184 inpanel = inpanel && ctx->input.mouse.buttons[NK_BUTTON_LEFT].clicked;
24185 ishovered = nk_input_is_mouse_hovering_rect(&ctx->input, win_bounds);
24186 if ((win != ctx->active) && ishovered && !ctx->input.mouse.buttons[NK_BUTTON_LEFT].down) {
24190 iter->bounds:
nk_rect(iter->bounds.x, iter->bounds.y, iter->bounds.w, h);
24191 if (NK_INTERSECT(win_bounds.x, win_bounds.y, win_bounds.w, win_bounds.h,
24192 iter_bounds.x, iter_bounds.y, iter_bounds.w, iter_bounds.h) &&
24196 if (iter->popup.win && iter->popup.active && !(iter->flags &
NK_WINDOW_HIDDEN) &&
24197 NK_INTERSECT(win->bounds.x, win_bounds.y, win_bounds.w, win_bounds.h,
24198 iter->popup.win->bounds.x, iter->popup.win->bounds.y,
24199 iter->popup.win->bounds.w, iter->popup.win->bounds.h))
24206 if (iter && inpanel && (win != ctx->end)) {
24211 iter->bounds:
nk_rect(iter->bounds.x, iter->bounds.y, iter->bounds.w, h);
24212 if (NK_INBOX(ctx->input.mouse.pos.x, ctx->input.mouse.pos.y,
24213 iter_bounds.x, iter_bounds.y, iter_bounds.w, iter_bounds.h) &&
24216 if (iter->popup.win && iter->popup.active && !(iter->flags &
NK_WINDOW_HIDDEN) &&
24217 NK_INTERSECT(win_bounds.x, win_bounds.y, win_bounds.w, win_bounds.h,
24218 iter->popup.win->bounds.x, iter->popup.win->bounds.y,
24219 iter->popup.win->bounds.w, iter->popup.win->bounds.h))
24224 if (iter && !(win->flags &
NK_WINDOW_ROM) && (win->flags & NK_WINDOW_BACKGROUND)) {
24227 ctx->active = iter;
24228 if (!(iter->flags & NK_WINDOW_BACKGROUND)) {
24231 nk_remove_window(ctx, iter);
24232 nk_insert_window(ctx, iter, NK_INSERT_BACK);
24235 if (!iter && ctx->end != win) {
24236 if (!(win->flags & NK_WINDOW_BACKGROUND)) {
24239 nk_remove_window(ctx, win);
24240 nk_insert_window(ctx, win, NK_INSERT_BACK);
24245 if (ctx->end != win && !(win->flags & NK_WINDOW_BACKGROUND))
24249 win->layout = (
struct nk_panel*)nk_create_panel(ctx);
24250 ctx->current = win;
24251 ret = nk_panel_begin(ctx, title, NK_PANEL_WINDOW);
24252 win->layout->offset_x = &win->scrollbar.x;
24253 win->layout->offset_y = &win->scrollbar.y;
24271 NK_ASSERT(ctx->current &&
"if this triggers you forgot to call `nk_begin`");
24272 if (!ctx || !ctx->current)
24275 layout = ctx->current->layout;
24276 if (!layout || (layout->type == NK_PANEL_WINDOW && (ctx->current->flags &
NK_WINDOW_HIDDEN))) {
24281 nk_free_panel(ctx, ctx->current->layout);
24298 NK_ASSERT(ctx->current);
24299 if (!ctx || !ctx->current)
return nk_rect(0,0,0,0);
24300 return ctx->current->bounds;
24316 NK_ASSERT(ctx->current);
24317 if (!ctx || !ctx->current)
return nk_vec2(0,0);
24318 return nk_vec2(ctx->current->bounds.x, ctx->current->bounds.y);
24334 NK_ASSERT(ctx->current);
24335 if (!ctx || !ctx->current)
return nk_vec2(0,0);
24336 return nk_vec2(ctx->current->bounds.w, ctx->current->bounds.h);
24352 NK_ASSERT(ctx->current);
24353 if (!ctx || !ctx->current)
return 0;
24354 return ctx->current->bounds.w;
24370 NK_ASSERT(ctx->current);
24371 if (!ctx || !ctx->current)
return 0;
24372 return ctx->current->bounds.h;
24388 NK_ASSERT(ctx->current);
24389 if (!ctx || !ctx->current)
return nk_rect(0,0,0,0);
24390 return ctx->current->layout->clip;
24406 NK_ASSERT(ctx->current);
24407 NK_ASSERT(ctx->current->layout);
24408 if (!ctx || !ctx->current)
return nk_vec2(0,0);
24409 return nk_vec2(ctx->current->layout->clip.x, ctx->current->layout->clip.y);
24425 NK_ASSERT(ctx->current);
24426 NK_ASSERT(ctx->current->layout);
24427 if (!ctx || !ctx->current)
return nk_vec2(0,0);
24428 return nk_vec2(ctx->current->layout->clip.x + ctx->current->layout->clip.w,
24429 ctx->current->layout->clip.y + ctx->current->layout->clip.h);
24445 NK_ASSERT(ctx->current);
24446 NK_ASSERT(ctx->current->layout);
24447 if (!ctx || !ctx->current)
return nk_vec2(0,0);
24448 return nk_vec2(ctx->current->layout->clip.w, ctx->current->layout->clip.h);
24464 NK_ASSERT(ctx->current);
24465 NK_ASSERT(ctx->current->layout);
24466 if (!ctx || !ctx->current)
return 0;
24467 return &ctx->current->buffer;
24483 NK_ASSERT(ctx->current);
24484 if (!ctx || !ctx->current)
return 0;
24485 return ctx->current->layout;
24504 NK_ASSERT(ctx->current);
24505 if (!ctx || !ctx->current)
24507 win = ctx->current;
24509 *offset_x = win->scrollbar.x;
24511 *offset_y = win->scrollbar.y;
24527 NK_ASSERT(ctx->current);
24528 NK_ASSERT(ctx->current->layout);
24529 if (!ctx || !ctx->current)
return 0;
24530 return ctx->current == ctx->active;
24546 NK_ASSERT(ctx->current);
24550 struct nk_rect actual_bounds = ctx->current->bounds;
24552 actual_bounds.h = ctx->current->layout->header_height;
24554 return nk_input_is_mouse_hovering_rect(&ctx->input, actual_bounds);
24572 if (!ctx)
return 0;
24578 if (iter->popup.active && iter->popup.win && nk_input_is_mouse_hovering_rect(&ctx->input, iter->popup.win->bounds))
24582 struct nk_rect header = iter->bounds;
24583 header.h = ctx->style.font->
height + 2 * ctx->style.window.header.padding.y;
24584 if (nk_input_is_mouse_hovering_rect(&ctx->input, header))
24586 }
else if (nk_input_is_mouse_hovering_rect(&ctx->input, iter->bounds)) {
24608 int any_active = (ctx->last_widget_state & NK_WIDGET_STATE_MODIFIED);
24609 return any_hovered || any_active;
24626 nk_hash title_hash;
24629 if (!ctx)
return 0;
24631 title_len = (int)nk_strlen(name);
24632 title_hash = nk_murmur_hash(name, (
int)title_len, NK_WINDOW_TITLE);
24633 win = nk_find_window(ctx, title_hash, name);
24634 if (!win)
return 0;
24652 nk_hash title_hash;
24655 if (!ctx)
return 1;
24657 title_len = (int)nk_strlen(name);
24658 title_hash = nk_murmur_hash(name, (
int)title_len, NK_WINDOW_TITLE);
24659 win = nk_find_window(ctx, title_hash, name);
24660 if (!win)
return 1;
24678 nk_hash title_hash;
24681 if (!ctx)
return 1;
24683 title_len = (int)nk_strlen(name);
24684 title_hash = nk_murmur_hash(name, (
int)title_len, NK_WINDOW_TITLE);
24685 win = nk_find_window(ctx, title_hash, name);
24686 if (!win)
return 1;
24704 nk_hash title_hash;
24707 if (!ctx)
return 0;
24709 title_len = (int)nk_strlen(name);
24710 title_hash = nk_murmur_hash(name, (
int)title_len, NK_WINDOW_TITLE);
24711 win = nk_find_window(ctx, title_hash, name);
24712 if (!win)
return 0;
24713 return win == ctx->active;
24730 nk_hash title_hash;
24731 title_len = (int)nk_strlen(name);
24732 title_hash = nk_murmur_hash(name, (
int)title_len, NK_WINDOW_TITLE);
24733 return nk_find_window(ctx, title_hash, name);
24754 NK_ASSERT(ctx->current != win &&
"You cannot close a currently active window");
24755 if (ctx->current == win)
return;
24771 const char *name,
struct nk_rect bounds)
24778 win->bounds = bounds;
24792 const char *name,
struct nk_vec2 pos)
24796 win->bounds.x = pos.x;
24797 win->bounds.y = pos.y;
24811 const char *name,
struct nk_vec2 size)
24815 win->bounds.w = size.x;
24816 win->bounds.h = size.y;
24834 NK_ASSERT(ctx->current);
24835 if (!ctx || !ctx->current)
24837 win = ctx->current;
24838 win->scrollbar.x = offset_x;
24839 win->scrollbar.y = offset_y;
24854 enum nk_collapse_states c)
24857 nk_hash title_hash;
24862 title_len = (int)nk_strlen(name);
24863 title_hash = nk_murmur_hash(name, (
int)title_len, NK_WINDOW_TITLE);
24864 win = nk_find_window(ctx, title_hash, name);
24866 if (c == NK_MINIMIZED)
24883 enum nk_collapse_states c,
int cond)
24886 if (!ctx || !cond)
return;
24905 nk_hash title_hash;
24910 title_len = (int)nk_strlen(name);
24911 title_hash = nk_murmur_hash(name, (
int)title_len, NK_WINDOW_TITLE);
24912 win = nk_find_window(ctx, title_hash, name);
24914 if (s == NK_HIDDEN) {
24931 enum nk_show_states s,
int cond)
24934 if (!ctx || !cond)
return;
24953 nk_hash title_hash;
24958 title_len = (int)nk_strlen(name);
24959 title_hash = nk_murmur_hash(name, (
int)title_len, NK_WINDOW_TITLE);
24960 win = nk_find_window(ctx, title_hash, name);
24961 if (win && ctx->end != win) {
24962 nk_remove_window(ctx, win);
24963 nk_insert_window(ctx, win, NK_INSERT_BACK);
24985 if (!state)
return;
24986 nk_fill_rect(canvas, space, rounding && space.h > 1.5f ? space.h / 2.0f : 0, color);
25009 nk_popup_begin(
struct nk_context *ctx,
enum nk_popup_type type,
25010 const char *title, nk_flags flags,
struct nk_rect rect)
25017 nk_hash title_hash;
25022 NK_ASSERT(ctx->current);
25023 NK_ASSERT(ctx->current->layout);
25024 if (!ctx || !ctx->current || !ctx->current->layout)
25027 win = ctx->current;
25028 panel = win->layout;
25029 NK_ASSERT(!((
int)panel->type & (
int)NK_PANEL_SET_POPUP) &&
"popups are not allowed to have popups");
25031 title_len = (int)nk_strlen(title);
25032 title_hash = nk_murmur_hash(title, (
int)title_len, NK_PANEL_POPUP);
25034 popup = win->popup.win;
25036 popup = (
struct nk_window*)nk_create_window(ctx);
25037 popup->parent = win;
25038 win->popup.win = popup;
25039 win->popup.active = 0;
25040 win->popup.type = NK_PANEL_POPUP;
25044 if (win->popup.name != title_hash) {
25045 if (!win->popup.active) {
25046 nk_zero(popup,
sizeof(*popup));
25047 win->popup.name = title_hash;
25048 win->popup.active = 1;
25049 win->popup.type = NK_PANEL_POPUP;
25054 ctx->current = popup;
25055 rect.x += win->layout->clip.x;
25056 rect.y += win->layout->clip.y;
25059 popup->parent = win;
25060 popup->bounds = rect;
25061 popup->seq = ctx->seq;
25062 popup->layout = (
struct nk_panel*)nk_create_panel(ctx);
25063 popup->flags = flags;
25064 popup->flags |= NK_WINDOW_BORDER;
25065 if (type == NK_POPUP_DYNAMIC)
25068 popup->buffer = win->buffer;
25069 nk_start_popup(ctx, win);
25071 nk_push_scissor(&popup->buffer, nk_null_rect);
25073 if (nk_panel_begin(ctx, title, NK_PANEL_POPUP)) {
25076 root = win->layout;
25080 root = root->parent;
25082 win->popup.active = 1;
25083 popup->layout->offset_x = &popup->scrollbar.x;
25084 popup->layout->offset_y = &popup->scrollbar.y;
25085 popup->layout->parent = win->layout;
25090 root = win->layout;
25093 root = root->parent;
25095 win->popup.buf.active = 0;
25096 win->popup.active = 0;
25098 ctx->current = win;
25099 nk_free_panel(ctx, popup->layout);
25117 enum nk_panel_type panel_type)
25122 int is_active = nk_true;
25125 NK_ASSERT(ctx->current);
25126 NK_ASSERT(ctx->current->layout);
25127 if (!ctx || !ctx->current || !ctx->current->layout)
25131 win = ctx->current;
25132 panel = win->layout;
25133 NK_ASSERT(!((
int)panel->type & (
int)NK_PANEL_SET_POPUP));
25135 popup = win->popup.win;
25138 popup = (
struct nk_window*)nk_create_window(ctx);
25139 popup->parent = win;
25140 win->popup.win = popup;
25141 win->popup.type = panel_type;
25142 nk_command_buffer_init(&popup->buffer, &ctx->memory, NK_CLIPPING_ON);
25145 int pressed, in_body, in_header;
25146 #ifdef NK_BUTTON_TRIGGER_ON_RELEASE
25147 pressed = nk_input_is_mouse_released(&ctx->input, NK_BUTTON_LEFT);
25149 pressed = nk_input_is_mouse_pressed(&ctx->input, NK_BUTTON_LEFT);
25151 in_body = nk_input_is_mouse_hovering_rect(&ctx->input, body);
25152 in_header = nk_input_is_mouse_hovering_rect(&ctx->input, header);
25153 if (pressed && (!in_body || in_header))
25154 is_active = nk_false;
25156 win->popup.header = header;
25160 struct nk_panel *root = win->layout;
25163 root = root->parent;
25167 popup->bounds = body;
25168 popup->parent = win;
25169 popup->layout = (
struct nk_panel*)nk_create_panel(ctx);
25170 popup->flags = flags;
25171 popup->flags |= NK_WINDOW_BORDER;
25173 popup->seq = ctx->seq;
25174 win->popup.active = 1;
25175 NK_ASSERT(popup->layout);
25177 nk_start_popup(ctx, win);
25178 popup->buffer = win->buffer;
25179 nk_push_scissor(&popup->buffer, nk_null_rect);
25180 ctx->current = popup;
25182 nk_panel_begin(ctx, 0, panel_type);
25183 win->buffer = popup->buffer;
25184 popup->layout->parent = win->layout;
25185 popup->layout->offset_x = &popup->scrollbar.x;
25186 popup->layout->offset_y = &popup->scrollbar.y;
25190 root = win->layout;
25193 root = root->parent;
25212 if (!ctx || !ctx->current)
return;
25214 popup = ctx->current;
25215 NK_ASSERT(popup->parent);
25216 NK_ASSERT((
int)popup->layout->type & (
int)NK_PANEL_SET_POPUP);
25236 NK_ASSERT(ctx->current);
25237 NK_ASSERT(ctx->current->layout);
25238 if (!ctx || !ctx->current || !ctx->current->layout)
25241 popup = ctx->current;
25242 if (!popup->parent)
return;
25243 win = popup->parent;
25246 root = win->layout;
25249 root = root->parent;
25251 win->popup.active = 0;
25253 nk_push_scissor(&popup->buffer, nk_null_rect);
25256 win->buffer = popup->buffer;
25257 nk_finish_popup(ctx, win);
25258 ctx->current = win;
25259 nk_push_scissor(&win->buffer, win->layout->clip);
25274 nk_popup_get_scroll(
const struct nk_context *ctx, nk_uint *offset_x, nk_uint *offset_y)
25279 NK_ASSERT(ctx->current);
25280 NK_ASSERT(ctx->current->layout);
25281 if (!ctx || !ctx->current || !ctx->current->layout)
25284 popup = ctx->current;
25286 *offset_x = popup->scrollbar.x;
25288 *offset_y = popup->scrollbar.y;
25303 nk_popup_set_scroll(
struct nk_context *ctx, nk_uint offset_x, nk_uint offset_y)
25308 NK_ASSERT(ctx->current);
25309 NK_ASSERT(ctx->current->layout);
25310 if (!ctx || !ctx->current || !ctx->current->layout)
25313 popup = ctx->current;
25314 popup->scrollbar.x = offset_x;
25315 popup->scrollbar.y = offset_y;
25339 nk_contextual_begin(
struct nk_context *ctx, nk_flags flags,
struct nk_vec2 size,
25340 struct nk_rect trigger_bounds)
25347 NK_STORAGE
const struct nk_rect null_rect = {-1,-1,0,0};
25348 int is_clicked = 0;
25353 NK_ASSERT(ctx->current);
25354 NK_ASSERT(ctx->current->layout);
25355 if (!ctx || !ctx->current || !ctx->current->layout)
25358 win = ctx->current;
25359 ++win->popup.con_count;
25360 if (ctx->current != ctx->active)
25364 popup = win->popup.win;
25365 is_open = (popup && win->popup.type == NK_PANEL_CONTEXTUAL);
25366 in = win->widgets_disabled ? 0 : &ctx->input;
25368 is_clicked = nk_input_mouse_clicked(in, NK_BUTTON_RIGHT, trigger_bounds);
25369 if (win->popup.active_con && win->popup.con_count != win->popup.active_con)
25371 if (!is_open && win->popup.active_con)
25372 win->popup.active_con = 0;
25373 if ((!is_open && !is_clicked))
25377 win->popup.active_con = win->popup.con_count;
25379 body.x = in->mouse.pos.x;
25380 body.y = in->mouse.pos.y;
25382 body.x = popup->bounds.x;
25383 body.y = popup->bounds.y;
25390 ret = nk_nonblock_begin(ctx, flags | NK_WINDOW_NO_SCROLLBAR, body,
25391 null_rect, NK_PANEL_CONTEXTUAL);
25392 if (ret) win->popup.type = NK_PANEL_CONTEXTUAL;
25394 win->popup.active_con = 0;
25395 win->popup.type = NK_PANEL_NONE;
25396 if (win->popup.win)
25397 win->popup.win->flags = 0;
25415 nk_contextual_item_text(
struct nk_context *ctx,
const char *text,
int len,
25416 nk_flags alignment)
25426 NK_ASSERT(ctx->current);
25427 NK_ASSERT(ctx->current->layout);
25428 if (!ctx || !ctx->current || !ctx->current->layout)
25431 win = ctx->current;
25432 style = &ctx->style;
25433 state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding);
25434 if (!state)
return nk_false;
25437 if (nk_do_button_text(&ctx->last_widget_state, &win->buffer, bounds,
25438 text, len, alignment, NK_BUTTON_DEFAULT, &style->contextual_button, in, style->font)) {
25439 nk_contextual_close(ctx);
25457 nk_contextual_item_label(
struct nk_context *ctx,
const char *label, nk_flags align)
25459 return nk_contextual_item_text(ctx, label, nk_strlen(label), align);
25474 const char *text,
int len, nk_flags align)
25484 NK_ASSERT(ctx->current);
25485 NK_ASSERT(ctx->current->layout);
25486 if (!ctx || !ctx->current || !ctx->current->layout)
25489 win = ctx->current;
25490 style = &ctx->style;
25491 state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding);
25492 if (!state)
return nk_false;
25495 if (nk_do_button_text_image(&ctx->last_widget_state, &win->buffer, bounds,
25496 img, text, len, align, NK_BUTTON_DEFAULT, &style->contextual_button, style->font, in)){
25497 nk_contextual_close(ctx);
25515 const char *label, nk_flags align)
25517 return nk_contextual_item_image_text(ctx, img, label, nk_strlen(label), align);
25531 nk_contextual_item_symbol_text(
struct nk_context *ctx,
enum nk_symbol_type symbol,
25532 const char *text,
int len, nk_flags align)
25542 NK_ASSERT(ctx->current);
25543 NK_ASSERT(ctx->current->layout);
25544 if (!ctx || !ctx->current || !ctx->current->layout)
25547 win = ctx->current;
25548 style = &ctx->style;
25549 state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding);
25550 if (!state)
return nk_false;
25553 if (nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, bounds,
25554 symbol, text, len, align, NK_BUTTON_DEFAULT, &style->contextual_button, style->font, in)) {
25555 nk_contextual_close(ctx);
25572 nk_contextual_item_symbol_label(
struct nk_context *ctx,
enum nk_symbol_type symbol,
25573 const char *text, nk_flags align)
25575 return nk_contextual_item_symbol_text(ctx, symbol, text, nk_strlen(text), align);
25591 NK_ASSERT(ctx->current);
25592 NK_ASSERT(ctx->current->layout);
25593 if (!ctx || !ctx->current || !ctx->current->layout)
return;
25594 nk_popup_close(ctx);
25612 NK_ASSERT(ctx->current);
25613 if (!ctx || !ctx->current)
return;
25615 popup = ctx->current;
25616 panel = popup->layout;
25617 NK_ASSERT(popup->parent);
25618 NK_ASSERT((
int)panel->type & (
int)NK_PANEL_SET_POPUP);
25625 struct nk_rect body = {0,0,0,0};
25626 if (panel->at_y < (panel->bounds.y + panel->bounds.h)) {
25627 struct nk_vec2 padding = nk_panel_get_padding(&ctx->style, panel->type);
25628 body = panel->bounds;
25629 body.y = (panel->at_y + panel->footer_height + panel->border + padding.y + panel->row.height);
25630 body.h = (panel->bounds.y + panel->bounds.h) - body.y;
25632 {
int pressed = nk_input_is_mouse_pressed(&ctx->input, NK_BUTTON_LEFT);
25633 int in_body = nk_input_is_mouse_hovering_rect(&ctx->input, body);
25634 if (pressed && in_body)
25668 NK_ASSERT(ctx->current);
25669 NK_ASSERT(ctx->current->layout);
25670 if (!ctx || !ctx->current || !ctx->current->layout)
25673 layout = ctx->current->layout;
25674 NK_ASSERT(layout->at_y == layout->bounds.y);
25693 layout->menu.x = layout->at_x;
25694 layout->menu.y = layout->at_y + layout->row.height;
25695 layout->menu.w = layout->bounds.w;
25696 layout->menu.offset.x = *layout->offset_x;
25697 layout->menu.offset.y = *layout->offset_y;
25698 *layout->offset_y = 0;
25718 NK_ASSERT(ctx->current);
25719 NK_ASSERT(ctx->current->layout);
25720 if (!ctx || !ctx->current || !ctx->current->layout)
25723 win = ctx->current;
25724 out = &win->buffer;
25725 layout = win->layout;
25729 layout->menu.h = layout->at_y - layout->menu.y;
25730 layout->menu.h += layout->row.height + ctx->style.window.spacing.y;
25732 layout->bounds.y += layout->menu.h;
25733 layout->bounds.h -= layout->menu.h;
25735 *layout->offset_x = layout->menu.offset.x;
25736 *layout->offset_y = layout->menu.offset.y;
25737 layout->at_y = layout->bounds.y - layout->row.height;
25739 layout->clip.y = layout->bounds.y;
25740 layout->clip.h = layout->bounds.h;
25741 nk_push_scissor(out, layout->clip);
25756 const char *
id,
int is_clicked,
struct nk_rect header,
struct nk_vec2 size)
25762 nk_hash hash = nk_murmur_hash(
id, (
int)nk_strlen(
id), NK_PANEL_MENU);
25765 NK_ASSERT(ctx->current);
25766 NK_ASSERT(ctx->current->layout);
25767 if (!ctx || !ctx->current || !ctx->current->layout)
25772 body.y = header.y + header.h;
25775 popup = win->popup.win;
25776 is_open = popup ? nk_true : nk_false;
25777 is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_MENU);
25778 if ((is_clicked && is_open && !is_active) || (is_open && !is_active) ||
25779 (!is_open && !is_active && !is_clicked))
return 0;
25780 if (!nk_nonblock_begin(ctx, NK_WINDOW_NO_SCROLLBAR, body, header, NK_PANEL_MENU))
25783 win->popup.type = NK_PANEL_MENU;
25784 win->popup.name = hash;
25800 nk_menu_begin_text(
struct nk_context *ctx,
const char *title,
int len,
25801 nk_flags align,
struct nk_vec2 size)
25806 int is_clicked = nk_false;
25810 NK_ASSERT(ctx->current);
25811 NK_ASSERT(ctx->current->layout);
25812 if (!ctx || !ctx->current || !ctx->current->layout)
25815 win = ctx->current;
25816 state = nk_widget(&header, ctx);
25817 if (!state)
return 0;
25819 if (nk_do_button_text(&ctx->last_widget_state, &win->buffer, header,
25820 title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in, ctx->style.font))
25821 is_clicked = nk_true;
25822 return nk_menu_begin(ctx, win, title, is_clicked, header, size);
25834 NK_API nk_bool nk_menu_begin_label(
struct nk_context *ctx,
25835 const char *text, nk_flags align,
struct nk_vec2 size)
25837 return nk_menu_begin_text(ctx, text, nk_strlen(text), align, size);
25858 int is_clicked = nk_false;
25862 NK_ASSERT(ctx->current);
25863 NK_ASSERT(ctx->current->layout);
25864 if (!ctx || !ctx->current || !ctx->current->layout)
25867 win = ctx->current;
25868 state = nk_widget(&header, ctx);
25869 if (!state)
return 0;
25871 if (nk_do_button_image(&ctx->last_widget_state, &win->buffer, header,
25872 img, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in))
25873 is_clicked = nk_true;
25874 return nk_menu_begin(ctx, win,
id, is_clicked, header, size);
25888 nk_menu_begin_symbol(
struct nk_context *ctx,
const char *
id,
25889 enum nk_symbol_type sym,
struct nk_vec2 size)
25894 int is_clicked = nk_false;
25898 NK_ASSERT(ctx->current);
25899 NK_ASSERT(ctx->current->layout);
25900 if (!ctx || !ctx->current || !ctx->current->layout)
25903 win = ctx->current;
25904 state = nk_widget(&header, ctx);
25905 if (!state)
return 0;
25907 if (nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, header,
25908 sym, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in, ctx->style.font))
25909 is_clicked = nk_true;
25910 return nk_menu_begin(ctx, win,
id, is_clicked, header, size);
25925 nk_menu_begin_image_text(
struct nk_context *ctx,
const char *title,
int len,
25931 int is_clicked = nk_false;
25935 NK_ASSERT(ctx->current);
25936 NK_ASSERT(ctx->current->layout);
25937 if (!ctx || !ctx->current || !ctx->current->layout)
25940 win = ctx->current;
25941 state = nk_widget(&header, ctx);
25942 if (!state)
return 0;
25944 if (nk_do_button_text_image(&ctx->last_widget_state, &win->buffer,
25945 header, img, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button,
25946 ctx->style.font, in))
25947 is_clicked = nk_true;
25948 return nk_menu_begin(ctx, win, title, is_clicked, header, size);
25961 nk_menu_begin_image_label(
struct nk_context *ctx,
25962 const char *title, nk_flags align,
struct nk_image img,
struct nk_vec2 size)
25964 return nk_menu_begin_image_text(ctx, title, nk_strlen(title), align, img, size);
25979 nk_menu_begin_symbol_text(
struct nk_context *ctx,
const char *title,
int len,
25980 nk_flags align,
enum nk_symbol_type sym,
struct nk_vec2 size)
25985 int is_clicked = nk_false;
25989 NK_ASSERT(ctx->current);
25990 NK_ASSERT(ctx->current->layout);
25991 if (!ctx || !ctx->current || !ctx->current->layout)
25994 win = ctx->current;
25995 state = nk_widget(&header, ctx);
25996 if (!state)
return 0;
25999 if (nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer,
26000 header, sym, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button,
26001 ctx->style.font, in)) is_clicked = nk_true;
26002 return nk_menu_begin(ctx, win, title, is_clicked, header, size);
26015 nk_menu_begin_symbol_label(
struct nk_context *ctx,
26016 const char *title, nk_flags align,
enum nk_symbol_type sym,
struct nk_vec2 size )
26018 return nk_menu_begin_symbol_text(ctx, title, nk_strlen(title), align,sym,size);
26034 nk_menu_item_text(
struct nk_context *ctx,
const char *title,
int len, nk_flags align)
26036 return nk_contextual_item_text(ctx, title, len, align);
26051 nk_menu_item_label(
struct nk_context *ctx,
const char *label, nk_flags align)
26053 return nk_contextual_item_label(ctx, label, align);
26068 const char *label, nk_flags align)
26070 return nk_contextual_item_image_label(ctx, img, label, align);
26085 const char *text,
int len, nk_flags align)
26087 return nk_contextual_item_image_text(ctx, img, text, len, align);
26100 NK_API nk_bool nk_menu_item_symbol_text(
struct nk_context *ctx,
enum nk_symbol_type sym,
26101 const char *text,
int len, nk_flags align)
26103 return nk_contextual_item_symbol_text(ctx, sym, text, len, align);
26116 NK_API nk_bool nk_menu_item_symbol_label(
struct nk_context *ctx,
enum nk_symbol_type sym,
26117 const char *label, nk_flags align)
26119 return nk_contextual_item_symbol_label(ctx, sym, label, align);
26131 NK_API
void nk_menu_close(
struct nk_context *ctx)
26133 nk_contextual_close(ctx);
26148 nk_contextual_end(ctx);
26178 NK_ASSERT(ctx->current);
26179 NK_ASSERT(ctx->current->layout);
26180 if (!ctx || !ctx->current || !ctx->current->layout)
26183 win = ctx->current;
26184 layout = win->layout;
26185 layout->row.min_height = height;
26204 NK_ASSERT(ctx->current);
26205 NK_ASSERT(ctx->current->layout);
26206 if (!ctx || !ctx->current || !ctx->current->layout)
26209 win = ctx->current;
26210 layout = win->layout;
26211 layout->row.min_height = ctx->style.font->
height;
26212 layout->row.min_height += ctx->style.text.padding.y*2;
26213 layout->row.min_height += ctx->style.window.min_row_height_padding*2;
26227 nk_layout_row_calculate_usable_space(
const struct nk_style *style,
enum nk_panel_type type,
26228 float total_space,
int columns)
26230 float panel_spacing;
26237 spacing = style->window.spacing;
26240 panel_spacing = (float)NK_MAX(columns - 1, 0) * spacing.x;
26241 panel_space = total_space - panel_spacing;
26242 return panel_space;
26257 float height,
int cols)
26267 NK_ASSERT(ctx->current);
26268 NK_ASSERT(ctx->current->layout);
26269 if (!ctx || !ctx->current || !ctx->current->layout)
26273 layout = win->layout;
26274 style = &ctx->style;
26275 out = &win->buffer;
26276 color = style->window.background;
26277 item_spacing = style->window.spacing;
26289 layout->row.index = 0;
26290 layout->at_y += layout->row.height;
26291 layout->row.columns = cols;
26292 if (height == 0.0f)
26293 layout->row.height = NK_MAX(height, layout->row.min_height) + item_spacing.y;
26294 else layout->row.height = height + item_spacing.y;
26296 layout->row.item_offset = 0;
26300 background.x = win->bounds.x;
26301 background.w = win->bounds.w;
26302 background.y = layout->at_y - 1.0f;
26303 background.h = layout->row.height + 1.0f;
26320 float height,
int cols,
int width)
26325 NK_ASSERT(ctx->current);
26326 NK_ASSERT(ctx->current->layout);
26327 if (!ctx || !ctx->current || !ctx->current->layout)
26330 win = ctx->current;
26331 nk_panel_layout(ctx, win, height, cols);
26332 if (fmt == NK_DYNAMIC)
26333 win->layout->row.type = NK_LAYOUT_DYNAMIC_FIXED;
26334 else win->layout->row.type = NK_LAYOUT_STATIC_FIXED;
26336 win->layout->row.ratio = 0;
26337 win->layout->row.filled = 0;
26338 win->layout->row.item_offset = 0;
26339 win->layout->row.item_width = (float)width;
26357 NK_ASSERT(pixel_width);
26358 if (!ctx || !ctx->current || !ctx->current->layout)
return 0;
26359 win = ctx->current;
26360 return NK_CLAMP(0.0f, pixel_width/win->bounds.x, 1.0f);
26410 float row_height,
int cols)
26416 NK_ASSERT(ctx->current);
26417 NK_ASSERT(ctx->current->layout);
26418 if (!ctx || !ctx->current || !ctx->current->layout)
26421 win = ctx->current;
26422 layout = win->layout;
26423 nk_panel_layout(ctx, win, row_height, cols);
26424 if (fmt == NK_DYNAMIC)
26425 layout->row.type = NK_LAYOUT_DYNAMIC_ROW;
26426 else layout->row.type = NK_LAYOUT_STATIC_ROW;
26428 layout->row.ratio = 0;
26429 layout->row.filled = 0;
26430 layout->row.item_width = 0;
26431 layout->row.item_offset = 0;
26432 layout->row.columns = cols;
26452 NK_ASSERT(ctx->current);
26453 NK_ASSERT(ctx->current->layout);
26454 if (!ctx || !ctx->current || !ctx->current->layout)
26457 win = ctx->current;
26458 layout = win->layout;
26459 NK_ASSERT(layout->row.type == NK_LAYOUT_STATIC_ROW || layout->row.type == NK_LAYOUT_DYNAMIC_ROW);
26460 if (layout->row.type != NK_LAYOUT_STATIC_ROW && layout->row.type != NK_LAYOUT_DYNAMIC_ROW)
26463 if (layout->row.type == NK_LAYOUT_DYNAMIC_ROW) {
26464 float ratio = ratio_or_width;
26465 if ((ratio + layout->row.filled) > 1.0f)
return;
26467 layout->row.item_width = NK_SATURATE(ratio);
26468 else layout->row.item_width = 1.0f - layout->row.filled;
26469 }
else layout->row.item_width = ratio_or_width;
26488 NK_ASSERT(ctx->current);
26489 NK_ASSERT(ctx->current->layout);
26490 if (!ctx || !ctx->current || !ctx->current->layout)
26493 win = ctx->current;
26494 layout = win->layout;
26495 NK_ASSERT(layout->row.type == NK_LAYOUT_STATIC_ROW || layout->row.type == NK_LAYOUT_DYNAMIC_ROW);
26496 if (layout->row.type != NK_LAYOUT_STATIC_ROW && layout->row.type != NK_LAYOUT_DYNAMIC_ROW)
26498 layout->row.item_width = 0;
26499 layout->row.item_offset = 0;
26514 float height,
int cols,
const float *ratio)
26522 NK_ASSERT(ctx->current);
26523 NK_ASSERT(ctx->current->layout);
26524 if (!ctx || !ctx->current || !ctx->current->layout)
26527 win = ctx->current;
26528 layout = win->layout;
26529 nk_panel_layout(ctx, win, height, cols);
26530 if (fmt == NK_DYNAMIC) {
26533 layout->row.ratio = ratio;
26534 for (i = 0; i < cols; ++i) {
26535 if (ratio[i] < 0.0f)
26537 else r += ratio[i];
26539 r = NK_SATURATE(1.0f - r);
26540 layout->row.type = NK_LAYOUT_DYNAMIC;
26541 layout->row.item_width = (r > 0 && n_undef > 0) ? (r / (
float)n_undef):0;
26543 layout->row.ratio = ratio;
26544 layout->row.type = NK_LAYOUT_STATIC;
26545 layout->row.item_width = 0;
26546 layout->row.item_offset = 0;
26548 layout->row.item_offset = 0;
26549 layout->row.filled = 0;
26569 NK_ASSERT(ctx->current);
26570 NK_ASSERT(ctx->current->layout);
26571 if (!ctx || !ctx->current || !ctx->current->layout)
26574 win = ctx->current;
26575 layout = win->layout;
26576 nk_panel_layout(ctx, win, height, 1);
26577 layout->row.type = NK_LAYOUT_TEMPLATE;
26578 layout->row.columns = 0;
26579 layout->row.ratio = 0;
26580 layout->row.item_width = 0;
26581 layout->row.item_height = 0;
26582 layout->row.item_offset = 0;
26583 layout->row.filled = 0;
26584 layout->row.item.x = 0;
26585 layout->row.item.y = 0;
26586 layout->row.item.w = 0;
26587 layout->row.item.h = 0;
26606 NK_ASSERT(ctx->current);
26607 NK_ASSERT(ctx->current->layout);
26608 if (!ctx || !ctx->current || !ctx->current->layout)
26611 win = ctx->current;
26612 layout = win->layout;
26613 NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
26614 NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
26615 if (layout->row.type != NK_LAYOUT_TEMPLATE)
return;
26616 if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS)
return;
26617 layout->row.templates[layout->row.columns++] = -1.0f;
26637 NK_ASSERT(ctx->current);
26638 NK_ASSERT(ctx->current->layout);
26639 if (!ctx || !ctx->current || !ctx->current->layout)
26642 win = ctx->current;
26643 layout = win->layout;
26644 NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
26645 NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
26646 if (layout->row.type != NK_LAYOUT_TEMPLATE)
return;
26647 if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS)
return;
26648 layout->row.templates[layout->row.columns++] = -min_width;
26668 NK_ASSERT(ctx->current);
26669 NK_ASSERT(ctx->current->layout);
26670 if (!ctx || !ctx->current || !ctx->current->layout)
26673 win = ctx->current;
26674 layout = win->layout;
26675 NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
26676 NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
26677 if (layout->row.type != NK_LAYOUT_TEMPLATE)
return;
26678 if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS)
return;
26679 layout->row.templates[layout->row.columns++] = width;
26698 int variable_count = 0;
26699 int min_variable_count = 0;
26700 float min_fixed_width = 0.0f;
26701 float total_fixed_width = 0.0f;
26702 float max_variable_width = 0.0f;
26705 NK_ASSERT(ctx->current);
26706 NK_ASSERT(ctx->current->layout);
26707 if (!ctx || !ctx->current || !ctx->current->layout)
26710 win = ctx->current;
26711 layout = win->layout;
26712 NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
26713 if (layout->row.type != NK_LAYOUT_TEMPLATE)
return;
26714 for (i = 0; i < layout->row.columns; ++i) {
26715 float width = layout->row.templates[i];
26716 if (width >= 0.0f) {
26717 total_fixed_width += width;
26718 min_fixed_width += width;
26719 }
else if (width < -1.0f) {
26721 total_fixed_width += width;
26722 max_variable_width = NK_MAX(max_variable_width, width);
26725 min_variable_count++;
26729 if (variable_count) {
26730 float space = nk_layout_row_calculate_usable_space(&ctx->style, layout->type,
26731 layout->bounds.w, layout->row.columns);
26732 float var_width = (NK_MAX(space-min_fixed_width,0.0f)) / (
float)variable_count;
26733 int enough_space = var_width >= max_variable_width;
26735 var_width = (NK_MAX(space-total_fixed_width,0)) / (
float)min_variable_count;
26736 for (i = 0; i < layout->row.columns; ++i) {
26737 float *width = &layout->row.templates[i];
26738 *width = (*width >= 0.0f)? *width: (*width < -1.0f && !enough_space)? -(*width): var_width;
26755 float height,
int widget_count)
26761 NK_ASSERT(ctx->current);
26762 NK_ASSERT(ctx->current->layout);
26763 if (!ctx || !ctx->current || !ctx->current->layout)
26766 win = ctx->current;
26767 layout = win->layout;
26768 nk_panel_layout(ctx, win, height, widget_count);
26769 if (fmt == NK_STATIC)
26770 layout->row.type = NK_LAYOUT_STATIC_FREE;
26771 else layout->row.type = NK_LAYOUT_DYNAMIC_FREE;
26773 layout->row.ratio = 0;
26774 layout->row.filled = 0;
26775 layout->row.item_width = 0;
26776 layout->row.item_offset = 0;
26795 NK_ASSERT(ctx->current);
26796 NK_ASSERT(ctx->current->layout);
26797 if (!ctx || !ctx->current || !ctx->current->layout)
26800 win = ctx->current;
26801 layout = win->layout;
26802 layout->row.item_width = 0;
26803 layout->row.item_height = 0;
26804 layout->row.item_offset = 0;
26805 nk_zero(&layout->row.item,
sizeof(layout->row.item));
26825 NK_ASSERT(ctx->current);
26826 NK_ASSERT(ctx->current->layout);
26827 if (!ctx || !ctx->current || !ctx->current->layout)
26830 win = ctx->current;
26831 layout = win->layout;
26832 layout->row.item = rect;
26852 NK_ASSERT(ctx->current);
26853 NK_ASSERT(ctx->current->layout);
26854 win = ctx->current;
26855 layout = win->layout;
26857 ret.x = layout->clip.x;
26858 ret.y = layout->clip.y;
26859 ret.w = layout->clip.w;
26860 ret.h = layout->row.height;
26881 NK_ASSERT(ctx->current);
26882 NK_ASSERT(ctx->current->layout);
26883 win = ctx->current;
26884 layout = win->layout;
26886 ret.x = layout->at_x;
26887 ret.y = layout->at_y;
26888 ret.w = layout->bounds.w - NK_MAX(layout->at_x - layout->bounds.x,0);
26889 ret.h = layout->row.height;
26910 NK_ASSERT(ctx->current);
26911 NK_ASSERT(ctx->current->layout);
26912 win = ctx->current;
26913 layout = win->layout;
26915 ret.x += layout->at_x - (float)*layout->offset_x;
26916 ret.y += layout->at_y - (
float)*layout->offset_y;
26937 NK_ASSERT(ctx->current);
26938 NK_ASSERT(ctx->current->layout);
26939 win = ctx->current;
26940 layout = win->layout;
26942 ret.x += -layout->at_x + (float)*layout->offset_x;
26943 ret.y += -layout->at_y + (
float)*layout->offset_y;
26964 NK_ASSERT(ctx->current);
26965 NK_ASSERT(ctx->current->layout);
26966 win = ctx->current;
26967 layout = win->layout;
26969 ret.x += layout->at_x - (float)*layout->offset_x;
26970 ret.y += layout->at_y - (
float)*layout->offset_y;
26991 NK_ASSERT(ctx->current);
26992 NK_ASSERT(ctx->current->layout);
26993 win = ctx->current;
26994 layout = win->layout;
26996 ret.x += -layout->at_x + (float)*layout->offset_x;
26997 ret.y += -layout->at_y + (
float)*layout->offset_y;
27014 struct nk_panel *layout = win->layout;
27015 struct nk_vec2 spacing = ctx->style.window.spacing;
27016 const float row_height = layout->row.height - spacing.y;
27017 nk_panel_layout(ctx, win, row_height, layout->row.columns);
27039 float item_offset = 0;
27040 float item_width = 0;
27041 float item_spacing = 0;
27042 float panel_space = 0;
27045 NK_ASSERT(ctx->current);
27046 NK_ASSERT(ctx->current->layout);
27047 if (!ctx || !ctx->current || !ctx->current->layout)
27050 win = ctx->current;
27051 layout = win->layout;
27052 style = &ctx->style;
27055 spacing = style->window.spacing;
27056 panel_space = nk_layout_row_calculate_usable_space(&ctx->style, layout->type,
27057 layout->bounds.w, layout->row.columns);
27059 #define NK_FRAC(x) (x - (float)(int)nk_roundf(x))
27061 switch (layout->row.type) {
27062 case NK_LAYOUT_DYNAMIC_FIXED: {
27064 float w = NK_MAX(1.0f,panel_space) / (float)layout->row.columns;
27065 item_offset = (
float)layout->row.index * w;
27066 item_width = w + NK_FRAC(item_offset);
27067 item_spacing = (float)layout->row.index * spacing.x;
27069 case NK_LAYOUT_DYNAMIC_ROW: {
27071 float w = layout->row.item_width * panel_space;
27072 item_offset = layout->row.item_offset;
27073 item_width = w + NK_FRAC(item_offset);
27077 layout->row.item_offset += w + spacing.x;
27078 layout->row.filled += layout->row.item_width;
27079 layout->row.index = 0;
27082 case NK_LAYOUT_DYNAMIC_FREE: {
27084 bounds->x = layout->at_x + (layout->bounds.w * layout->row.item.x);
27085 bounds->x -= (float)*layout->offset_x;
27086 bounds->y = layout->at_y + (layout->row.height * layout->row.item.y);
27087 bounds->y -= (float)*layout->offset_y;
27088 bounds->w = layout->bounds.w * layout->row.item.w + NK_FRAC(bounds->x);
27089 bounds->h = layout->row.height * layout->row.item.h + NK_FRAC(bounds->y);
27092 case NK_LAYOUT_DYNAMIC: {
27095 NK_ASSERT(layout->row.ratio);
27096 ratio = (layout->row.ratio[layout->row.index] < 0) ?
27097 layout->row.item_width : layout->row.ratio[layout->row.index];
27099 w = (ratio * panel_space);
27100 item_spacing = (float)layout->row.index * spacing.x;
27101 item_offset = layout->row.item_offset;
27102 item_width = w + NK_FRAC(item_offset);
27105 layout->row.item_offset += w;
27106 layout->row.filled += ratio;
27109 case NK_LAYOUT_STATIC_FIXED: {
27111 item_width = layout->row.item_width;
27112 item_offset = (float)layout->row.index * item_width;
27113 item_spacing = (
float)layout->row.index * spacing.x;
27115 case NK_LAYOUT_STATIC_ROW: {
27117 item_width = layout->row.item_width;
27118 item_offset = layout->row.item_offset;
27119 item_spacing = (float)layout->row.index * spacing.x;
27120 if (modify) layout->row.item_offset += item_width;
27122 case NK_LAYOUT_STATIC_FREE: {
27124 bounds->x = layout->at_x + layout->row.item.x;
27125 bounds->w = layout->row.item.w;
27126 if (((bounds->x + bounds->w) > layout->max_x) && modify)
27127 layout->max_x = (bounds->x + bounds->w);
27128 bounds->x -= (float)*layout->offset_x;
27129 bounds->y = layout->at_y + layout->row.item.y;
27130 bounds->y -= (
float)*layout->offset_y;
27131 bounds->h = layout->row.item.h;
27134 case NK_LAYOUT_STATIC: {
27136 item_spacing = (float)layout->row.index * spacing.x;
27137 item_width = layout->row.ratio[layout->row.index];
27138 item_offset = layout->row.item_offset;
27139 if (modify) layout->row.item_offset += item_width;
27141 case NK_LAYOUT_TEMPLATE: {
27144 NK_ASSERT(layout->row.index < layout->row.columns);
27145 NK_ASSERT(layout->row.index < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
27146 w = layout->row.templates[layout->row.index];
27147 item_offset = layout->row.item_offset;
27148 item_width = w + NK_FRAC(item_offset);
27149 item_spacing = (float)layout->row.index * spacing.x;
27150 if (modify) layout->row.item_offset += w;
27153 default: NK_ASSERT(0);
break;
27157 bounds->w = item_width;
27158 bounds->h = layout->row.height - spacing.y;
27159 bounds->y = layout->at_y - (float)*layout->offset_y;
27160 bounds->x = layout->at_x + item_offset + item_spacing;
27161 if (((bounds->x + bounds->w) > layout->max_x) && modify)
27162 layout->max_x = bounds->x + bounds->w;
27163 bounds->x -= (
float)*layout->offset_x;
27183 NK_ASSERT(ctx->current);
27184 NK_ASSERT(ctx->current->layout);
27185 if (!ctx || !ctx->current || !ctx->current->layout)
27189 win = ctx->current;
27190 layout = win->layout;
27191 if (layout->row.index >= layout->row.columns)
27192 nk_panel_alloc_row(ctx, win);
27195 nk_layout_widget_space(bounds, ctx, win, nk_true);
27196 layout->row.index++;
27218 NK_ASSERT(ctx->current);
27219 NK_ASSERT(ctx->current->layout);
27220 if (!ctx || !ctx->current || !ctx->current->layout) {
27225 win = ctx->current;
27226 layout = win->layout;
27228 index = layout->row.index;
27229 if (layout->row.index >= layout->row.columns) {
27230 layout->at_y += layout->row.height;
27231 layout->row.index = 0;
27233 nk_layout_widget_space(bounds, ctx, win, nk_false);
27234 if (!layout->row.index) {
27235 bounds->x -= layout->row.item_offset;
27238 layout->row.index = index;
27252 struct nk_rect dummy_rect = { 0, 0, 0, 0 };
27253 nk_panel_alloc_space( &dummy_rect, ctx );
27276 nk_tree_state_base(
struct nk_context *ctx,
enum nk_tree_type type,
27277 struct nk_image *img,
const char *title,
enum nk_collapse_states *state)
27285 enum nk_symbol_type symbol;
27289 struct nk_rect header = {0,0,0,0};
27290 struct nk_rect sym = {0,0,0,0};
27291 struct nk_text text;
27297 NK_ASSERT(ctx->current);
27298 NK_ASSERT(ctx->current->layout);
27299 if (!ctx || !ctx->current || !ctx->current->layout)
27303 win = ctx->current;
27304 layout = win->layout;
27305 out = &win->buffer;
27306 style = &ctx->style;
27307 item_spacing = style->window.spacing;
27310 row_height = style->font->
height + 2 * style->tab.padding.y;
27315 widget_state = nk_widget(&header, ctx);
27316 if (type == NK_TREE_TAB) {
27317 const struct nk_style_item *background = &style->tab.background;
27319 switch(background->type) {
27320 case NK_STYLE_ITEM_IMAGE:
27321 nk_draw_image(out, header, &background->data.image, nk_rgb_factor(nk_white, style->tab.color_factor));
27323 case NK_STYLE_ITEM_NINE_SLICE:
27324 nk_draw_nine_slice(out, header, &background->data.slice, nk_rgb_factor(nk_white, style->tab.color_factor));
27326 case NK_STYLE_ITEM_COLOR:
27327 nk_fill_rect(out, header, 0, nk_rgb_factor(style->tab.border_color, style->tab.color_factor));
27328 nk_fill_rect(out, nk_shrink_rect(header, style->tab.border),
27329 style->tab.rounding, nk_rgb_factor(background->data.color, style->tab.color_factor));
27332 }
else text.background = style->window.background;
27337 if (nk_button_behavior(&ws, header, in, NK_BUTTON_DEFAULT))
27338 *state = (*state == NK_MAXIMIZED) ? NK_MINIMIZED : NK_MAXIMIZED;
27341 if (*state == NK_MAXIMIZED) {
27342 symbol = style->tab.sym_maximize;
27343 if (type == NK_TREE_TAB)
27344 button = &style->tab.tab_maximize_button;
27345 else button = &style->tab.node_maximize_button;
27347 symbol = style->tab.sym_minimize;
27348 if (type == NK_TREE_TAB)
27349 button = &style->tab.tab_minimize_button;
27350 else button = &style->tab.node_minimize_button;
27354 sym.w = sym.h = style->font->
height;
27355 sym.y = header.y + style->tab.padding.y;
27356 sym.x = header.x + style->tab.padding.x;
27357 nk_do_button_symbol(&ws, &win->buffer, sym, symbol, NK_BUTTON_DEFAULT,
27358 button, 0, style->font);
27362 sym.x = sym.x + sym.w + 4 * item_spacing.x;
27364 sym.w = style->font->
height + style->tab.spacing.x;}
27369 header.w = NK_MAX(header.w, sym.w + item_spacing.x);
27370 label.x = sym.x + sym.w + item_spacing.x;
27372 label.w = header.w - (sym.w + item_spacing.y + style->tab.indent);
27373 label.h = style->font->
height;
27374 text.text = nk_rgb_factor(style->tab.text, style->tab.color_factor);
27376 nk_widget_text(out, label, title, nk_strlen(title), &text,
27377 NK_TEXT_LEFT, style->font);}
27380 if (*state == NK_MAXIMIZED) {
27381 layout->at_x = header.x + (float)*layout->offset_x + style->tab.indent;
27382 layout->bounds.w = NK_MAX(layout->bounds.w, style->tab.indent);
27383 layout->bounds.w -= (style->tab.indent + style->window.padding.x);
27384 layout->row.tree_depth++;
27386 }
else return nk_false;
27400 nk_tree_base(
struct nk_context *ctx,
enum nk_tree_type type,
27401 struct nk_image *img,
const char *title,
enum nk_collapse_states initial_state,
27402 const char *hash,
int len,
int line)
27406 nk_hash tree_hash = 0;
27407 nk_uint *state = 0;
27411 title_len = (int)nk_strlen(title);
27412 tree_hash = nk_murmur_hash(title, (
int)title_len, (nk_hash)line);
27413 }
else tree_hash = nk_murmur_hash(hash, len, (nk_hash)line);
27414 state = nk_find_value(win, tree_hash);
27416 state = nk_add_value(ctx, win, tree_hash, 0);
27417 *state = initial_state;
27419 return nk_tree_state_base(ctx, type, img, title, (
enum nk_collapse_states*)state);
27434 const char *title,
enum nk_collapse_states *state)
27436 return nk_tree_state_base(ctx, type, 0, title, state);
27451 struct nk_image img,
const char *title,
enum nk_collapse_states *state)
27453 return nk_tree_state_base(ctx, type, &img, title, state);
27472 NK_ASSERT(ctx->current);
27473 NK_ASSERT(ctx->current->layout);
27474 if (!ctx || !ctx->current || !ctx->current->layout)
27477 win = ctx->current;
27478 layout = win->layout;
27479 layout->at_x -= ctx->style.tab.indent + (float)*layout->offset_x;
27480 layout->bounds.w += ctx->style.tab.indent + ctx->style.window.padding.x;
27481 NK_ASSERT(layout->row.tree_depth);
27482 layout->row.tree_depth--;
27497 const char *title,
enum nk_collapse_states initial_state,
27498 const char *hash,
int len,
int line)
27500 return nk_tree_base(ctx, type, 0, title, initial_state, hash, len, line);
27515 struct nk_image img,
const char *title,
enum nk_collapse_states initial_state,
27516 const char *hash,
int len,
int seed)
27518 return nk_tree_base(ctx, type, &img, title, initial_state, hash, len, seed);
27547 nk_tree_element_image_push_hashed_base(
struct nk_context *ctx,
enum nk_tree_type type,
27548 struct nk_image *img,
const char *title,
int title_len,
27549 enum nk_collapse_states *state, nk_bool *selected)
27557 enum nk_symbol_type symbol;
27565 struct nk_rect header = {0,0,0,0};
27566 struct nk_rect sym = {0,0,0,0};
27572 NK_ASSERT(ctx->current);
27573 NK_ASSERT(ctx->current->layout);
27574 if (!ctx || !ctx->current || !ctx->current->layout)
27578 win = ctx->current;
27579 layout = win->layout;
27580 out = &win->buffer;
27581 style = &ctx->style;
27582 item_spacing = style->window.spacing;
27583 padding = style->selectable.padding;
27586 row_height = style->font->
height + 2 * style->tab.padding.y;
27591 widget_state = nk_widget(&header, ctx);
27592 if (type == NK_TREE_TAB) {
27593 const struct nk_style_item *background = &style->tab.background;
27595 switch (background->type) {
27596 case NK_STYLE_ITEM_IMAGE:
27597 nk_draw_image(out, header, &background->data.image, nk_rgb_factor(nk_white, style->tab.color_factor));
27599 case NK_STYLE_ITEM_NINE_SLICE:
27600 nk_draw_nine_slice(out, header, &background->data.slice, nk_rgb_factor(nk_white, style->tab.color_factor));
27602 case NK_STYLE_ITEM_COLOR:
27603 nk_fill_rect(out, header, 0, nk_rgb_factor(style->tab.border_color, style->tab.color_factor));
27604 nk_fill_rect(out, nk_shrink_rect(header, style->tab.border),
27605 style->tab.rounding, nk_rgb_factor(background->data.color, style->tab.color_factor));
27615 if (*state == NK_MAXIMIZED) {
27616 symbol = style->tab.sym_maximize;
27617 if (type == NK_TREE_TAB)
27618 button = &style->tab.tab_maximize_button;
27619 else button = &style->tab.node_maximize_button;
27621 symbol = style->tab.sym_minimize;
27622 if (type == NK_TREE_TAB)
27623 button = &style->tab.tab_minimize_button;
27624 else button = &style->tab.node_minimize_button;
27627 sym.w = sym.h = style->font->
height;
27628 sym.y = header.y + style->tab.padding.y;
27629 sym.x = header.x + style->tab.padding.x;
27630 if (nk_do_button_symbol(&ws, &win->buffer, sym, symbol, NK_BUTTON_DEFAULT, button, in, style->font))
27631 *state = (*state == NK_MAXIMIZED) ? NK_MINIMIZED : NK_MAXIMIZED;}
27634 {nk_flags dummy = 0;
27637 text_len = nk_strlen(title);
27638 text_width = style->font->
width(style->font->userdata, style->font->
height, title, text_len);
27639 text_width += (4 * padding.x);
27641 header.w = NK_MAX(header.w, sym.w + item_spacing.x);
27642 label.x = sym.x + sym.w + item_spacing.x;
27644 label.w = NK_MIN(header.w - (sym.w + item_spacing.y + style->tab.indent), text_width);
27645 label.h = style->font->
height;
27648 nk_do_selectable_image(&dummy, &win->buffer, label, title, title_len, NK_TEXT_LEFT,
27649 selected, img, &style->selectable, in, style->font);
27650 }
else nk_do_selectable(&dummy, &win->buffer, label, title, title_len, NK_TEXT_LEFT,
27651 selected, &style->selectable, in, style->font);
27654 if (*state == NK_MAXIMIZED) {
27655 layout->at_x = header.x + (float)*layout->offset_x + style->tab.indent;
27656 layout->bounds.w = NK_MAX(layout->bounds.w, style->tab.indent);
27657 layout->bounds.w -= (style->tab.indent + style->window.padding.x);
27658 layout->row.tree_depth++;
27660 }
else return nk_false;
27674 nk_tree_element_base(
struct nk_context *ctx,
enum nk_tree_type type,
27675 struct nk_image *img,
const char *title,
enum nk_collapse_states initial_state,
27676 nk_bool *selected,
const char *hash,
int len,
int line)
27680 nk_hash tree_hash = 0;
27681 nk_uint *state = 0;
27685 title_len = (int)nk_strlen(title);
27686 tree_hash = nk_murmur_hash(title, (
int)title_len, (nk_hash)line);
27687 }
else tree_hash = nk_murmur_hash(hash, len, (nk_hash)line);
27688 state = nk_find_value(win, tree_hash);
27690 state = nk_add_value(ctx, win, tree_hash, 0);
27691 *state = initial_state;
27692 }
return nk_tree_element_image_push_hashed_base(ctx, type, img, title,
27693 nk_strlen(title), (
enum nk_collapse_states*)state, selected);
27707 nk_tree_element_push_hashed(
struct nk_context *ctx,
enum nk_tree_type type,
27708 const char *title,
enum nk_collapse_states initial_state,
27709 nk_bool *selected,
const char *hash,
int len,
int seed)
27711 return nk_tree_element_base(ctx, type, 0, title, initial_state, selected, hash, len, seed);
27725 nk_tree_element_image_push_hashed(
struct nk_context *ctx,
enum nk_tree_type type,
27726 struct nk_image img,
const char *title,
enum nk_collapse_states initial_state,
27727 nk_bool *selected,
const char *hash,
int len,
int seed)
27729 return nk_tree_element_base(ctx, type, &img, title, initial_state, selected, hash, len, seed);
27768 nk_uint *x_offset, nk_uint *y_offset,
const char *title, nk_flags flags)
27774 win = ctx->current;
27775 nk_panel_alloc_space(&bounds, ctx);
27776 {
const struct nk_rect *c = &win->layout->clip;
27777 if (!NK_INTERSECT(c->x, c->y, c->w, c->h, bounds.x, bounds.y, bounds.w, bounds.h) &&
27778 !(flags & NK_WINDOW_MOVABLE)) {
27785 nk_zero(&panel,
sizeof(panel));
27786 panel.bounds = bounds;
27787 panel.flags = flags;
27788 panel.scrollbar.x = *x_offset;
27789 panel.scrollbar.y = *y_offset;
27790 panel.buffer = win->buffer;
27791 panel.layout = (
struct nk_panel*)nk_create_panel(ctx);
27792 ctx->current = &panel;
27793 nk_panel_begin(ctx, (flags & NK_WINDOW_TITLE) ? title: 0, NK_PANEL_GROUP);
27795 win->buffer = panel.buffer;
27796 win->buffer.clip = panel.layout->clip;
27797 panel.layout->offset_x = x_offset;
27798 panel.layout->offset_y = y_offset;
27799 panel.layout->parent = win->layout;
27800 win->layout = panel.layout;
27802 ctx->current = win;
27806 nk_flags f = panel.layout->flags;
27834 struct nk_vec2 panel_padding;
27837 NK_ASSERT(ctx->current);
27838 if (!ctx || !ctx->current)
27842 NK_ASSERT(ctx->current);
27843 win = ctx->current;
27844 NK_ASSERT(win->layout);
27846 NK_ASSERT(g->parent);
27847 parent = g->parent;
27850 nk_zero_struct(pan);
27851 panel_padding = nk_panel_get_padding(&ctx->style, NK_PANEL_GROUP);
27852 pan.bounds.y = g->bounds.y - (g->header_height + g->menu.h);
27853 pan.bounds.x = g->bounds.x - panel_padding.x;
27854 pan.bounds.w = g->bounds.w + 2 * panel_padding.x;
27855 pan.bounds.h = g->bounds.h + g->header_height + g->menu.h;
27856 if (g->flags & NK_WINDOW_BORDER) {
27857 pan.bounds.x -= g->border;
27858 pan.bounds.y -= g->border;
27859 pan.bounds.w += 2*g->border;
27860 pan.bounds.h += 2*g->border;
27862 if (!(g->flags & NK_WINDOW_NO_SCROLLBAR)) {
27863 pan.bounds.w += ctx->style.window.scrollbar_size.x;
27864 pan.bounds.h += ctx->style.window.scrollbar_size.y;
27866 pan.scrollbar.x = *g->offset_x;
27867 pan.scrollbar.y = *g->offset_y;
27868 pan.flags = g->flags;
27869 pan.buffer = win->buffer;
27872 ctx->current = &pan;
27875 nk_unify(&clip, &parent->clip, pan.bounds.x, pan.bounds.y,
27876 pan.bounds.x + pan.bounds.w, pan.bounds.y + pan.bounds.h + panel_padding.x);
27877 nk_push_scissor(&pan.buffer, clip);
27880 win->buffer = pan.buffer;
27881 nk_push_scissor(&win->buffer, parent->clip);
27882 ctx->current = win;
27883 win->layout = parent;
27884 g->bounds = pan.bounds;
27899 struct nk_scroll *scroll,
const char *title, nk_flags flags)
27916 const char *title, nk_flags flags)
27926 NK_ASSERT(ctx->current);
27927 NK_ASSERT(ctx->current->layout);
27928 if (!ctx || !ctx->current || !ctx->current->layout || !
id)
27932 win = ctx->current;
27933 id_len = (int)nk_strlen(
id);
27934 id_hash = nk_murmur_hash(
id, (
int)id_len, NK_PANEL_GROUP);
27935 x_offset = nk_find_value(win, id_hash);
27937 x_offset = nk_add_value(ctx, win, id_hash, 0);
27938 y_offset = nk_add_value(ctx, win, id_hash+1, 0);
27940 NK_ASSERT(x_offset);
27941 NK_ASSERT(y_offset);
27942 if (!x_offset || !y_offset)
return 0;
27943 *x_offset = *y_offset = 0;
27944 }
else y_offset = nk_find_value(win, id_hash+1);
27997 nk_uint *x_offset_ptr;
27998 nk_uint *y_offset_ptr;
28002 NK_ASSERT(ctx->current);
28003 NK_ASSERT(ctx->current->layout);
28004 if (!ctx || !ctx->current || !ctx->current->layout || !
id)
28008 win = ctx->current;
28009 id_len = (int)nk_strlen(
id);
28010 id_hash = nk_murmur_hash(
id, (
int)id_len, NK_PANEL_GROUP);
28011 x_offset_ptr = nk_find_value(win, id_hash);
28012 if (!x_offset_ptr) {
28013 x_offset_ptr = nk_add_value(ctx, win, id_hash, 0);
28014 y_offset_ptr = nk_add_value(ctx, win, id_hash+1, 0);
28016 NK_ASSERT(x_offset_ptr);
28017 NK_ASSERT(y_offset_ptr);
28018 if (!x_offset_ptr || !y_offset_ptr)
return;
28019 *x_offset_ptr = *y_offset_ptr = 0;
28020 }
else y_offset_ptr = nk_find_value(win, id_hash+1);
28022 *x_offset = *x_offset_ptr;
28024 *y_offset = *y_offset_ptr;
28045 nk_uint *x_offset_ptr;
28046 nk_uint *y_offset_ptr;
28050 NK_ASSERT(ctx->current);
28051 NK_ASSERT(ctx->current->layout);
28052 if (!ctx || !ctx->current || !ctx->current->layout || !
id)
28056 win = ctx->current;
28057 id_len = (int)nk_strlen(
id);
28058 id_hash = nk_murmur_hash(
id, (
int)id_len, NK_PANEL_GROUP);
28059 x_offset_ptr = nk_find_value(win, id_hash);
28060 if (!x_offset_ptr) {
28061 x_offset_ptr = nk_add_value(ctx, win, id_hash, 0);
28062 y_offset_ptr = nk_add_value(ctx, win, id_hash+1, 0);
28064 NK_ASSERT(x_offset_ptr);
28065 NK_ASSERT(y_offset_ptr);
28066 if (!x_offset_ptr || !y_offset_ptr)
return;
28067 *x_offset_ptr = *y_offset_ptr = 0;
28068 }
else y_offset_ptr = nk_find_value(win, id_hash+1);
28069 *x_offset_ptr = x_offset;
28070 *y_offset_ptr = y_offset;
28094 const char *title, nk_flags flags,
int row_height,
int row_count)
28097 nk_hash title_hash;
28110 if (!ctx || !view || !title)
return 0;
28112 win = ctx->current;
28113 style = &ctx->style;
28114 item_spacing = style->window.spacing;
28115 row_height += NK_MAX(0, (
int)item_spacing.y);
28118 title_len = (int)nk_strlen(title);
28119 title_hash = nk_murmur_hash(title, (
int)title_len, NK_PANEL_GROUP);
28120 x_offset = nk_find_value(win, title_hash);
28122 x_offset = nk_add_value(ctx, win, title_hash, 0);
28123 y_offset = nk_add_value(ctx, win, title_hash+1, 0);
28125 NK_ASSERT(x_offset);
28126 NK_ASSERT(y_offset);
28127 if (!x_offset || !y_offset)
return 0;
28128 *x_offset = *y_offset = 0;
28129 }
else y_offset = nk_find_value(win, title_hash+1);
28130 view->scroll_value = *y_offset;
28131 view->scroll_pointer = y_offset;
28135 win = ctx->current;
28136 layout = win->layout;
28138 view->total_height = row_height * NK_MAX(row_count,1);
28139 view->begin = (int)NK_MAX(((
float)view->scroll_value / (
float)row_height), 0.0f);
28140 view->count = (int)NK_MAX(nk_iceilf((layout->clip.h)/(float)row_height),0);
28141 view->count = NK_MIN(view->count, row_count - view->begin);
28142 view->end = view->begin + view->count;
28164 NK_ASSERT(view->ctx);
28165 NK_ASSERT(view->scroll_pointer);
28166 if (!view || !view->ctx)
return;
28169 win = ctx->current;
28170 layout = win->layout;
28171 layout->at_y = layout->bounds.y + (float)view->total_height;
28172 *view->scroll_pointer = *view->scroll_pointer + view->scroll_value;
28196 nk_widget_bounds(const struct
nk_context *ctx)
28200 NK_ASSERT(ctx->current);
28201 if (!ctx || !ctx->current)
28203 nk_layout_peek(&bounds, ctx);
28217 nk_widget_position(const struct
nk_context *ctx)
28221 NK_ASSERT(ctx->current);
28222 if (!ctx || !ctx->current)
28225 nk_layout_peek(&bounds, ctx);
28226 return nk_vec2(bounds.x, bounds.y);
28239 nk_widget_size(const struct
nk_context *ctx)
28243 NK_ASSERT(ctx->current);
28244 if (!ctx || !ctx->current)
28247 nk_layout_peek(&bounds, ctx);
28248 return nk_vec2(bounds.w, bounds.h);
28261 nk_widget_width(
const struct nk_context *ctx)
28265 NK_ASSERT(ctx->current);
28266 if (!ctx || !ctx->current)
28269 nk_layout_peek(&bounds, ctx);
28283 nk_widget_height(
const struct nk_context *ctx)
28287 NK_ASSERT(ctx->current);
28288 if (!ctx || !ctx->current)
28291 nk_layout_peek(&bounds, ctx);
28305 nk_widget_is_hovered(
const struct nk_context *ctx)
28310 NK_ASSERT(ctx->current);
28311 if (!ctx || !ctx->current || ctx->active != ctx->current)
28314 c = ctx->current->layout->clip;
28315 c.x = (float)((
int)c.x);
28316 c.y = (float)((
int)c.y);
28317 c.w = (float)((
int)c.w);
28318 c.h = (float)((
int)c.h);
28320 nk_layout_peek(&bounds, ctx);
28321 nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
28322 if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
28324 return nk_input_is_mouse_hovering_rect(&ctx->input, bounds);
28338 nk_widget_is_mouse_clicked(
const struct nk_context *ctx,
enum nk_buttons btn)
28343 NK_ASSERT(ctx->current);
28344 if (!ctx || !ctx->current || ctx->active != ctx->current)
28347 c = ctx->current->layout->clip;
28348 c.x = (float)((
int)c.x);
28349 c.y = (float)((
int)c.y);
28350 c.w = (float)((
int)c.w);
28351 c.h = (float)((
int)c.h);
28353 nk_layout_peek(&bounds, ctx);
28354 nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
28355 if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
28357 return nk_input_mouse_clicked(&ctx->input, btn, bounds);
28372 nk_widget_has_mouse_click_down(
const struct nk_context *ctx,
enum nk_buttons btn, nk_bool down)
28377 NK_ASSERT(ctx->current);
28378 if (!ctx || !ctx->current || ctx->active != ctx->current)
28381 c = ctx->current->layout->clip;
28382 c.x = (float)((
int)c.x);
28383 c.y = (float)((
int)c.y);
28384 c.w = (float)((
int)c.w);
28385 c.h = (float)((
int)c.h);
28387 nk_layout_peek(&bounds, ctx);
28388 nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
28389 if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
28391 return nk_input_has_mouse_click_down_in_rect(&ctx->input, btn, bounds, down);
28413 NK_ASSERT(ctx->current);
28414 NK_ASSERT(ctx->current->layout);
28415 if (!ctx || !ctx->current || !ctx->current->layout)
28419 nk_panel_alloc_space(bounds, ctx);
28420 win = ctx->current;
28421 layout = win->layout;
28435 bounds->x = (float)((
int)bounds->x);
28436 bounds->y = (float)((
int)bounds->y);
28437 bounds->w = (float)((
int)bounds->w);
28438 bounds->h = (float)((
int)bounds->h);
28440 c.x = (float)((
int)c.x);
28441 c.y = (float)((
int)c.y);
28442 c.w = (float)((
int)c.w);
28443 c.h = (float)((
int)c.h);
28445 nk_unify(&v, &c, bounds->x, bounds->y, bounds->x + bounds->w, bounds->y + bounds->h);
28446 if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds->x, bounds->y, bounds->w, bounds->h))
28448 if (win->widgets_disabled)
28450 if (!NK_INBOX(in->mouse.pos.x, in->mouse.pos.y, v.x, v.y, v.w, v.h))
28471 NK_UNUSED(item_padding);
28474 NK_ASSERT(ctx->current);
28475 NK_ASSERT(ctx->current->layout);
28476 if (!ctx || !ctx->current || !ctx->current->layout)
28479 state = nk_widget(bounds, ctx);
28494 nk_spacing(
struct nk_context *ctx,
int cols)
28499 int i, index, rows;
28502 NK_ASSERT(ctx->current);
28503 NK_ASSERT(ctx->current->layout);
28504 if (!ctx || !ctx->current || !ctx->current->layout)
28508 win = ctx->current;
28509 layout = win->layout;
28510 index = (layout->row.index + cols) % layout->row.columns;
28511 rows = (layout->row.index + cols) / layout->row.columns;
28513 for (i = 0; i < rows; ++i)
28514 nk_panel_alloc_row(ctx, win);
28518 if (layout->row.type != NK_LAYOUT_DYNAMIC_FIXED &&
28519 layout->row.type != NK_LAYOUT_STATIC_FIXED) {
28520 for (i = 0; i < cols; ++i)
28521 nk_panel_alloc_space(&none, ctx);
28522 } layout->row.index = index;
28535 nk_widget_disable_begin(
struct nk_context* ctx)
28541 NK_ASSERT(ctx->current);
28543 if (!ctx || !ctx->current)
28546 win = ctx->current;
28547 style = &ctx->style;
28549 win->widgets_disabled = nk_true;
28551 style->button.color_factor_text = style->button.disabled_factor;
28552 style->button.color_factor_background = style->button.disabled_factor;
28553 style->chart.color_factor = style->chart.disabled_factor;
28554 style->checkbox.color_factor = style->checkbox.disabled_factor;
28555 style->combo.color_factor = style->combo.disabled_factor;
28556 style->combo.button.color_factor_text = style->combo.button.disabled_factor;
28557 style->combo.button.color_factor_background = style->combo.button.disabled_factor;
28558 style->contextual_button.color_factor_text = style->contextual_button.disabled_factor;
28559 style->contextual_button.color_factor_background = style->contextual_button.disabled_factor;
28560 style->edit.color_factor = style->edit.disabled_factor;
28561 style->edit.scrollbar.color_factor = style->edit.scrollbar.disabled_factor;
28562 style->menu_button.color_factor_text = style->menu_button.disabled_factor;
28563 style->menu_button.color_factor_background = style->menu_button.disabled_factor;
28564 style->option.color_factor = style->option.disabled_factor;
28565 style->progress.color_factor = style->progress.disabled_factor;
28566 style->property.color_factor = style->property.disabled_factor;
28567 style->property.inc_button.color_factor_text = style->property.inc_button.disabled_factor;
28568 style->property.inc_button.color_factor_background = style->property.inc_button.disabled_factor;
28569 style->property.dec_button.color_factor_text = style->property.dec_button.disabled_factor;
28570 style->property.dec_button.color_factor_background = style->property.dec_button.disabled_factor;
28571 style->property.edit.color_factor = style->property.edit.disabled_factor;
28572 style->scrollh.color_factor = style->scrollh.disabled_factor;
28573 style->scrollh.inc_button.color_factor_text = style->scrollh.inc_button.disabled_factor;
28574 style->scrollh.inc_button.color_factor_background = style->scrollh.inc_button.disabled_factor;
28575 style->scrollh.dec_button.color_factor_text = style->scrollh.dec_button.disabled_factor;
28576 style->scrollh.dec_button.color_factor_background = style->scrollh.dec_button.disabled_factor;
28577 style->scrollv.color_factor = style->scrollv.disabled_factor;
28578 style->scrollv.inc_button.color_factor_text = style->scrollv.inc_button.disabled_factor;
28579 style->scrollv.inc_button.color_factor_background = style->scrollv.inc_button.disabled_factor;
28580 style->scrollv.dec_button.color_factor_text = style->scrollv.dec_button.disabled_factor;
28581 style->scrollv.dec_button.color_factor_background = style->scrollv.dec_button.disabled_factor;
28582 style->selectable.color_factor = style->selectable.disabled_factor;
28583 style->slider.color_factor = style->slider.disabled_factor;
28584 style->slider.inc_button.color_factor_text = style->slider.inc_button.disabled_factor;
28585 style->slider.inc_button.color_factor_background = style->slider.inc_button.disabled_factor;
28586 style->slider.dec_button.color_factor_text = style->slider.dec_button.disabled_factor;
28587 style->slider.dec_button.color_factor_background = style->slider.dec_button.disabled_factor;
28588 style->tab.color_factor = style->tab.disabled_factor;
28589 style->tab.node_maximize_button.color_factor_text = style->tab.node_maximize_button.disabled_factor;
28590 style->tab.node_minimize_button.color_factor_text = style->tab.node_minimize_button.disabled_factor;
28591 style->tab.tab_maximize_button.color_factor_text = style->tab.tab_maximize_button.disabled_factor;
28592 style->tab.tab_maximize_button.color_factor_background = style->tab.tab_maximize_button.disabled_factor;
28593 style->tab.tab_minimize_button.color_factor_text = style->tab.tab_minimize_button.disabled_factor;
28594 style->tab.tab_minimize_button.color_factor_background = style->tab.tab_minimize_button.disabled_factor;
28595 style->text.color_factor = style->text.disabled_factor;
28608 nk_widget_disable_end(
struct nk_context* ctx)
28614 NK_ASSERT(ctx->current);
28616 if (!ctx || !ctx->current)
28619 win = ctx->current;
28620 style = &ctx->style;
28622 win->widgets_disabled = nk_false;
28624 style->button.color_factor_text = 1.0f;
28625 style->button.color_factor_background = 1.0f;
28626 style->chart.color_factor = 1.0f;
28627 style->checkbox.color_factor = 1.0f;
28628 style->combo.color_factor = 1.0f;
28629 style->combo.button.color_factor_text = 1.0f;
28630 style->combo.button.color_factor_background = 1.0f;
28631 style->contextual_button.color_factor_text = 1.0f;
28632 style->contextual_button.color_factor_background = 1.0f;
28633 style->edit.color_factor = 1.0f;
28634 style->edit.scrollbar.color_factor = 1.0f;
28635 style->menu_button.color_factor_text = 1.0f;
28636 style->menu_button.color_factor_background = 1.0f;
28637 style->option.color_factor = 1.0f;
28638 style->progress.color_factor = 1.0f;
28639 style->property.color_factor = 1.0f;
28640 style->property.inc_button.color_factor_text = 1.0f;
28641 style->property.inc_button.color_factor_background = 1.0f;
28642 style->property.dec_button.color_factor_text = 1.0f;
28643 style->property.dec_button.color_factor_background = 1.0f;
28644 style->property.edit.color_factor = 1.0f;
28645 style->scrollh.color_factor = 1.0f;
28646 style->scrollh.inc_button.color_factor_text = 1.0f;
28647 style->scrollh.inc_button.color_factor_background = 1.0f;
28648 style->scrollh.dec_button.color_factor_text = 1.0f;
28649 style->scrollh.dec_button.color_factor_background = 1.0f;
28650 style->scrollv.color_factor = 1.0f;
28651 style->scrollv.inc_button.color_factor_text = 1.0f;
28652 style->scrollv.inc_button.color_factor_background = 1.0f;
28653 style->scrollv.dec_button.color_factor_text = 1.0f;
28654 style->scrollv.dec_button.color_factor_background = 1.0f;
28655 style->selectable.color_factor = 1.0f;
28656 style->slider.color_factor = 1.0f;
28657 style->slider.inc_button.color_factor_text = 1.0f;
28658 style->slider.inc_button.color_factor_background = 1.0f;
28659 style->slider.dec_button.color_factor_text = 1.0f;
28660 style->slider.dec_button.color_factor_background = 1.0f;
28661 style->tab.color_factor = 1.0f;
28662 style->tab.node_maximize_button.color_factor_text = 1.0f;
28663 style->tab.node_minimize_button.color_factor_text = 1.0f;
28664 style->tab.tab_maximize_button.color_factor_text = 1.0f;
28665 style->tab.tab_maximize_button.color_factor_background = 1.0f;
28666 style->tab.tab_minimize_button.color_factor_text = 1.0f;
28667 style->tab.tab_minimize_button.color_factor_background = 1.0f;
28668 style->text.color_factor = 1.0f;
28692 const char *
string,
int len,
const struct nk_text *t,
28700 if (!o || !t)
return;
28702 b.h = NK_MAX(b.h, 2 * t->padding.y);
28703 label.x = 0; label.w = 0;
28704 label.y = b.y + t->padding.y;
28705 label.h = NK_MIN(f->
height, b.h - 2 * t->padding.y);
28707 text_width = f->
width(f->userdata, f->
height, (
const char*)
string, len);
28708 text_width += (2.0f * t->padding.x);
28711 if (a & NK_TEXT_ALIGN_LEFT) {
28712 label.x = b.x + t->padding.x;
28713 label.w = NK_MAX(0, b.w - 2 * t->padding.x);
28714 }
else if (a & NK_TEXT_ALIGN_CENTERED) {
28715 label.w = NK_MAX(1, 2 * t->padding.x + (
float)text_width);
28716 label.x = (b.x + t->padding.x + ((b.w - 2 * t->padding.x) - label.w) / 2);
28717 label.x = NK_MAX(b.x + t->padding.x, label.x);
28718 label.w = NK_MIN(b.x + b.w, label.x + label.w);
28719 if (label.w >= label.x) label.w -= label.x;
28720 }
else if (a & NK_TEXT_ALIGN_RIGHT) {
28721 label.x = NK_MAX(b.x + t->padding.x, (b.x + b.w) - (2 * t->padding.x + (
float)text_width));
28722 label.w = (float)text_width + 2 * t->padding.x;
28726 if (a & NK_TEXT_ALIGN_MIDDLE) {
28727 label.y = b.y + b.h/2.0f - (float)f->
height/2.0f;
28728 label.h = NK_MAX(b.h/2.0f, b.h - (b.h/2.0f + f->
height/2.0f));
28729 }
else if (a & NK_TEXT_ALIGN_BOTTOM) {
28730 label.y = b.y + b.h - f->
height;
28733 nk_draw_text(o, label, (
const char*)
string, len, f, t->background, t->text);
28748 const char *
string,
int len,
const struct nk_text *t,
28756 struct nk_text text;
28757 NK_INTERN nk_rune seperator[] = {
' '};
28761 if (!o || !t)
return;
28764 text.background = t->background;
28765 text.text = t->text;
28767 b.w = NK_MAX(b.w, 2 * t->padding.x);
28768 b.h = NK_MAX(b.h, 2 * t->padding.y);
28769 b.h = b.h - 2 * t->padding.y;
28771 line.x = b.x + t->padding.x;
28772 line.y = b.y + t->padding.y;
28773 line.w = b.w - 2 * t->padding.x;
28774 line.h = 2 * t->padding.y + f->
height;
28776 fitting = nk_text_clamp(f,
string, len, line.w, &glyphs, &width, seperator,NK_LEN(seperator));
28777 while (done < len) {
28778 if (!fitting || line.y + line.h >= (b.y + b.h))
break;
28779 nk_widget_text(o, line, &
string[done], fitting, &text, NK_TEXT_LEFT, f);
28781 line.y += f->
height + 2 * t->padding.y;
28782 fitting = nk_text_clamp(f, &
string[done], len - done, line.w, &glyphs, &width, seperator,NK_LEN(seperator));
28798 nk_text_colored(
struct nk_context *ctx,
const char *str,
int len,
28799 nk_flags alignment,
struct nk_color color)
28806 struct nk_text text;
28809 NK_ASSERT(ctx->current);
28810 NK_ASSERT(ctx->current->layout);
28811 if (!ctx || !ctx->current || !ctx->current->layout)
return;
28813 win = ctx->current;
28814 style = &ctx->style;
28815 nk_panel_alloc_space(&bounds, ctx);
28816 item_padding = style->text.padding;
28818 text.padding.x = item_padding.x;
28819 text.padding.y = item_padding.y;
28820 text.background = style->window.background;
28821 text.text = nk_rgb_factor(color, style->text.color_factor);
28822 nk_widget_text(&win->buffer, bounds, str, len, &text, alignment, style->font);
28836 nk_text_wrap_colored(
struct nk_context *ctx,
const char *str,
28844 struct nk_text text;
28847 NK_ASSERT(ctx->current);
28848 NK_ASSERT(ctx->current->layout);
28849 if (!ctx || !ctx->current || !ctx->current->layout)
return;
28851 win = ctx->current;
28852 style = &ctx->style;
28853 nk_panel_alloc_space(&bounds, ctx);
28854 item_padding = style->text.padding;
28856 text.padding.x = item_padding.x;
28857 text.padding.y = item_padding.y;
28858 text.background = style->window.background;
28859 text.text = nk_rgb_factor(color, style->text.color_factor);
28860 nk_widget_text_wrap(&win->buffer, bounds, str, len, &text, style->font);
28862 #ifdef NK_INCLUDE_STANDARD_VARARGS
28875 nk_labelf_colored(
struct nk_context *ctx, nk_flags flags,
28876 struct nk_color color,
const char *fmt, ...)
28879 va_start(args, fmt);
28880 nk_labelfv_colored(ctx, flags, color, fmt, args);
28896 const char *fmt, ...)
28899 va_start(args, fmt);
28900 nk_labelfv_colored_wrap(ctx, color, fmt, args);
28916 nk_labelf(
struct nk_context *ctx, nk_flags flags,
const char *fmt, ...)
28919 va_start(args, fmt);
28920 nk_labelfv(ctx, flags, fmt, args);
28935 nk_labelf_wrap(
struct nk_context *ctx,
const char *fmt,...)
28938 va_start(args, fmt);
28939 nk_labelfv_wrap(ctx, fmt, args);
28954 nk_labelfv_colored(
struct nk_context *ctx, nk_flags flags,
28955 struct nk_color color,
const char *fmt, va_list args)
28958 nk_strfmt(buf, NK_LEN(buf), fmt, args);
28959 nk_label_colored(ctx, buf, flags, color);
28975 const char *fmt, va_list args)
28978 nk_strfmt(buf, NK_LEN(buf), fmt, args);
28979 nk_label_colored_wrap(ctx, buf, color);
28996 nk_labelfv(
struct nk_context *ctx, nk_flags flags,
const char *fmt, va_list args)
28999 nk_strfmt(buf, NK_LEN(buf), fmt, args);
29000 nk_label(ctx, buf, flags);
29016 nk_labelfv_wrap(
struct nk_context *ctx,
const char *fmt, va_list args)
29019 nk_strfmt(buf, NK_LEN(buf), fmt, args);
29020 nk_label_wrap(ctx, buf);
29036 nk_value_bool(
struct nk_context *ctx,
const char *prefix,
int value)
29038 nk_labelf(ctx, NK_TEXT_LEFT,
"%s: %s", prefix, ((value) ?
"true":
"false"));
29053 nk_value_int(
struct nk_context *ctx,
const char *prefix,
int value)
29055 nk_labelf(ctx, NK_TEXT_LEFT,
"%s: %d", prefix, value);
29070 nk_value_uint(
struct nk_context *ctx,
const char *prefix,
unsigned int value)
29072 nk_labelf(ctx, NK_TEXT_LEFT,
"%s: %u", prefix, value);
29087 nk_value_float(
struct nk_context *ctx,
const char *prefix,
float value)
29089 double double_value = (double)value;
29090 nk_labelf(ctx, NK_TEXT_LEFT,
"%s: %.3f", prefix, double_value);
29107 nk_labelf(ctx, NK_TEXT_LEFT,
"%s: (%d, %d, %d, %d)", p, c.r, c.g, c.b, c.a);
29124 double c[4]; nk_color_dv(c, color);
29125 nk_labelf(ctx, NK_TEXT_LEFT,
"%s: (%.2f, %.2f, %.2f, %.2f)",
29126 p, c[0], c[1], c[2], c[3]);
29141 nk_value_color_hex(
struct nk_context *ctx,
const char *prefix,
struct nk_color color)
29144 nk_color_hex_rgba(hex, color);
29145 nk_labelf(ctx, NK_TEXT_LEFT,
"%s: %s", prefix, hex);
29162 nk_text(
struct nk_context *ctx,
const char *str,
int len, nk_flags alignment)
29166 nk_text_colored(ctx, str, len, alignment, ctx->style.text.color);
29181 nk_text_wrap(
struct nk_context *ctx,
const char *str,
int len)
29185 nk_text_wrap_colored(ctx, str, len, ctx->style.text.color);
29200 nk_label(
struct nk_context *ctx,
const char *str, nk_flags alignment)
29202 nk_text(ctx, str, nk_strlen(str), alignment);
29217 nk_label_colored(
struct nk_context *ctx,
const char *str, nk_flags align,
29220 nk_text_colored(ctx, str, nk_strlen(str), align, color);
29234 nk_label_wrap(
struct nk_context *ctx,
const char *str)
29236 nk_text_wrap(ctx, str, nk_strlen(str));
29251 nk_label_colored_wrap(
struct nk_context *ctx,
const char *str,
struct nk_color color)
29253 nk_text_wrap_colored(ctx, str, nk_strlen(str), color);
29276 nk_handle_ptr(
void *ptr)
29293 nk_handle_id(
int id)
29296 nk_zero_struct(handle);
29314 nk_subimage_ptr(void *ptr, nk_ushort w, nk_ushort h,
struct nk_rect r)
29317 nk_zero(&s,
sizeof(s));
29318 s.handle.ptr = ptr;
29320 s.region[0] = (nk_ushort)r.x;
29321 s.region[1] = (nk_ushort)r.y;
29322 s.region[2] = (nk_ushort)r.w;
29323 s.region[3] = (nk_ushort)r.h;
29340 nk_subimage_id(int id, nk_ushort w, nk_ushort h, struct
nk_rect r)
29343 nk_zero(&s,
sizeof(s));
29346 s.region[0] = (nk_ushort)r.x;
29347 s.region[1] = (nk_ushort)r.y;
29348 s.region[2] = (nk_ushort)r.w;
29349 s.region[3] = (nk_ushort)r.h;
29366 nk_subimage_handle(
nk_handle handle, nk_ushort w, nk_ushort h, struct
nk_rect r)
29369 nk_zero(&s,
sizeof(s));
29372 s.region[0] = (nk_ushort)r.x;
29373 s.region[1] = (nk_ushort)r.y;
29374 s.region[2] = (nk_ushort)r.w;
29375 s.region[3] = (nk_ushort)r.h;
29392 nk_zero(&s,
sizeof(s));
29412 nk_image_ptr(void *ptr)
29415 nk_zero(&s,
sizeof(s));
29417 s.handle.ptr = ptr;
29436 nk_image_id(int id)
29439 nk_zero(&s,
sizeof(s));
29459 nk_image_is_subimage(
const struct nk_image* img)
29462 return !(img->w == 0 && img->h == 0);
29482 NK_ASSERT(ctx->current);
29483 NK_ASSERT(ctx->current->layout);
29484 if (!ctx || !ctx->current || !ctx->current->layout)
return;
29486 win = ctx->current;
29487 if (!nk_widget(&bounds, ctx))
return;
29509 NK_ASSERT(ctx->current);
29510 NK_ASSERT(ctx->current->layout);
29511 if (!ctx || !ctx->current || !ctx->current->layout)
return;
29513 win = ctx->current;
29514 if (!nk_widget(&bounds, ctx))
return;
29542 nk_sub9slice_ptr(void *ptr, nk_ushort w, nk_ushort h,
struct nk_rect rgn, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b)
29546 nk_zero(&s,
sizeof(s));
29547 i->handle.ptr = ptr;
29548 i->w = w; i->h = h;
29549 i->region[0] = (nk_ushort)rgn.x;
29550 i->region[1] = (nk_ushort)rgn.y;
29551 i->region[2] = (nk_ushort)rgn.w;
29552 i->region[3] = (nk_ushort)rgn.h;
29553 s.l = l; s.t = t; s.r = r; s.b = b;
29572 nk_sub9slice_id(int id, nk_ushort w, nk_ushort h, struct
nk_rect rgn, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b)
29576 nk_zero(&s,
sizeof(s));
29578 i->w = w; i->h = h;
29579 i->region[0] = (nk_ushort)rgn.x;
29580 i->region[1] = (nk_ushort)rgn.y;
29581 i->region[2] = (nk_ushort)rgn.w;
29582 i->region[3] = (nk_ushort)rgn.h;
29583 s.l = l; s.t = t; s.r = r; s.b = b;
29601 nk_sub9slice_handle(
nk_handle handle, nk_ushort w, nk_ushort h, struct
nk_rect rgn, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b)
29605 nk_zero(&s,
sizeof(s));
29606 i->handle = handle;
29607 i->w = w; i->h = h;
29608 i->region[0] = (nk_ushort)rgn.x;
29609 i->region[1] = (nk_ushort)rgn.y;
29610 i->region[2] = (nk_ushort)rgn.w;
29611 i->region[3] = (nk_ushort)rgn.h;
29612 s.l = l; s.t = t; s.r = r; s.b = b;
29630 nk_nine_slice_handle(
nk_handle handle, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b)
29634 nk_zero(&s,
sizeof(s));
29635 i->handle = handle;
29636 i->w = 0; i->h = 0;
29641 s.l = l; s.t = t; s.r = r; s.b = b;
29659 nk_nine_slice_ptr(void *ptr, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b)
29663 nk_zero(&s,
sizeof(s));
29665 i->handle.ptr = ptr;
29666 i->w = 0; i->h = 0;
29671 s.l = l; s.t = t; s.r = r; s.b = b;
29689 nk_nine_slice_id(int id, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b)
29693 nk_zero(&s,
sizeof(s));
29695 i->w = 0; i->h = 0;
29700 s.l = l; s.t = t; s.r = r; s.b = b;
29714 nk_nine_slice_is_sub9slice(
const struct nk_nine_slice* slice)
29717 return !(slice->img.w == 0 && slice->img.h == 0);
29753 case NK_SYMBOL_UNDERSCORE:
29754 case NK_SYMBOL_PLUS:
29755 case NK_SYMBOL_MINUS: {
29757 const char *X = (type == NK_SYMBOL_X) ?
"x":
29758 (type == NK_SYMBOL_UNDERSCORE) ?
"_":
29759 (type == NK_SYMBOL_PLUS) ?
"+":
"-";
29760 struct nk_text text;
29762 text.background = background;
29763 text.text = foreground;
29764 nk_widget_text(out, content, X, 1, &text, NK_TEXT_CENTERED, font);
29766 case NK_SYMBOL_CIRCLE_SOLID:
29767 case NK_SYMBOL_CIRCLE_OUTLINE:
29768 case NK_SYMBOL_RECT_SOLID:
29769 case NK_SYMBOL_RECT_OUTLINE: {
29771 if (type == NK_SYMBOL_RECT_SOLID || type == NK_SYMBOL_RECT_OUTLINE) {
29773 if (type == NK_SYMBOL_RECT_OUTLINE)
29774 nk_fill_rect(out, nk_shrink_rect(content, border_width), 0, background);
29776 nk_fill_circle(out, content, foreground);
29777 if (type == NK_SYMBOL_CIRCLE_OUTLINE)
29778 nk_fill_circle(out, nk_shrink_rect(content, 1), background);
29781 case NK_SYMBOL_TRIANGLE_UP:
29782 case NK_SYMBOL_TRIANGLE_DOWN:
29783 case NK_SYMBOL_TRIANGLE_LEFT:
29784 case NK_SYMBOL_TRIANGLE_RIGHT: {
29785 enum nk_heading heading;
29787 heading = (type == NK_SYMBOL_TRIANGLE_RIGHT) ? NK_RIGHT :
29788 (type == NK_SYMBOL_TRIANGLE_LEFT) ? NK_LEFT:
29789 (type == NK_SYMBOL_TRIANGLE_UP) ? NK_UP: NK_DOWN;
29790 nk_triangle_from_direction(points, content, 0, 0, heading);
29791 nk_fill_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y,
29792 points[2].x, points[2].y, foreground);
29794 case NK_SYMBOL_TRIANGLE_UP_OUTLINE:
29795 case NK_SYMBOL_TRIANGLE_DOWN_OUTLINE:
29796 case NK_SYMBOL_TRIANGLE_LEFT_OUTLINE:
29797 case NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE: {
29798 enum nk_heading heading;
29800 heading = (type == NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE) ? NK_RIGHT :
29801 (type == NK_SYMBOL_TRIANGLE_LEFT_OUTLINE) ? NK_LEFT:
29802 (type == NK_SYMBOL_TRIANGLE_UP_OUTLINE) ? NK_UP: NK_DOWN;
29803 nk_triangle_from_direction(points, content, 0, 0, heading);
29804 nk_stroke_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y,
29805 points[2].x, points[2].y, border_width, foreground);
29808 case NK_SYMBOL_NONE:
29809 case NK_SYMBOL_MAX:
break;
29826 nk_button_behavior(nk_flags *state,
struct nk_rect r,
29827 const struct nk_input *i,
enum nk_button_behavior behavior)
29830 nk_widget_state_reset(state);
29832 if (nk_input_is_mouse_hovering_rect(i, r)) {
29834 if (nk_input_is_mouse_down(i, NK_BUTTON_LEFT))
29836 if (nk_input_has_mouse_click_in_button_rect(i, NK_BUTTON_LEFT, r)) {
29837 ret = (behavior != NK_BUTTON_DEFAULT) ?
29838 nk_input_is_mouse_down(i, NK_BUTTON_LEFT):
29839 #ifdef NK_BUTTON_TRIGGER_ON_RELEASE
29840 nk_input_is_mouse_released(i, NK_BUTTON_LEFT);
29842 nk_input_is_mouse_pressed(i, NK_BUTTON_LEFT);
29848 else if (nk_input_is_mouse_prev_hovering_rect(i, r))
29870 const struct nk_rect *bounds, nk_flags state,
29875 background = &style->hover;
29877 background = &style->active;
29878 else background = &style->normal;
29880 switch (background->type) {
29881 case NK_STYLE_ITEM_IMAGE:
29882 nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor_background));
29884 case NK_STYLE_ITEM_NINE_SLICE:
29885 nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor_background));
29887 case NK_STYLE_ITEM_COLOR:
29888 nk_fill_rect(out, *bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor_background));
29889 nk_stroke_rect(out, *bounds, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor_background));
29913 enum nk_button_behavior behavior,
struct nk_rect *content)
29919 if (!out || !style)
29923 content->x = r.x + style->padding.x + style->border + style->rounding;
29924 content->y = r.y + style->padding.y + style->border + style->rounding;
29925 content->w = r.w - (2 * (style->padding.x + style->border + style->rounding));
29926 content->h = r.h - (2 * (style->padding.y + style->border + style->rounding));
29929 bounds.x = r.x - style->touch_padding.x;
29930 bounds.y = r.y - style->touch_padding.y;
29931 bounds.w = r.w + 2 * style->touch_padding.x;
29932 bounds.h = r.h + 2 * style->touch_padding.y;
29933 return nk_button_behavior(state, bounds, in, behavior);
29953 const struct nk_rect *bounds,
const struct nk_rect *content, nk_flags state,
29955 nk_flags text_alignment,
const struct nk_user_font *font)
29957 struct nk_text text;
29959 background = nk_draw_button(out, bounds, state, style);
29962 if (background->type == NK_STYLE_ITEM_COLOR)
29963 text.background = background->data.color;
29964 else text.background = style->text_background;
29966 text.text = style->text_hover;
29968 text.text = style->text_active;
29969 else text.text = style->text_normal;
29971 text.text = nk_rgb_factor(text.text, style->color_factor_text);
29974 nk_widget_text(out, *content, txt, len, &text, text_alignment, font);
29993 nk_do_button_text(nk_flags *state,
29995 const char *
string,
int len, nk_flags align,
enum nk_button_behavior behavior,
30000 int ret = nk_false;
30007 if (!out || !style || !font || !
string)
30010 ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
30011 if (style->draw_begin) style->draw_begin(out, style->userdata);
30012 nk_draw_button_text(out, &bounds, &content, *state, style,
string, len, align, font);
30013 if (style->draw_end) style->draw_end(out, style->userdata);
30036 enum nk_symbol_type type,
const struct nk_user_font *font)
30042 background = nk_draw_button(out, bounds, state, style);
30043 if (background->type == NK_STYLE_ITEM_COLOR)
30044 bg = background->data.color;
30045 else bg = style->text_background;
30048 sym = style->text_hover;
30050 sym = style->text_active;
30051 else sym = style->text_normal;
30053 sym = nk_rgb_factor(sym, style->color_factor_text);
30054 nk_draw_symbol(out, type, *content, bg, sym, 1, font);
30073 nk_do_button_symbol(nk_flags *state,
30075 enum nk_symbol_type symbol,
enum nk_button_behavior behavior,
30086 if (!out || !style || !font || !state)
30089 ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
30090 if (style->draw_begin) style->draw_begin(out, style->userdata);
30091 nk_draw_button_symbol(out, &bounds, &content, *state, style, symbol, font);
30092 if (style->draw_end) style->draw_end(out, style->userdata);
30116 nk_draw_button(out, bounds, state, style);
30117 nk_draw_image(out, *content, img, nk_rgb_factor(nk_white, style->color_factor_background));
30136 nk_do_button_image(nk_flags *state,
30138 struct nk_image img,
enum nk_button_behavior b,
30147 if (!out || !style || !state)
30150 ret = nk_do_button(state, out, bounds, style, in, b, &content);
30151 content.x += style->image_padding.x;
30152 content.y += style->image_padding.y;
30153 content.w -= 2 * style->image_padding.x;
30154 content.h -= 2 * style->image_padding.y;
30156 if (style->draw_begin) style->draw_begin(out, style->userdata);
30157 nk_draw_button_image(out, &bounds, &content, *state, style, &img);
30158 if (style->draw_end) style->draw_end(out, style->userdata);
30181 const char *str,
int len,
enum nk_symbol_type type,
30185 struct nk_text text;
30189 background = nk_draw_button(out, bounds, state, style);
30190 if (background->type == NK_STYLE_ITEM_COLOR)
30191 text.background = background->data.color;
30192 else text.background = style->text_background;
30196 sym = style->text_hover;
30197 text.text = style->text_hover;
30199 sym = style->text_active;
30200 text.text = style->text_active;
30202 sym = style->text_normal;
30203 text.text = style->text_normal;
30206 sym = nk_rgb_factor(sym, style->color_factor_text);
30207 text.text = nk_rgb_factor(text.text, style->color_factor_text);
30209 nk_draw_symbol(out, type, *symbol, style->text_background, sym, 0, font);
30210 nk_widget_text(out, *label, str, len, &text, NK_TEXT_CENTERED, font);
30229 nk_do_button_text_symbol(nk_flags *state,
30231 enum nk_symbol_type symbol,
const char *str,
int len, nk_flags align,
30232 enum nk_button_behavior behavior,
const struct nk_style_button *style,
30236 struct nk_rect tri = {0,0,0,0};
30242 if (!out || !style || !font)
30245 ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
30246 tri.y = content.y + (content.h/2) - font->
height/2;
30248 if (align & NK_TEXT_ALIGN_LEFT) {
30249 tri.x = (content.x + content.w) - (2 * style->padding.x + tri.w);
30250 tri.x = NK_MAX(tri.x, 0);
30251 }
else tri.x = content.x + 2 * style->padding.x;
30254 if (style->draw_begin) style->draw_begin(out, style->userdata);
30255 nk_draw_button_text_symbol(out, &bounds, &content, &tri,
30256 *state, style, str, len, symbol, font);
30257 if (style->draw_end) style->draw_end(out, style->userdata);
30280 const char *str,
int len,
const struct nk_user_font *font,
30283 struct nk_text text;
30285 background = nk_draw_button(out, bounds, state, style);
30288 if (background->type == NK_STYLE_ITEM_COLOR)
30289 text.background = background->data.color;
30290 else text.background = style->text_background;
30292 text.text = style->text_hover;
30294 text.text = style->text_active;
30295 else text.text = style->text_normal;
30297 text.text = nk_rgb_factor(text.text, style->color_factor_text);
30298 text.padding =
nk_vec2(0, 0);
30299 nk_widget_text(out, *label, str, len, &text, NK_TEXT_CENTERED, font);
30300 nk_draw_image(out, *image, img, nk_rgb_factor(nk_white, style->color_factor_background));
30319 nk_do_button_text_image(nk_flags *state,
30321 struct nk_image img,
const char* str,
int len, nk_flags align,
30322 enum nk_button_behavior behavior,
const struct nk_style_button *style,
30333 if (!out || !font || !style || !str)
30336 ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
30337 icon.y = bounds.y + style->padding.y;
30338 icon.w = icon.h = bounds.h - 2 * style->padding.y;
30339 if (align & NK_TEXT_ALIGN_LEFT) {
30340 icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w);
30341 icon.x = NK_MAX(icon.x, 0);
30342 }
else icon.x = bounds.x + 2 * style->padding.x;
30344 icon.x += style->image_padding.x;
30345 icon.y += style->image_padding.y;
30346 icon.w -= 2 * style->image_padding.x;
30347 icon.h -= 2 * style->image_padding.y;
30349 if (style->draw_begin) style->draw_begin(out, style->userdata);
30350 nk_draw_button_text_image(out, &bounds, &content, &icon, *state, style, str, len, font, &img);
30351 if (style->draw_end) style->draw_end(out, style->userdata);
30371 nk_button_set_behavior(
struct nk_context *ctx,
enum nk_button_behavior behavior)
30375 ctx->button_behavior = behavior;
30394 nk_button_push_behavior(
struct nk_context *ctx,
enum nk_button_behavior behavior)
30396 struct nk_config_stack_button_behavior *button_stack;
30397 struct nk_config_stack_button_behavior_element *element;
30400 if (!ctx)
return 0;
30402 button_stack = &ctx->stacks.button_behaviors;
30403 NK_ASSERT(button_stack->head < (
int)NK_LEN(button_stack->elements));
30404 if (button_stack->head >= (
int)NK_LEN(button_stack->elements))
30407 element = &button_stack->elements[button_stack->head++];
30408 element->address = &ctx->button_behavior;
30409 element->old_value = ctx->button_behavior;
30410 ctx->button_behavior = behavior;
30430 nk_button_pop_behavior(
struct nk_context *ctx)
30432 struct nk_config_stack_button_behavior *button_stack;
30433 struct nk_config_stack_button_behavior_element *element;
30436 if (!ctx)
return 0;
30438 button_stack = &ctx->stacks.button_behaviors;
30439 NK_ASSERT(button_stack->head > 0);
30440 if (button_stack->head < 1)
30443 element = &button_stack->elements[--button_stack->head];
30444 *element->address = element->old_value;
30464 nk_button_text_styled(
struct nk_context *ctx,
30476 NK_ASSERT(ctx->current);
30477 NK_ASSERT(ctx->current->layout);
30478 if (!style || !ctx || !ctx->current || !ctx->current->layout)
return 0;
30480 win = ctx->current;
30481 layout = win->layout;
30482 state = nk_widget(&bounds, ctx);
30484 if (!state)
return 0;
30486 return nk_do_button_text(&ctx->last_widget_state, &win->buffer, bounds,
30487 title, len, style->text_alignment, ctx->button_behavior,
30488 style, in, ctx->style.font);
30507 nk_button_text(
struct nk_context *ctx,
const char *title,
int len)
30510 if (!ctx)
return 0;
30511 return nk_button_text_styled(ctx, &ctx->style.button, title, len);
30529 NK_API nk_bool nk_button_label_styled(
struct nk_context *ctx,
30532 return nk_button_text_styled(ctx, style, title, nk_strlen(title));
30550 NK_API nk_bool nk_button_label(
struct nk_context *ctx,
const char *title)
30552 return nk_button_text(ctx, title, nk_strlen(title));
30584 NK_ASSERT(ctx->current);
30585 NK_ASSERT(ctx->current->layout);
30586 if (!ctx || !ctx->current || !ctx->current->layout)
30589 win = ctx->current;
30590 layout = win->layout;
30592 state = nk_widget(&bounds, ctx);
30593 if (!state)
return 0;
30596 button = ctx->style.button;
30597 button.normal = nk_style_item_color(color);
30598 button.hover = nk_style_item_color(color);
30599 button.active = nk_style_item_color(color);
30600 ret = nk_do_button(&ctx->last_widget_state, &win->buffer, bounds,
30601 &button, in, ctx->button_behavior, &content);
30602 nk_draw_button(&win->buffer, &bounds, ctx->last_widget_state, &button);
30622 nk_button_symbol_styled(
struct nk_context *ctx,
30633 NK_ASSERT(ctx->current);
30634 NK_ASSERT(ctx->current->layout);
30635 if (!ctx || !ctx->current || !ctx->current->layout)
30638 win = ctx->current;
30639 layout = win->layout;
30640 state = nk_widget(&bounds, ctx);
30641 if (!state)
return 0;
30643 return nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, bounds,
30644 symbol, ctx->button_behavior, style, in, ctx->style.font);
30663 nk_button_symbol(
struct nk_context *ctx,
enum nk_symbol_type symbol)
30666 if (!ctx)
return 0;
30667 return nk_button_symbol_styled(ctx, &ctx->style.button, symbol);
30697 NK_ASSERT(ctx->current);
30698 NK_ASSERT(ctx->current->layout);
30699 if (!ctx || !ctx->current || !ctx->current->layout)
30702 win = ctx->current;
30703 layout = win->layout;
30705 state = nk_widget(&bounds, ctx);
30706 if (!state)
return 0;
30708 return nk_do_button_image(&ctx->last_widget_state, &win->buffer, bounds,
30709 img, ctx->button_behavior, style, in);
30731 if (!ctx)
return 0;
30732 return nk_button_image_styled(ctx, &ctx->style.button, img);
30751 nk_button_symbol_text_styled(
struct nk_context *ctx,
30753 const char *text,
int len, nk_flags align)
30763 NK_ASSERT(ctx->current);
30764 NK_ASSERT(ctx->current->layout);
30765 if (!ctx || !ctx->current || !ctx->current->layout)
30768 win = ctx->current;
30769 layout = win->layout;
30771 state = nk_widget(&bounds, ctx);
30772 if (!state)
return 0;
30774 return nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, bounds,
30775 symbol, text, len, align, ctx->button_behavior,
30776 style, ctx->style.font, in);
30795 nk_button_symbol_text(
struct nk_context *ctx,
enum nk_symbol_type symbol,
30796 const char* text,
int len, nk_flags align)
30799 if (!ctx)
return 0;
30800 return nk_button_symbol_text_styled(ctx, &ctx->style.button, symbol, text, len, align);
30818 NK_API nk_bool nk_button_symbol_label(
struct nk_context *ctx,
enum nk_symbol_type symbol,
30819 const char *label, nk_flags align)
30821 return nk_button_symbol_text(ctx, symbol, label, nk_strlen(label), align);
30839 NK_API nk_bool nk_button_symbol_label_styled(
struct nk_context *ctx,
30841 const char *title, nk_flags align)
30843 return nk_button_symbol_text_styled(ctx, style, symbol, title, nk_strlen(title), align);
30862 nk_button_image_text_styled(
struct nk_context *ctx,
30864 int len, nk_flags align)
30874 NK_ASSERT(ctx->current);
30875 NK_ASSERT(ctx->current->layout);
30876 if (!ctx || !ctx->current || !ctx->current->layout)
30879 win = ctx->current;
30880 layout = win->layout;
30882 state = nk_widget(&bounds, ctx);
30883 if (!state)
return 0;
30885 return nk_do_button_text_image(&ctx->last_widget_state, &win->buffer,
30886 bounds, img, text, len, align, ctx->button_behavior,
30887 style, ctx->style.font, in);
30907 const char *text,
int len, nk_flags align)
30909 return nk_button_image_text_styled(ctx, &ctx->style.button,img, text, len, align);
30928 const char *label, nk_flags align)
30930 return nk_button_image_text(ctx, img, label, nk_strlen(label), align);
30948 NK_API nk_bool nk_button_image_label_styled(
struct nk_context *ctx,
30950 const char *label, nk_flags text_alignment)
30952 return nk_button_image_text_styled(ctx, style, img, label, nk_strlen(label), text_alignment);
30977 nk_flags *state, nk_bool active)
30979 nk_widget_state_reset(state);
30980 if (nk_button_behavior(state, select, in, NK_BUTTON_DEFAULT)) {
30986 else if (nk_input_is_mouse_prev_hovering_rect(in, select))
31004 const struct nk_rect *cursors,
const char *
string,
int len,
31005 const struct nk_user_font *font, nk_flags text_alignment)
31009 struct nk_text text;
31013 background = &style->hover;
31014 cursor = &style->cursor_hover;
31015 text.text = style->text_hover;
31017 background = &style->hover;
31018 cursor = &style->cursor_hover;
31019 text.text = style->text_active;
31021 background = &style->normal;
31022 cursor = &style->cursor_normal;
31023 text.text = style->text_normal;
31026 text.text = nk_rgb_factor(text.text, style->color_factor);
31027 text.padding.x = 0;
31028 text.padding.y = 0;
31029 text.background = style->text_background;
31030 nk_widget_text(out, *label,
string, len, &text, text_alignment, font);
31033 if (background->type == NK_STYLE_ITEM_COLOR) {
31034 nk_fill_rect(out, *selector, 0, nk_rgb_factor(style->border_color, style->color_factor));
31035 nk_fill_rect(out, nk_shrink_rect(*selector, style->border), 0, nk_rgb_factor(background->data.color, style->color_factor));
31036 }
else nk_draw_image(out, *selector, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
31038 if (cursor->type == NK_STYLE_ITEM_IMAGE)
31039 nk_draw_image(out, *cursors, &cursor->data.image, nk_rgb_factor(nk_white, style->color_factor));
31040 else nk_fill_rect(out, *cursors, 0, cursor->data.color);
31057 const struct nk_rect *cursors,
const char *
string,
int len,
31058 const struct nk_user_font *font, nk_flags text_alignment)
31062 struct nk_text text;
31066 background = &style->hover;
31067 cursor = &style->cursor_hover;
31068 text.text = style->text_hover;
31070 background = &style->hover;
31071 cursor = &style->cursor_hover;
31072 text.text = style->text_active;
31074 background = &style->normal;
31075 cursor = &style->cursor_normal;
31076 text.text = style->text_normal;
31079 text.text = nk_rgb_factor(text.text, style->color_factor);
31080 text.padding.x = 0;
31081 text.padding.y = 0;
31082 text.background = style->text_background;
31083 nk_widget_text(out, *label,
string, len, &text, text_alignment, font);
31086 if (background->type == NK_STYLE_ITEM_COLOR) {
31087 nk_fill_circle(out, *selector, nk_rgb_factor(style->border_color, style->color_factor));
31088 nk_fill_circle(out, nk_shrink_rect(*selector, style->border), nk_rgb_factor(background->data.color, style->color_factor));
31089 }
else nk_draw_image(out, *selector, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
31091 if (cursor->type == NK_STYLE_ITEM_IMAGE)
31092 nk_draw_image(out, *cursors, &cursor->data.image, nk_rgb_factor(nk_white, style->color_factor));
31093 else nk_fill_circle(out, *cursors, cursor->data.color);
31107 nk_do_toggle(nk_flags *state,
31109 nk_bool *active,
const char *str,
int len,
enum nk_toggle_type type,
31111 const struct nk_user_font *font, nk_flags widget_alignment, nk_flags text_alignment)
31122 if (!out || !style || !font || !active)
31125 r.w = NK_MAX(r.w, font->
height + 2 * style->padding.x);
31126 r.h = NK_MAX(r.h, font->
height + 2 * style->padding.y);
31129 bounds.x = r.x - style->touch_padding.x;
31130 bounds.y = r.y - style->touch_padding.y;
31131 bounds.w = r.w + 2 * style->touch_padding.x;
31132 bounds.h = r.h + 2 * style->touch_padding.y;
31135 select.w = font->
height;
31136 select.h = select.w;
31138 if (widget_alignment & NK_WIDGET_ALIGN_RIGHT) {
31139 select.x = r.x + r.w - font->
height;
31143 label.w = r.w - select.w - style->spacing * 2;
31144 }
else if (widget_alignment & NK_WIDGET_ALIGN_CENTERED) {
31145 select.x = r.x + (r.w - select.w) / 2;
31149 label.w = (r.w - select.w - style->spacing * 2) / 2;
31154 label.x = select.x + select.w + style->spacing;
31155 label.w = NK_MAX(r.x + r.w, label.x) - label.x;
31158 if (widget_alignment & NK_WIDGET_ALIGN_TOP) {
31160 }
else if (widget_alignment & NK_WIDGET_ALIGN_BOTTOM) {
31161 select.y = r.y + r.h - select.h - 2 * style->padding.y;
31163 select.y = r.y + r.h/2.0f - select.h/2.0f;
31166 label.y = select.y;
31167 label.h = select.w;
31170 cursor.x = select.x + style->padding.x + style->border;
31171 cursor.y = select.y + style->padding.y + style->border;
31172 cursor.w = select.w - (2 * style->padding.x + 2 * style->border);
31173 cursor.h = select.h - (2 * style->padding.y + 2 * style->border);
31176 was_active = *active;
31177 *active = nk_toggle_behavior(in, bounds, state, *active);
31180 if (style->draw_begin)
31181 style->draw_begin(out, style->userdata);
31182 if (type == NK_TOGGLE_CHECK) {
31183 nk_draw_checkbox(out, *state, style, *active, &label, &select, &cursor, str, len, font, text_alignment);
31185 nk_draw_option(out, *state, style, *active, &label, &select, &cursor, str, len, font, text_alignment);
31187 if (style->draw_end)
31188 style->draw_end(out, style->userdata);
31189 return (was_active != *active);
31210 nk_check_text(
struct nk_context *ctx,
const char *text,
int len, nk_bool active)
31221 NK_ASSERT(ctx->current);
31222 NK_ASSERT(ctx->current->layout);
31223 if (!ctx || !ctx->current || !ctx->current->layout)
31226 win = ctx->current;
31227 style = &ctx->style;
31228 layout = win->layout;
31230 state = nk_widget(&bounds, ctx);
31231 if (!state)
return active;
31233 nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &active,
31234 text, len, NK_TOGGLE_CHECK, &style->checkbox, in, style->font, NK_WIDGET_LEFT, NK_TEXT_LEFT);
31251 nk_check_text_align(
struct nk_context *ctx,
const char *text,
int len, nk_bool active, nk_flags widget_alignment, nk_flags text_alignment)
31262 NK_ASSERT(ctx->current);
31263 NK_ASSERT(ctx->current->layout);
31264 if (!ctx || !ctx->current || !ctx->current->layout)
31267 win = ctx->current;
31268 style = &ctx->style;
31269 layout = win->layout;
31271 state = nk_widget(&bounds, ctx);
31272 if (!state)
return active;
31274 nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &active,
31275 text, len, NK_TOGGLE_CHECK, &style->checkbox, in, style->font, widget_alignment, text_alignment);
31290 NK_API
unsigned int
31291 nk_check_flags_text(
struct nk_context *ctx,
const char *text,
int len,
31292 unsigned int flags,
unsigned int value)
31297 if (!ctx || !text)
return flags;
31298 old_active = (int)((flags & value) & value);
31299 if (nk_check_text(ctx, text, len, old_active))
31301 else flags &= ~value;
31318 nk_checkbox_text(
struct nk_context *ctx,
const char *text,
int len, nk_bool *active)
31324 if (!ctx || !text || !active)
return 0;
31326 *active = nk_check_text(ctx, text, len, *active);
31327 return old_val != *active;
31343 nk_checkbox_text_align(
struct nk_context *ctx,
const char *text,
int len, nk_bool *active, nk_flags widget_alignment, nk_flags text_alignment)
31349 if (!ctx || !text || !active)
return 0;
31351 *active = nk_check_text_align(ctx, text, len, *active, widget_alignment, text_alignment);
31352 return old_val != *active;
31367 nk_checkbox_flags_text(
struct nk_context *ctx,
const char *text,
int len,
31368 unsigned int *flags,
unsigned int value)
31374 if (!ctx || !text || !flags)
return 0;
31376 active = (int)((*flags & value) & value);
31377 if (nk_checkbox_text(ctx, text, len, &active)) {
31378 if (active) *flags |= value;
31379 else *flags &= ~value;
31396 NK_API nk_bool nk_check_label(
struct nk_context *ctx,
const char *label, nk_bool active)
31398 return nk_check_text(ctx, label, nk_strlen(label), active);
31411 NK_API
unsigned int nk_check_flags_label(
struct nk_context *ctx,
const char *label,
31412 unsigned int flags,
unsigned int value)
31414 return nk_check_flags_text(ctx, label, nk_strlen(label), flags, value);
31428 NK_API nk_bool nk_checkbox_label(
struct nk_context *ctx,
const char *label, nk_bool *active)
31430 return nk_checkbox_text(ctx, label, nk_strlen(label), active);
31443 NK_API nk_bool nk_checkbox_label_align(
struct nk_context *ctx,
const char *label, nk_bool *active, nk_flags widget_alignment, nk_flags text_alignment)
31445 return nk_checkbox_text_align(ctx, label, nk_strlen(label), active, widget_alignment, text_alignment);
31458 NK_API nk_bool nk_checkbox_flags_label(
struct nk_context *ctx,
const char *label,
31459 unsigned int *flags,
unsigned int value)
31461 return nk_checkbox_flags_text(ctx, label, nk_strlen(label), flags, value);
31482 nk_option_text(
struct nk_context *ctx,
const char *text,
int len, nk_bool is_active)
31493 NK_ASSERT(ctx->current);
31494 NK_ASSERT(ctx->current->layout);
31495 if (!ctx || !ctx->current || !ctx->current->layout)
31498 win = ctx->current;
31499 style = &ctx->style;
31500 layout = win->layout;
31502 state = nk_widget(&bounds, ctx);
31503 if (!state)
return (
int)state;
31505 nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &is_active,
31506 text, len, NK_TOGGLE_OPTION, &style->option, in, style->font, NK_WIDGET_LEFT, NK_TEXT_LEFT);
31523 nk_option_text_align(
struct nk_context *ctx,
const char *text,
int len, nk_bool is_active, nk_flags widget_alignment, nk_flags text_alignment)
31534 NK_ASSERT(ctx->current);
31535 NK_ASSERT(ctx->current->layout);
31536 if (!ctx || !ctx->current || !ctx->current->layout)
31539 win = ctx->current;
31540 style = &ctx->style;
31541 layout = win->layout;
31543 state = nk_widget(&bounds, ctx);
31544 if (!state)
return (
int)state;
31546 nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &is_active,
31547 text, len, NK_TOGGLE_OPTION, &style->option, in, style->font, widget_alignment, text_alignment);
31564 nk_radio_text(
struct nk_context *ctx,
const char *text,
int len, nk_bool *active)
31570 if (!ctx || !text || !active)
return 0;
31571 old_value = *active;
31572 *active = nk_option_text(ctx, text, len, old_value);
31573 return old_value != *active;
31589 nk_radio_text_align(
struct nk_context *ctx,
const char *text,
int len, nk_bool *active, nk_flags widget_alignment, nk_flags text_alignment)
31595 if (!ctx || !text || !active)
return 0;
31596 old_value = *active;
31597 *active = nk_option_text_align(ctx, text, len, old_value, widget_alignment, text_alignment);
31598 return old_value != *active;
31613 nk_option_label(
struct nk_context *ctx,
const char *label, nk_bool active)
31615 return nk_option_text(ctx, label, nk_strlen(label), active);
31630 nk_option_label_align(
struct nk_context *ctx,
const char *label, nk_bool active, nk_flags widget_alignment, nk_flags text_alignment)
31632 return nk_option_text_align(ctx, label, nk_strlen(label), active, widget_alignment, text_alignment);
31647 nk_radio_label(
struct nk_context *ctx,
const char *label, nk_bool *active)
31649 return nk_radio_text(ctx, label, nk_strlen(label), active);
31664 nk_radio_label_align(
struct nk_context *ctx,
const char *label, nk_bool *active, nk_flags widget_alignment, nk_flags text_alignment)
31666 return nk_radio_text_align(ctx, label, nk_strlen(label), active, widget_alignment, text_alignment);
31691 const struct nk_rect *bounds,
31692 const struct nk_rect *icon,
const struct nk_image *img,
enum nk_symbol_type sym,
31693 const char *
string,
int len, nk_flags align,
const struct nk_user_font *font)
31696 struct nk_text text;
31697 text.padding = style->padding;
31702 background = &style->pressed;
31703 text.text = style->text_pressed;
31705 background = &style->hover;
31706 text.text = style->text_hover;
31708 background = &style->normal;
31709 text.text = style->text_normal;
31713 background = &style->pressed_active;
31714 text.text = style->text_pressed_active;
31716 background = &style->hover_active;
31717 text.text = style->text_hover_active;
31719 background = &style->normal_active;
31720 text.text = style->text_normal_active;
31724 text.text = nk_rgb_factor(text.text, style->color_factor);
31727 switch (background->type) {
31728 case NK_STYLE_ITEM_IMAGE:
31729 text.background = nk_rgba(0, 0, 0, 0);
31730 nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
31732 case NK_STYLE_ITEM_NINE_SLICE:
31733 text.background = nk_rgba(0, 0, 0, 0);
31734 nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor));
31736 case NK_STYLE_ITEM_COLOR:
31737 text.background = background->data.color;
31738 nk_fill_rect(out, *bounds, style->rounding, background->data.color);
31742 if (img)
nk_draw_image(out, *icon, img, nk_rgb_factor(nk_white, style->color_factor));
31743 else nk_draw_symbol(out, sym, *icon, text.background, text.text, 1, font);
31745 nk_widget_text(out, *bounds,
string, len, &text, align, font);
31760 struct nk_rect bounds,
const char *str,
int len, nk_flags align, nk_bool *value,
31775 if (!state || !out || !str || !len || !value || !style || !font)
return 0;
31776 old_value = *value;
31779 touch.x = bounds.x - style->touch_padding.x;
31780 touch.y = bounds.y - style->touch_padding.y;
31781 touch.w = bounds.w + style->touch_padding.x * 2;
31782 touch.h = bounds.h + style->touch_padding.y * 2;
31785 if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT))
31786 *value = !(*value);
31789 if (style->draw_begin) style->draw_begin(out, style->userdata);
31790 nk_draw_selectable(out, *state, style, *value, &bounds, 0,0,NK_SYMBOL_NONE, str, len, align, font);
31791 if (style->draw_end) style->draw_end(out, style->userdata);
31792 return old_value != *value;
31807 struct nk_rect bounds,
const char *str,
int len, nk_flags align, nk_bool *value,
31823 if (!state || !out || !str || !len || !value || !style || !font)
return 0;
31824 old_value = *value;
31827 touch.x = bounds.x - style->touch_padding.x;
31828 touch.y = bounds.y - style->touch_padding.y;
31829 touch.w = bounds.w + style->touch_padding.x * 2;
31830 touch.h = bounds.h + style->touch_padding.y * 2;
31831 if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT))
31832 *value = !(*value);
31834 icon.y = bounds.y + style->padding.y;
31835 icon.w = icon.h = bounds.h - 2 * style->padding.y;
31836 if (align & NK_TEXT_ALIGN_LEFT) {
31837 icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w);
31838 icon.x = NK_MAX(icon.x, 0);
31839 }
else icon.x = bounds.x + 2 * style->padding.x;
31841 icon.x += style->image_padding.x;
31842 icon.y += style->image_padding.y;
31843 icon.w -= 2 * style->image_padding.x;
31844 icon.h -= 2 * style->image_padding.y;
31847 if (style->draw_begin) style->draw_begin(out, style->userdata);
31848 nk_draw_selectable(out, *state, style, *value, &bounds, &icon, img, NK_SYMBOL_NONE, str, len, align, font);
31849 if (style->draw_end) style->draw_end(out, style->userdata);
31850 return old_value != *value;
31865 struct nk_rect bounds,
const char *str,
int len, nk_flags align, nk_bool *value,
31881 if (!state || !out || !str || !len || !value || !style || !font)
return 0;
31882 old_value = *value;
31885 touch.x = bounds.x - style->touch_padding.x;
31886 touch.y = bounds.y - style->touch_padding.y;
31887 touch.w = bounds.w + style->touch_padding.x * 2;
31888 touch.h = bounds.h + style->touch_padding.y * 2;
31889 if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT))
31890 *value = !(*value);
31892 icon.y = bounds.y + style->padding.y;
31893 icon.w = icon.h = bounds.h - 2 * style->padding.y;
31894 if (align & NK_TEXT_ALIGN_LEFT) {
31895 icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w);
31896 icon.x = NK_MAX(icon.x, 0);
31897 }
else icon.x = bounds.x + 2 * style->padding.x;
31899 icon.x += style->image_padding.x;
31900 icon.y += style->image_padding.y;
31901 icon.w -= 2 * style->image_padding.x;
31902 icon.h -= 2 * style->image_padding.y;
31905 if (style->draw_begin) style->draw_begin(out, style->userdata);
31906 nk_draw_selectable(out, *state, style, *value, &bounds, &icon, 0, sym, str, len, align, font);
31907 if (style->draw_end) style->draw_end(out, style->userdata);
31908 return old_value != *value;
31924 nk_selectable_text(
struct nk_context *ctx,
const char *str,
int len,
31925 nk_flags align, nk_bool *value)
31937 NK_ASSERT(ctx->current);
31938 NK_ASSERT(ctx->current->layout);
31939 if (!ctx || !ctx->current || !ctx->current->layout || !value)
31942 win = ctx->current;
31943 layout = win->layout;
31944 style = &ctx->style;
31946 state = nk_widget(&bounds, ctx);
31947 if (!state)
return 0;
31949 return nk_do_selectable(&ctx->last_widget_state, &win->buffer, bounds,
31950 str, len, align, value, &style->selectable, in, style->font);
31965 const char *str,
int len, nk_flags align, nk_bool *value)
31977 NK_ASSERT(ctx->current);
31978 NK_ASSERT(ctx->current->layout);
31979 if (!ctx || !ctx->current || !ctx->current->layout || !value)
31982 win = ctx->current;
31983 layout = win->layout;
31984 style = &ctx->style;
31986 state = nk_widget(&bounds, ctx);
31987 if (!state)
return 0;
31989 return nk_do_selectable_image(&ctx->last_widget_state, &win->buffer, bounds,
31990 str, len, align, value, &img, &style->selectable, in, style->font);
32004 nk_selectable_symbol_text(
struct nk_context *ctx,
enum nk_symbol_type sym,
32005 const char *str,
int len, nk_flags align, nk_bool *value)
32017 NK_ASSERT(ctx->current);
32018 NK_ASSERT(ctx->current->layout);
32019 if (!ctx || !ctx->current || !ctx->current->layout || !value)
32022 win = ctx->current;
32023 layout = win->layout;
32024 style = &ctx->style;
32026 state = nk_widget(&bounds, ctx);
32027 if (!state)
return 0;
32029 return nk_do_selectable_symbol(&ctx->last_widget_state, &win->buffer, bounds,
32030 str, len, align, value, sym, &style->selectable, in, style->font);
32044 nk_selectable_symbol_label(
struct nk_context *ctx,
enum nk_symbol_type sym,
32045 const char *title, nk_flags align, nk_bool *value)
32047 return nk_selectable_symbol_text(ctx, sym, title, nk_strlen(title), align, value);
32061 NK_API nk_bool nk_select_text(
struct nk_context *ctx,
const char *str,
int len,
32062 nk_flags align, nk_bool value)
32064 nk_selectable_text(ctx, str, len, align, &value);
return value;
32078 NK_API nk_bool nk_selectable_label(
struct nk_context *ctx,
const char *str, nk_flags align, nk_bool *value)
32080 return nk_selectable_text(ctx, str, nk_strlen(str), align, value);
32093 NK_API nk_bool nk_selectable_image_label(
struct nk_context *ctx,
struct nk_image img,
32094 const char *str, nk_flags align, nk_bool *value)
32096 return nk_selectable_image_text(ctx, img, str, nk_strlen(str), align, value);
32110 NK_API nk_bool nk_select_label(
struct nk_context *ctx,
const char *str, nk_flags align, nk_bool value)
32112 nk_selectable_text(ctx, str, nk_strlen(str), align, &value);
return value;
32126 const char *str, nk_flags align, nk_bool value)
32128 nk_selectable_image_text(ctx, img, str, nk_strlen(str), align, &value);
return value;
32142 const char *str,
int len, nk_flags align, nk_bool value)
32144 nk_selectable_image_text(ctx, img, str, len, align, &value);
return value;
32158 nk_select_symbol_text(
struct nk_context *ctx,
enum nk_symbol_type sym,
32159 const char *title,
int title_len, nk_flags align, nk_bool value)
32161 nk_selectable_symbol_text(ctx, sym, title, title_len, align, &value);
return value;
32175 nk_select_symbol_label(
struct nk_context *ctx,
enum nk_symbol_type sym,
32176 const char *title, nk_flags align, nk_bool value)
32178 return nk_select_symbol_text(ctx, sym, title, nk_strlen(title), align, value);
32202 nk_slider_behavior(nk_flags *state,
struct nk_rect *logical_cursor,
32204 struct nk_rect bounds,
float slider_min,
float slider_max,
float slider_value,
32205 float slider_step,
float slider_steps)
32207 int left_mouse_down;
32208 int left_mouse_click_in_cursor;
32211 nk_widget_state_reset(state);
32212 left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
32213 left_mouse_click_in_cursor = in && nk_input_has_mouse_click_down_in_rect(in,
32214 NK_BUTTON_LEFT, *visual_cursor, nk_true);
32216 if (left_mouse_down && left_mouse_click_in_cursor) {
32218 const float d = in->mouse.pos.x - (visual_cursor->x+visual_cursor->w*0.5f);
32219 const float pxstep = bounds.w / slider_steps;
32223 if (NK_ABS(d) >= pxstep) {
32224 const float steps = (float)((
int)(NK_ABS(d) / pxstep));
32225 slider_value += (d > 0) ? (slider_step*steps) : -(slider_step*steps);
32226 slider_value = NK_CLAMP(slider_min, slider_value, slider_max);
32227 ratio = (slider_value - slider_min)/slider_step;
32228 logical_cursor->x = bounds.x + (logical_cursor->w * ratio);
32229 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = logical_cursor->x;
32234 if (nk_input_is_mouse_hovering_rect(in, bounds))
32237 !nk_input_is_mouse_prev_hovering_rect(in, bounds))
32239 else if (nk_input_is_mouse_prev_hovering_rect(in, bounds))
32241 return slider_value;
32257 const struct nk_rect *visual_cursor,
float min,
float value,
float max)
32272 background = &style->active;
32273 bar_color = style->bar_active;
32274 cursor = &style->cursor_active;
32276 background = &style->hover;
32277 bar_color = style->bar_hover;
32278 cursor = &style->cursor_hover;
32280 background = &style->normal;
32281 bar_color = style->bar_normal;
32282 cursor = &style->cursor_normal;
32287 bar.y = (visual_cursor->y + visual_cursor->h/2) - bounds->h/12;
32289 bar.h = bounds->h/6;
32292 fill.w = (visual_cursor->x + (visual_cursor->w/2.0f)) - bar.x;
32298 switch(background->type) {
32299 case NK_STYLE_ITEM_IMAGE:
32300 nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
32302 case NK_STYLE_ITEM_NINE_SLICE:
32303 nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor));
32305 case NK_STYLE_ITEM_COLOR:
32306 nk_fill_rect(out, *bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor));
32307 nk_stroke_rect(out, *bounds, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor));
32312 nk_fill_rect(out, bar, style->rounding, nk_rgb_factor(bar_color, style->color_factor));
32313 nk_fill_rect(out, fill, style->rounding, nk_rgb_factor(style->bar_filled, style->color_factor));
32316 if (cursor->type == NK_STYLE_ITEM_IMAGE)
32317 nk_draw_image(out, *visual_cursor, &cursor->data.image, nk_rgb_factor(nk_white, style->color_factor));
32319 nk_fill_circle(out, *visual_cursor, nk_rgb_factor(cursor->data.color, style->color_factor));
32332 nk_do_slider(nk_flags *state,
32334 float min,
float val,
float max,
float step,
32338 float slider_range;
32341 float slider_value;
32342 float slider_steps;
32343 float cursor_offset;
32345 struct nk_rect visual_cursor;
32346 struct nk_rect logical_cursor;
32350 if (!out || !style)
32354 bounds.x = bounds.x + style->padding.x;
32355 bounds.y = bounds.y + style->padding.y;
32356 bounds.h = NK_MAX(bounds.h, 2*style->padding.y);
32357 bounds.w = NK_MAX(bounds.w, 2*style->padding.x + style->cursor_size.x);
32358 bounds.w -= 2 * style->padding.x;
32359 bounds.h -= 2 * style->padding.y;
32362 if (style->show_buttons) {
32365 button.y = bounds.y;
32366 button.w = bounds.h;
32367 button.h = bounds.h;
32370 button.x = bounds.x;
32371 if (nk_do_button_symbol(&ws, out, button, style->dec_symbol, NK_BUTTON_DEFAULT,
32372 &style->dec_button, in, font))
32376 button.x = (bounds.x + bounds.w) - button.w;
32377 if (nk_do_button_symbol(&ws, out, button, style->inc_symbol, NK_BUTTON_DEFAULT,
32378 &style->inc_button, in, font))
32381 bounds.x = bounds.x + button.w + style->spacing.x;
32382 bounds.w = bounds.w - (2*button.w + 2*style->spacing.x);
32386 bounds.x += style->cursor_size.x*0.5f;
32387 bounds.w -= style->cursor_size.x;
32390 slider_max = NK_MAX(min, max);
32391 slider_min = NK_MIN(min, max);
32392 slider_value = NK_CLAMP(slider_min, val, slider_max);
32393 slider_range = slider_max - slider_min;
32394 slider_steps = slider_range / step;
32395 cursor_offset = (slider_value - slider_min) / step;
32400 logical_cursor.h = bounds.h;
32401 logical_cursor.w = bounds.w / slider_steps;
32402 logical_cursor.x = bounds.x + (logical_cursor.w * cursor_offset);
32403 logical_cursor.y = bounds.y;
32405 visual_cursor.h = style->cursor_size.y;
32406 visual_cursor.w = style->cursor_size.x;
32407 visual_cursor.y = (bounds.y + bounds.h*0.5f) - visual_cursor.h*0.5f;
32408 visual_cursor.x = logical_cursor.x - visual_cursor.w*0.5f;
32410 slider_value = nk_slider_behavior(state, &logical_cursor, &visual_cursor,
32411 in, bounds, slider_min, slider_max, slider_value, step, slider_steps);
32412 visual_cursor.x = logical_cursor.x - visual_cursor.w*0.5f;
32415 if (style->draw_begin) style->draw_begin(out, style->userdata);
32416 nk_draw_slider(out, *state, style, &bounds, &visual_cursor, slider_min, slider_value, slider_max);
32417 if (style->draw_end) style->draw_end(out, style->userdata);
32418 return slider_value;
32434 nk_slider_float(
struct nk_context *ctx,
float min_value,
float *value,
float max_value,
32448 NK_ASSERT(ctx->current);
32449 NK_ASSERT(ctx->current->layout);
32451 if (!ctx || !ctx->current || !ctx->current->layout || !value)
32454 win = ctx->current;
32455 style = &ctx->style;
32456 layout = win->layout;
32458 state = nk_widget(&bounds, ctx);
32459 if (!state)
return ret;
32462 old_value = *value;
32463 *value = nk_do_slider(&ctx->last_widget_state, &win->buffer, bounds, min_value,
32464 old_value, max_value, value_step, &style->slider, in, style->font);
32465 return (old_value > *value || old_value < *value);
32482 nk_slide_float(
struct nk_context *ctx,
float min,
float val,
float max,
float step)
32484 nk_slider_float(ctx, min, &val, max, step);
return val;
32501 nk_slide_int(
struct nk_context *ctx,
int min,
int val,
int max,
int step)
32503 float value = (float)val;
32504 nk_slider_float(ctx, (
float)min, &value, (
float)max, (
float)step);
32522 nk_slider_int(
struct nk_context *ctx,
int min,
int *val,
int max,
int step)
32525 float value = (float)*val;
32526 ret = nk_slider_float(ctx, (
float)min, &value, (
float)max, (
float)step);
32553 nk_knob_behavior(nk_flags *state,
struct nk_input *in,
32554 struct nk_rect bounds,
float knob_min,
float knob_max,
float knob_value,
32555 float knob_step,
float knob_steps,
32556 enum nk_heading zero_direction,
float dead_zone_percent)
32559 float angle = 0.0f;
32560 origin.x = bounds.x + (bounds.w / 2);
32561 origin.y = bounds.y + (bounds.h / 2);
32563 nk_widget_state_reset(state);
32567 in->mouse.buttons[NK_BUTTON_LEFT].down &&
32568 nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, bounds, nk_true)){
32570 const float direction_rads[4] = {
32578 angle = NK_ATAN2(in->mouse.pos.y - origin.y, in->mouse.pos.x - origin.x) + direction_rads[zero_direction];
32579 angle -= (angle > NK_PI * 2) ? NK_PI * 3 : NK_PI;
32582 angle *= 1.0f / (1.0f - dead_zone_percent);
32583 angle = NK_CLAMP(-NK_PI, angle, NK_PI);
32586 angle = (angle + NK_PI) / (NK_PI * 2);
32589 knob_value = knob_min + ( (int)(angle * knob_steps + (knob_step / 2)) ) * knob_step;
32590 knob_value = NK_CLAMP(knob_min, knob_value, knob_max);
32594 if (nk_input_is_mouse_hovering_rect(in, bounds)){
32598 if (in->mouse.scroll_delta.y > 0 ||
32599 (in->keyboard.keys[NK_KEY_UP].down && in->keyboard.keys[NK_KEY_UP].clicked))
32600 knob_value += knob_step;
32602 if (in->mouse.scroll_delta.y < 0 ||
32603 (in->keyboard.keys[NK_KEY_DOWN].down && in->keyboard.keys[NK_KEY_DOWN].clicked))
32604 knob_value -= knob_step;
32606 knob_value = NK_CLAMP(knob_min, knob_value, knob_max);
32609 !nk_input_is_mouse_prev_hovering_rect(in, bounds))
32611 else if (nk_input_is_mouse_prev_hovering_rect(in, bounds))
32629 const struct nk_style_knob *style,
const struct nk_rect *bounds,
float min,
float value,
float max,
32630 enum nk_heading zero_direction,
float dead_zone_percent)
32633 struct nk_color knob_color, cursor;
32640 background = &style->active;
32641 knob_color = style->knob_active;
32642 cursor = style->cursor_active;
32644 background = &style->hover;
32645 knob_color = style->knob_hover;
32646 cursor = style->cursor_hover;
32648 background = &style->normal;
32649 knob_color = style->knob_normal;
32650 cursor = style->cursor_normal;
32654 switch(background->type) {
32655 case NK_STYLE_ITEM_IMAGE:
32656 nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
32658 case NK_STYLE_ITEM_NINE_SLICE:
32659 nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor));
32661 case NK_STYLE_ITEM_COLOR:
32662 nk_fill_rect(out, *bounds, 0, nk_rgb_factor(background->data.color, style->color_factor));
32663 nk_stroke_rect(out, *bounds, 0, style->border, nk_rgb_factor(style->border_color, style->color_factor));
32668 nk_fill_circle(out, *bounds, nk_rgb_factor(knob_color, style->color_factor));
32669 if(style->knob_border > 0){
32670 struct nk_rect border_bounds = *bounds;
32671 border_bounds.x += style->knob_border / 2;
32672 border_bounds.y += style->knob_border / 2;
32673 border_bounds.w -= style->knob_border;
32674 border_bounds.h -= style->knob_border;
32675 nk_stroke_circle(out, border_bounds, style->knob_border, nk_rgb_factor(style->knob_border_color, style->color_factor));
32678 float half_circle_size = (bounds->w / 2);
32679 float angle = (value - min) / (max - min);
32680 float alive_zone = 1.0f - dead_zone_percent;
32681 struct nk_vec2 cursor_start, cursor_end;
32682 const float direction_rads[4] = {
32689 angle = (angle * alive_zone) + (dead_zone_percent / 2);
32692 angle *= NK_PI * 2;
32695 angle += direction_rads[zero_direction];
32696 if(angle > NK_PI * 2)
32697 angle -= NK_PI * 2;
32699 cursor_start.x = bounds->x + half_circle_size + (angle > NK_PI);
32700 cursor_start.y = bounds->y + half_circle_size + (angle < NK_PI_HALF || angle > (NK_PI * 1.5f));
32702 cursor_end.x = cursor_start.x + (half_circle_size * NK_COS(angle));
32703 cursor_end.y = cursor_start.y + (half_circle_size * NK_SIN(angle));
32706 cursor_start.x = (cursor_start.x + cursor_end.x) / 2;
32707 cursor_start.y = (cursor_start.y + cursor_end.y) / 2;
32710 nk_stroke_line(out, cursor_start.x, cursor_start.y, cursor_end.x, cursor_end.y, 2, nk_rgb_factor(cursor, style->color_factor));
32724 nk_do_knob(nk_flags *state,
32726 float min,
float val,
float max,
float step,
32727 enum nk_heading zero_direction,
float dead_zone_percent,
32738 if (!out || !style)
32742 bounds.y = bounds.y + style->padding.y;
32743 bounds.x = bounds.x + style->padding.x;
32744 bounds.h = NK_MAX(bounds.h, 2*style->padding.y);
32745 bounds.w = NK_MAX(bounds.w, 2*style->padding.x);
32746 bounds.w -= 2 * style->padding.x;
32747 bounds.h -= 2 * style->padding.y;
32748 if(bounds.h < bounds.w){
32749 bounds.x += (bounds.w - bounds.h) / 2;
32750 bounds.w = bounds.h;
32754 knob_max = NK_MAX(min, max);
32755 knob_min = NK_MIN(min, max);
32756 knob_value = NK_CLAMP(knob_min, val, knob_max);
32757 knob_range = knob_max - knob_min;
32758 knob_steps = knob_range / step;
32760 knob_value = nk_knob_behavior(state, in, bounds, knob_min, knob_max, knob_value, step, knob_steps, zero_direction, dead_zone_percent);
32763 if (style->draw_begin) style->draw_begin(out, style->userdata);
32764 nk_draw_knob(out, *state, style, &bounds, knob_min, knob_value, knob_max, zero_direction, dead_zone_percent);
32765 if (style->draw_end) style->draw_end(out, style->userdata);
32782 nk_knob_float(
struct nk_context *ctx,
float min_value,
float *value,
float max_value,
32783 float value_step,
enum nk_heading zero_direction,
float dead_zone_degrees)
32796 NK_ASSERT(ctx->current);
32797 NK_ASSERT(ctx->current->layout);
32799 NK_ASSERT(NK_BETWEEN(dead_zone_degrees, 0.0f, 360.0f));
32800 if (!ctx || !ctx->current || !ctx->current->layout || !value)
32803 win = ctx->current;
32804 style = &ctx->style;
32805 layout = win->layout;
32807 state = nk_widget(&bounds, ctx);
32808 if (!state)
return ret;
32811 old_value = *value;
32812 *value = nk_do_knob(&ctx->last_widget_state, &win->buffer, bounds, min_value,
32813 old_value, max_value, value_step, zero_direction, dead_zone_degrees / 360.0f, &style->knob, in);
32815 return (old_value > *value || old_value < *value);
32832 nk_knob_int(
struct nk_context *ctx,
int min,
int *val,
int max,
int step,
32833 enum nk_heading zero_direction,
float dead_zone_degrees)
32836 float value = (float)*val;
32837 ret = nk_knob_float(ctx, (
float)min, &value, (
float)max, (
float)step, zero_direction, dead_zone_degrees);
32862 nk_progress_behavior(nk_flags *state,
struct nk_input *in,
32863 struct nk_rect r,
struct nk_rect cursor, nk_size max, nk_size value, nk_bool modifiable)
32865 int left_mouse_down = 0;
32866 int left_mouse_click_in_cursor = 0;
32868 nk_widget_state_reset(state);
32869 if (!in || !modifiable)
return value;
32870 left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
32871 left_mouse_click_in_cursor = in && nk_input_has_mouse_click_down_in_rect(in,
32872 NK_BUTTON_LEFT, cursor, nk_true);
32873 if (nk_input_is_mouse_hovering_rect(in, r))
32876 if (in && left_mouse_down && left_mouse_click_in_cursor) {
32877 if (left_mouse_down && left_mouse_click_in_cursor) {
32878 float ratio = NK_MAX(0, (
float)(in->mouse.pos.x - cursor.x)) / (float)cursor.w;
32879 value = (nk_size)NK_CLAMP(0, (
float)max * ratio, (
float)max);
32880 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = cursor.x + cursor.w/2.0f;
32887 else if (nk_input_is_mouse_prev_hovering_rect(in, r))
32905 const struct nk_rect *scursor, nk_size value, nk_size max)
32915 background = &style->active;
32916 cursor = &style->cursor_active;
32918 background = &style->hover;
32919 cursor = &style->cursor_hover;
32921 background = &style->normal;
32922 cursor = &style->cursor_normal;
32926 switch(background->type) {
32927 case NK_STYLE_ITEM_IMAGE:
32928 nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
32930 case NK_STYLE_ITEM_NINE_SLICE:
32931 nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor));
32933 case NK_STYLE_ITEM_COLOR:
32934 nk_fill_rect(out, *bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor));
32935 nk_stroke_rect(out, *bounds, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor));
32940 switch(cursor->type) {
32941 case NK_STYLE_ITEM_IMAGE:
32942 nk_draw_image(out, *scursor, &cursor->data.image, nk_rgb_factor(nk_white, style->color_factor));
32944 case NK_STYLE_ITEM_NINE_SLICE:
32945 nk_draw_nine_slice(out, *scursor, &cursor->data.slice, nk_rgb_factor(nk_white, style->color_factor));
32947 case NK_STYLE_ITEM_COLOR:
32948 nk_fill_rect(out, *scursor, style->rounding, nk_rgb_factor(cursor->data.color, style->color_factor));
32949 nk_stroke_rect(out, *scursor, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor));
32964 nk_do_progress(nk_flags *state,
32966 nk_size value, nk_size max, nk_bool modifiable,
32970 nk_size prog_value;
32975 if (!out || !style)
return 0;
32978 cursor.w = NK_MAX(bounds.w, 2 * style->padding.x + 2 * style->border);
32979 cursor.h = NK_MAX(bounds.h, 2 * style->padding.y + 2 * style->border);
32980 cursor = nk_pad_rect(bounds,
nk_vec2(style->padding.x + style->border, style->padding.y + style->border));
32981 prog_scale = (float)value / (
float)max;
32984 prog_value = NK_MIN(value, max);
32985 prog_value = nk_progress_behavior(state, in, bounds, cursor,max, prog_value, modifiable);
32986 cursor.w = cursor.w * prog_scale;
32989 if (style->draw_begin) style->draw_begin(out, style->userdata);
32990 nk_draw_progress(out, *state, style, &bounds, &cursor, value, max);
32991 if (style->draw_end) style->draw_end(out, style->userdata);
33008 nk_progress(
struct nk_context *ctx, nk_size *cur, nk_size max, nk_bool is_modifyable)
33021 NK_ASSERT(ctx->current);
33022 NK_ASSERT(ctx->current->layout);
33023 if (!ctx || !ctx->current || !ctx->current->layout || !cur)
33026 win = ctx->current;
33027 style = &ctx->style;
33028 layout = win->layout;
33029 state = nk_widget(&bounds, ctx);
33030 if (!state)
return 0;
33034 *cur = nk_do_progress(&ctx->last_widget_state, &win->buffer, bounds,
33035 *cur, max, is_modifyable, &style->progress, in);
33036 return (*cur != old_value);
33052 nk_prog(
struct nk_context *ctx, nk_size cur, nk_size max, nk_bool modifyable)
33054 nk_progress(ctx, &cur, max, modifyable);
33079 nk_scrollbar_behavior(nk_flags *state,
struct nk_input *in,
33080 int has_scrolling,
const struct nk_rect *scroll,
33082 const struct nk_rect *empty1,
float scroll_offset,
33083 float target,
float scroll_step,
enum nk_orientation o)
33086 int left_mouse_down;
33087 unsigned int left_mouse_clicked;
33088 int left_mouse_click_in_cursor;
33089 float scroll_delta;
33091 nk_widget_state_reset(state);
33092 if (!in)
return scroll_offset;
33094 left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
33095 left_mouse_clicked = in->mouse.buttons[NK_BUTTON_LEFT].clicked;
33096 left_mouse_click_in_cursor = nk_input_has_mouse_click_down_in_rect(in,
33097 NK_BUTTON_LEFT, *cursor, nk_true);
33098 if (nk_input_is_mouse_hovering_rect(in, *scroll))
33101 scroll_delta = (o == NK_VERTICAL) ? in->mouse.scroll_delta.y: in->mouse.scroll_delta.x;
33102 if (left_mouse_down && left_mouse_click_in_cursor && !left_mouse_clicked) {
33104 float pixel, delta;
33106 if (o == NK_VERTICAL) {
33108 pixel = in->mouse.delta.y;
33109 delta = (pixel / scroll->h) * target;
33110 scroll_offset = NK_CLAMP(0, scroll_offset + delta, target - scroll->h);
33111 cursor_y = scroll->y + ((scroll_offset/target) * scroll->h);
33112 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y = cursor_y + cursor->h/2.0f;
33115 pixel = in->mouse.delta.x;
33116 delta = (pixel / scroll->w) * target;
33117 scroll_offset = NK_CLAMP(0, scroll_offset + delta, target - scroll->w);
33118 cursor_x = scroll->x + ((scroll_offset/target) * scroll->w);
33119 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = cursor_x + cursor->w/2.0f;
33121 }
else if ((nk_input_is_key_pressed(in, NK_KEY_SCROLL_UP) && o == NK_VERTICAL && has_scrolling)||
33122 nk_button_behavior(&ws, *empty0, in, NK_BUTTON_DEFAULT)) {
33124 if (o == NK_VERTICAL)
33125 scroll_offset = NK_MAX(0, scroll_offset - scroll->h);
33126 else scroll_offset = NK_MAX(0, scroll_offset - scroll->w);
33127 }
else if ((nk_input_is_key_pressed(in, NK_KEY_SCROLL_DOWN) && o == NK_VERTICAL && has_scrolling) ||
33128 nk_button_behavior(&ws, *empty1, in, NK_BUTTON_DEFAULT)) {
33130 if (o == NK_VERTICAL)
33131 scroll_offset = NK_MIN(scroll_offset + scroll->h, target - scroll->h);
33132 else scroll_offset = NK_MIN(scroll_offset + scroll->w, target - scroll->w);
33133 }
else if (has_scrolling) {
33134 if ((scroll_delta < 0 || (scroll_delta > 0))) {
33136 scroll_offset = scroll_offset + scroll_step * (-scroll_delta);
33137 if (o == NK_VERTICAL)
33138 scroll_offset = NK_CLAMP(0, scroll_offset, target - scroll->h);
33139 else scroll_offset = NK_CLAMP(0, scroll_offset, target - scroll->w);
33140 }
else if (nk_input_is_key_pressed(in, NK_KEY_SCROLL_START)) {
33142 if (o == NK_VERTICAL) scroll_offset = 0;
33143 }
else if (nk_input_is_key_pressed(in, NK_KEY_SCROLL_END)) {
33145 if (o == NK_VERTICAL) scroll_offset = target - scroll->h;
33150 else if (nk_input_is_mouse_prev_hovering_rect(in, *scroll))
33152 return scroll_offset;
33168 const struct nk_rect *scroll)
33175 background = &style->active;
33176 cursor = &style->cursor_active;
33178 background = &style->hover;
33179 cursor = &style->cursor_hover;
33181 background = &style->normal;
33182 cursor = &style->cursor_normal;
33186 switch (background->type) {
33187 case NK_STYLE_ITEM_IMAGE:
33188 nk_draw_image(out, *bounds, &background->data.image, nk_white);
33190 case NK_STYLE_ITEM_NINE_SLICE:
33191 nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_white);
33193 case NK_STYLE_ITEM_COLOR:
33194 nk_fill_rect(out, *bounds, style->rounding, background->data.color);
33195 nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color);
33200 switch (cursor->type) {
33201 case NK_STYLE_ITEM_IMAGE:
33202 nk_draw_image(out, *scroll, &cursor->data.image, nk_white);
33204 case NK_STYLE_ITEM_NINE_SLICE:
33205 nk_draw_nine_slice(out, *scroll, &cursor->data.slice, nk_white);
33207 case NK_STYLE_ITEM_COLOR:
33208 nk_fill_rect(out, *scroll, style->rounding_cursor, cursor->data.color);
33209 nk_stroke_rect(out, *scroll, style->rounding_cursor, style->border_cursor, style->cursor_border_color);
33224 nk_do_scrollbarv(nk_flags *state,
33226 float offset,
float target,
float step,
float button_pixel_inc,
33235 float scroll_offset;
33237 float scroll_ratio;
33242 if (!out || !style)
return 0;
33244 scroll.w = NK_MAX(scroll.w, 1);
33245 scroll.h = NK_MAX(scroll.h, 0);
33246 if (target <= scroll.h)
return 0;
33249 if (style->show_buttons) {
33254 button.x = scroll.x;
33255 button.w = scroll.w;
33256 button.h = scroll.w;
33258 scroll_h = NK_MAX(scroll.h - 2 * button.h,0);
33259 scroll_step = NK_MIN(step, button_pixel_inc);
33262 button.y = scroll.y;
33263 if (nk_do_button_symbol(&ws, out, button, style->dec_symbol,
33264 NK_BUTTON_REPEATER, &style->dec_button, in, font))
33265 offset = offset - scroll_step;
33268 button.y = scroll.y + scroll.h - button.h;
33269 if (nk_do_button_symbol(&ws, out, button, style->inc_symbol,
33270 NK_BUTTON_REPEATER, &style->inc_button, in, font))
33271 offset = offset + scroll_step;
33273 scroll.y = scroll.y + button.h;
33274 scroll.h = scroll_h;
33278 scroll_step = NK_MIN(step, scroll.h);
33279 scroll_offset = NK_CLAMP(0, offset, target - scroll.h);
33280 scroll_ratio = scroll.h / target;
33281 scroll_off = scroll_offset / target;
33284 cursor.h = NK_MAX((scroll_ratio * scroll.h) - (2*style->border + 2*style->padding.y), 0);
33285 cursor.y = scroll.y + (scroll_off * scroll.h) + style->border + style->padding.y;
33286 cursor.w = scroll.w - (2 * style->border + 2 * style->padding.x);
33287 cursor.x = scroll.x + style->border + style->padding.x;
33290 empty_north.x = scroll.x;
33291 empty_north.y = scroll.y;
33292 empty_north.w = scroll.w;
33293 empty_north.h = NK_MAX(cursor.y - scroll.y, 0);
33295 empty_south.x = scroll.x;
33296 empty_south.y = cursor.y + cursor.h;
33297 empty_south.w = scroll.w;
33298 empty_south.h = NK_MAX((scroll.y + scroll.h) - (cursor.y + cursor.h), 0);
33301 scroll_offset = nk_scrollbar_behavior(state, in, has_scrolling, &scroll, &cursor,
33302 &empty_north, &empty_south, scroll_offset, target, scroll_step, NK_VERTICAL);
33303 scroll_off = scroll_offset / target;
33304 cursor.y = scroll.y + (scroll_off * scroll.h) + style->border_cursor + style->padding.y;
33307 if (style->draw_begin) style->draw_begin(out, style->userdata);
33308 nk_draw_scrollbar(out, *state, style, &scroll, &cursor);
33309 if (style->draw_end) style->draw_end(out, style->userdata);
33310 return scroll_offset;
33323 nk_do_scrollbarh(nk_flags *state,
33325 float offset,
float target,
float step,
float button_pixel_inc,
33334 float scroll_offset;
33336 float scroll_ratio;
33340 if (!out || !style)
return 0;
33343 scroll.h = NK_MAX(scroll.h, 1);
33344 scroll.w = NK_MAX(scroll.w, 2 * scroll.h);
33345 if (target <= scroll.w)
return 0;
33348 if (style->show_buttons) {
33352 button.y = scroll.y;
33353 button.w = scroll.h;
33354 button.h = scroll.h;
33356 scroll_w = scroll.w - 2 * button.w;
33357 scroll_step = NK_MIN(step, button_pixel_inc);
33360 button.x = scroll.x;
33361 if (nk_do_button_symbol(&ws, out, button, style->dec_symbol,
33362 NK_BUTTON_REPEATER, &style->dec_button, in, font))
33363 offset = offset - scroll_step;
33366 button.x = scroll.x + scroll.w - button.w;
33367 if (nk_do_button_symbol(&ws, out, button, style->inc_symbol,
33368 NK_BUTTON_REPEATER, &style->inc_button, in, font))
33369 offset = offset + scroll_step;
33371 scroll.x = scroll.x + button.w;
33372 scroll.w = scroll_w;
33376 scroll_step = NK_MIN(step, scroll.w);
33377 scroll_offset = NK_CLAMP(0, offset, target - scroll.w);
33378 scroll_ratio = scroll.w / target;
33379 scroll_off = scroll_offset / target;
33382 cursor.w = (scroll_ratio * scroll.w) - (2*style->border + 2*style->padding.x);
33383 cursor.x = scroll.x + (scroll_off * scroll.w) + style->border + style->padding.x;
33384 cursor.h = scroll.h - (2 * style->border + 2 * style->padding.y);
33385 cursor.y = scroll.y + style->border + style->padding.y;
33388 empty_west.x = scroll.x;
33389 empty_west.y = scroll.y;
33390 empty_west.w = cursor.x - scroll.x;
33391 empty_west.h = scroll.h;
33393 empty_east.x = cursor.x + cursor.w;
33394 empty_east.y = scroll.y;
33395 empty_east.w = (scroll.x + scroll.w) - (cursor.x + cursor.w);
33396 empty_east.h = scroll.h;
33399 scroll_offset = nk_scrollbar_behavior(state, in, has_scrolling, &scroll, &cursor,
33400 &empty_west, &empty_east, scroll_offset, target, scroll_step, NK_HORIZONTAL);
33401 scroll_off = scroll_offset / target;
33402 cursor.x = scroll.x + (scroll_off * scroll.w);
33405 if (style->draw_begin) style->draw_begin(out, style->userdata);
33406 nk_draw_scrollbar(out, *state, style, &scroll, &cursor);
33407 if (style->draw_end) style->draw_end(out, style->userdata);
33408 return scroll_offset;
33421 struct nk_text_find {
33424 int first_char, length;
33428 struct nk_text_edit_row {
33431 float baseline_y_delta;
33439 NK_INTERN
void nk_textedit_makeundo_delete(
struct nk_text_edit*,
int,
int);
33440 NK_INTERN
void nk_textedit_makeundo_insert(
struct nk_text_edit*,
int,
int);
33441 NK_INTERN
void nk_textedit_makeundo_replace(
struct nk_text_edit*,
int,
int,
int);
33442 #define NK_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
33457 nk_textedit_get_width(
const struct nk_text_edit *edit,
int line_start,
int char_id,
33461 nk_rune unicode = 0;
33462 const char *str = nk_str_at_const(&edit->string, line_start + char_id, &unicode, &len);
33463 return font->
width(font->userdata, font->
height, str, len);
33477 nk_textedit_layout_row(
struct nk_text_edit_row *r,
struct nk_text_edit *edit,
33478 int line_start_id,
float row_height,
const struct nk_user_font *font)
33483 const char *remaining;
33484 int len = nk_str_len_char(&edit->string);
33485 const char *end = nk_str_get_const(&edit->string) + len;
33486 const char *text = nk_str_at_const(&edit->string, line_start_id, &unicode, &l);
33487 const struct nk_vec2 size = nk_text_calculate_text_bounds(font,
33488 text, (
int)(end - text), row_height, &remaining, 0, &glyphs, NK_STOP_ON_NEW_LINE);
33492 r->baseline_y_delta = size.y;
33495 r->num_chars = glyphs;
33510 nk_textedit_locate_coord(
struct nk_text_edit *edit,
float x,
float y,
33513 struct nk_text_edit_row r;
33514 int n = edit->string.len;
33515 float base_y = 0, prev_x;
33519 r.ymin = r.ymax = 0;
33524 nk_textedit_layout_row(&r, edit, i, row_height, font);
33525 if (r.num_chars <= 0)
33528 if (i==0 && y < base_y + r.ymin)
33531 if (y < base_y + r.ymax)
33535 base_y += r.baseline_y_delta;
33551 for (i=0; i < r.num_chars; ++i) {
33552 float w = nk_textedit_get_width(edit, k, i, font);
33553 if (x < prev_x+w) {
33554 if (x < prev_x+w/2)
33565 if (nk_str_rune_at(&edit->string, i+r.num_chars-1) ==
'\n')
33566 return i+r.num_chars-1;
33567 else return i+r.num_chars;
33582 nk_textedit_click(
struct nk_text_edit *state,
float x,
float y,
33587 state->cursor = nk_textedit_locate_coord(state, x, y, font, row_height);
33588 state->select_start = state->cursor;
33589 state->select_end = state->cursor;
33590 state->has_preferred_x = 0;
33605 nk_textedit_drag(
struct nk_text_edit *state,
float x,
float y,
33610 int p = nk_textedit_locate_coord(state, x, y, font, row_height);
33611 if (state->select_start == state->select_end)
33612 state->select_start = state->cursor;
33613 state->cursor = state->select_end = p;
33627 nk_textedit_find_charpos(
struct nk_text_find *find,
struct nk_text_edit *state,
33628 int n,
int single_line,
const struct nk_user_font *font,
float row_height)
33632 struct nk_text_edit_row r;
33633 int prev_start = 0;
33634 int z = state->string.len;
33641 nk_textedit_layout_row(&r, state, 0, row_height, font);
33643 find->first_char = 0;
33649 nk_textedit_layout_row(&r, state, i, row_height, font);
33652 find->first_char = i;
33653 find->length = r.num_chars;
33657 find->height = r.ymax - r.ymin;
33658 find->prev_first = prev_start;
33666 nk_textedit_layout_row(&r, state, i, row_height, font);
33667 if (n < i + r.num_chars)
break;
33670 find->y += r.baseline_y_delta;
33673 find->first_char = first = i;
33674 find->length = r.num_chars;
33675 find->height = r.ymax - r.ymin;
33676 find->prev_first = prev_start;
33680 for (i=0; first+i < n; ++i)
33681 find->x += nk_textedit_get_width(state, first, i, font);
33697 int n = state->string.len;
33698 if (NK_TEXT_HAS_SELECTION(state)) {
33699 if (state->select_start > n) state->select_start = n;
33700 if (state->select_end > n) state->select_end = n;
33702 if (state->select_start == state->select_end)
33703 state->cursor = state->select_start;
33705 if (state->cursor > n) state->cursor = n;
33720 nk_textedit_delete(
struct nk_text_edit *state,
int where,
int len)
33723 nk_textedit_makeundo_delete(state, where, len);
33724 nk_str_delete_runes(&state->string, where, len);
33725 state->has_preferred_x = 0;
33738 nk_textedit_delete_selection(
struct nk_text_edit *state)
33741 nk_textedit_clamp(state);
33742 if (NK_TEXT_HAS_SELECTION(state)) {
33743 if (state->select_start < state->select_end) {
33744 nk_textedit_delete(state, state->select_start,
33745 state->select_end - state->select_start);
33746 state->select_end = state->cursor = state->select_start;
33748 nk_textedit_delete(state, state->select_end,
33749 state->select_start - state->select_end);
33750 state->select_start = state->cursor = state->select_end;
33752 state->has_preferred_x = 0;
33769 if (state->select_end < state->select_start) {
33770 int temp = state->select_end;
33771 state->select_end = state->select_start;
33772 state->select_start = temp;
33789 if (NK_TEXT_HAS_SELECTION(state)) {
33790 nk_textedit_sortselection(state);
33791 state->cursor = state->select_start;
33792 state->select_end = state->select_start;
33793 state->has_preferred_x = 0;
33810 if (NK_TEXT_HAS_SELECTION(state)) {
33811 nk_textedit_sortselection(state);
33812 nk_textedit_clamp(state);
33813 state->cursor = state->select_end;
33814 state->select_start = state->select_end;
33815 state->has_preferred_x = 0;
33830 nk_is_word_boundary(
struct nk_text_edit *state,
int idx)
33834 if (idx <= 0)
return 1;
33835 if (!nk_str_at_rune(&state->string, idx, &c, &len))
return 1;
33836 return (c ==
' ' || c ==
'\t' ||c == 0x3000 || c ==
',' || c ==
';' ||
33837 c ==
'(' || c ==
')' || c ==
'{' || c ==
'}' || c ==
'[' || c ==
']' ||
33851 nk_textedit_move_to_word_previous(
struct nk_text_edit *state)
33853 int c = state->cursor - 1;
33854 while( c >= 0 && !nk_is_word_boundary(state, c))
33873 nk_textedit_move_to_word_next(
struct nk_text_edit *state)
33875 const int len = state->string.len;
33876 int c = state->cursor+1;
33877 while( c < len && !nk_is_word_boundary(state, c))
33896 nk_textedit_prep_selection_at_cursor(
struct nk_text_edit *state)
33899 if (!NK_TEXT_HAS_SELECTION(state))
33900 state->select_start = state->select_end = state->cursor;
33901 else state->cursor = state->select_end;
33917 if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
33919 if (NK_TEXT_HAS_SELECTION(state)) {
33920 nk_textedit_delete_selection(state);
33921 state->has_preferred_x = 0;
33939 nk_textedit_paste(
struct nk_text_edit *state,
char const *ctext,
int len)
33943 const char *text = (
const char *) ctext;
33944 if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
return 0;
33947 nk_textedit_clamp(state);
33948 nk_textedit_delete_selection(state);
33951 glyphs = nk_utf_len(ctext, len);
33952 if (nk_str_insert_text_char(&state->string, state->cursor, text, len)) {
33953 nk_textedit_makeundo_insert(state, state->cursor, glyphs);
33954 state->cursor += len;
33955 state->has_preferred_x = 0;
33959 if (state->undo.undo_point)
33960 --state->undo.undo_point;
33976 nk_textedit_text(
struct nk_text_edit *state,
const char *text,
int total_len)
33984 if (!text || !total_len || state->mode == NK_TEXT_EDIT_MODE_VIEW)
return;
33986 glyph_len = nk_utf_decode(text, &unicode, total_len);
33987 while ((text_len < total_len) && glyph_len)
33990 if (unicode == 127)
goto next;
33992 if (unicode ==
'\n' && state->single_line)
goto next;
33994 if (state->filter && !state->filter(state, unicode))
goto next;
33996 if (!NK_TEXT_HAS_SELECTION(state) &&
33997 state->cursor < state->string.len)
33999 if (state->mode == NK_TEXT_EDIT_MODE_REPLACE) {
34000 nk_textedit_makeundo_replace(state, state->cursor, 1, 1);
34001 nk_str_delete_runes(&state->string, state->cursor, 1);
34003 if (nk_str_insert_text_utf8(&state->string, state->cursor,
34007 state->has_preferred_x = 0;
34010 nk_textedit_delete_selection(state);
34011 if (nk_str_insert_text_utf8(&state->string, state->cursor,
34014 nk_textedit_makeundo_insert(state, state->cursor, 1);
34015 state->cursor = NK_MIN(state->cursor + 1, state->string.len);
34016 state->has_preferred_x = 0;
34020 text_len += glyph_len;
34021 glyph_len = nk_utf_decode(text + text_len, &unicode, total_len-text_len);
34037 nk_textedit_key(
struct nk_text_edit *state,
enum nk_keys key,
int shift_mod,
34053 case NK_KEY_TEXT_UNDO:
34054 nk_textedit_undo(state);
34055 state->has_preferred_x = 0;
34058 case NK_KEY_TEXT_REDO:
34059 nk_textedit_redo(state);
34060 state->has_preferred_x = 0;
34063 case NK_KEY_TEXT_SELECT_ALL:
34064 nk_textedit_select_all(state);
34065 state->has_preferred_x = 0;
34068 case NK_KEY_TEXT_INSERT_MODE:
34069 if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
34070 state->mode = NK_TEXT_EDIT_MODE_INSERT;
34072 case NK_KEY_TEXT_REPLACE_MODE:
34073 if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
34074 state->mode = NK_TEXT_EDIT_MODE_REPLACE;
34076 case NK_KEY_TEXT_RESET_MODE:
34077 if (state->mode == NK_TEXT_EDIT_MODE_INSERT ||
34078 state->mode == NK_TEXT_EDIT_MODE_REPLACE)
34079 state->mode = NK_TEXT_EDIT_MODE_VIEW;
34084 nk_textedit_clamp(state);
34085 nk_textedit_prep_selection_at_cursor(state);
34087 if (state->select_end > 0)
34088 --state->select_end;
34089 state->cursor = state->select_end;
34090 state->has_preferred_x = 0;
34094 if (NK_TEXT_HAS_SELECTION(state))
34095 nk_textedit_move_to_first(state);
34096 else if (state->cursor > 0)
34098 state->has_preferred_x = 0;
34103 nk_textedit_prep_selection_at_cursor(state);
34105 ++state->select_end;
34106 nk_textedit_clamp(state);
34107 state->cursor = state->select_end;
34108 state->has_preferred_x = 0;
34112 if (NK_TEXT_HAS_SELECTION(state))
34113 nk_textedit_move_to_last(state);
34114 else ++state->cursor;
34115 nk_textedit_clamp(state);
34116 state->has_preferred_x = 0;
34119 case NK_KEY_TEXT_WORD_LEFT:
34121 if( !NK_TEXT_HAS_SELECTION( state ) )
34122 nk_textedit_prep_selection_at_cursor(state);
34123 state->cursor = nk_textedit_move_to_word_previous(state);
34124 state->select_end = state->cursor;
34125 nk_textedit_clamp(state );
34127 if (NK_TEXT_HAS_SELECTION(state))
34128 nk_textedit_move_to_first(state);
34130 state->cursor = nk_textedit_move_to_word_previous(state);
34131 nk_textedit_clamp(state );
34135 case NK_KEY_TEXT_WORD_RIGHT:
34137 if( !NK_TEXT_HAS_SELECTION( state ) )
34138 nk_textedit_prep_selection_at_cursor(state);
34139 state->cursor = nk_textedit_move_to_word_next(state);
34140 state->select_end = state->cursor;
34141 nk_textedit_clamp(state);
34143 if (NK_TEXT_HAS_SELECTION(state))
34144 nk_textedit_move_to_last(state);
34146 state->cursor = nk_textedit_move_to_word_next(state);
34147 nk_textedit_clamp(state );
34151 case NK_KEY_DOWN: {
34152 struct nk_text_find find;
34153 struct nk_text_edit_row row;
34154 int i, sel = shift_mod;
34156 if (state->single_line) {
34158 key = NK_KEY_RIGHT;
34163 nk_textedit_prep_selection_at_cursor(state);
34164 else if (NK_TEXT_HAS_SELECTION(state))
34165 nk_textedit_move_to_last(state);
34168 nk_textedit_clamp(state);
34169 nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
34176 float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
34177 int start = find.first_char + find.length;
34179 state->cursor = start;
34180 nk_textedit_layout_row(&row, state, state->cursor, row_height, font);
34183 for (i=0; i < row.num_chars && x < row.x1; ++i) {
34184 float dx = nk_textedit_get_width(state, start, i, font);
34190 nk_textedit_clamp(state);
34192 state->has_preferred_x = 1;
34193 state->preferred_x = goal_x;
34195 state->select_end = state->cursor;
34200 struct nk_text_find find;
34201 struct nk_text_edit_row row;
34202 int i, sel = shift_mod;
34204 if (state->single_line) {
34211 nk_textedit_prep_selection_at_cursor(state);
34212 else if (NK_TEXT_HAS_SELECTION(state))
34213 nk_textedit_move_to_first(state);
34216 nk_textedit_clamp(state);
34217 nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
34221 if (find.prev_first != find.first_char) {
34224 float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
34226 state->cursor = find.prev_first;
34227 nk_textedit_layout_row(&row, state, state->cursor, row_height, font);
34230 for (i=0; i < row.num_chars && x < row.x1; ++i) {
34231 float dx = nk_textedit_get_width(state, find.prev_first, i, font);
34237 nk_textedit_clamp(state);
34239 state->has_preferred_x = 1;
34240 state->preferred_x = goal_x;
34241 if (sel) state->select_end = state->cursor;
34246 if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
34248 if (NK_TEXT_HAS_SELECTION(state))
34249 nk_textedit_delete_selection(state);
34251 int n = state->string.len;
34252 if (state->cursor < n)
34253 nk_textedit_delete(state, state->cursor, 1);
34255 state->has_preferred_x = 0;
34258 case NK_KEY_BACKSPACE:
34259 if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
34261 if (NK_TEXT_HAS_SELECTION(state))
34262 nk_textedit_delete_selection(state);
34264 nk_textedit_clamp(state);
34265 if (state->cursor > 0) {
34266 nk_textedit_delete(state, state->cursor-1, 1);
34270 state->has_preferred_x = 0;
34273 case NK_KEY_TEXT_START:
34275 nk_textedit_prep_selection_at_cursor(state);
34276 state->cursor = state->select_end = 0;
34277 state->has_preferred_x = 0;
34279 state->cursor = state->select_start = state->select_end = 0;
34280 state->has_preferred_x = 0;
34284 case NK_KEY_TEXT_END:
34286 nk_textedit_prep_selection_at_cursor(state);
34287 state->cursor = state->select_end = state->string.len;
34288 state->has_preferred_x = 0;
34290 state->cursor = state->string.len;
34291 state->select_start = state->select_end = 0;
34292 state->has_preferred_x = 0;
34296 case NK_KEY_TEXT_LINE_START: {
34298 struct nk_text_find find;
34299 nk_textedit_clamp(state);
34300 nk_textedit_prep_selection_at_cursor(state);
34301 if (state->string.len && state->cursor == state->string.len)
34303 nk_textedit_find_charpos(&find, state,state->cursor, state->single_line,
34305 state->cursor = state->select_end = find.first_char;
34306 state->has_preferred_x = 0;
34308 struct nk_text_find find;
34309 if (state->string.len && state->cursor == state->string.len)
34311 nk_textedit_clamp(state);
34312 nk_textedit_move_to_first(state);
34313 nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
34315 state->cursor = find.first_char;
34316 state->has_preferred_x = 0;
34320 case NK_KEY_TEXT_LINE_END: {
34322 struct nk_text_find find;
34323 nk_textedit_clamp(state);
34324 nk_textedit_prep_selection_at_cursor(state);
34325 nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
34327 state->has_preferred_x = 0;
34328 state->cursor = find.first_char + find.length;
34329 if (find.length > 0 && nk_str_rune_at(&state->string, state->cursor-1) ==
'\n')
34331 state->select_end = state->cursor;
34333 struct nk_text_find find;
34334 nk_textedit_clamp(state);
34335 nk_textedit_move_to_first(state);
34336 nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
34339 state->has_preferred_x = 0;
34340 state->cursor = find.first_char + find.length;
34341 if (find.length > 0 && nk_str_rune_at(&state->string, state->cursor-1) ==
'\n')
34359 state->redo_point = NK_TEXTEDIT_UNDOSTATECOUNT;
34360 state->redo_char_point = NK_TEXTEDIT_UNDOCHARCOUNT;
34376 if (state->undo_point > 0) {
34378 if (state->undo_rec[0].char_storage >= 0) {
34379 int n = state->undo_rec[0].insert_length, i;
34381 state->undo_char_point = (short)(state->undo_char_point - n);
34382 NK_MEMCPY(state->undo_char, state->undo_char + n,
34383 (nk_size)state->undo_char_point*
sizeof(nk_rune));
34384 for (i=0; i < state->undo_point; ++i) {
34385 if (state->undo_rec[i].char_storage >= 0)
34386 state->undo_rec[i].char_storage = (short)
34387 (state->undo_rec[i].char_storage - n);
34390 --state->undo_point;
34391 NK_MEMCPY(state->undo_rec, state->undo_rec+1,
34392 (nk_size)((nk_size)state->undo_point *
sizeof(state->undo_rec[0])));
34413 int k = NK_TEXTEDIT_UNDOSTATECOUNT-1;
34414 if (state->redo_point <= k) {
34416 if (state->undo_rec[k].char_storage >= 0) {
34417 int n = state->undo_rec[k].insert_length, i;
34419 state->redo_char_point = (short)(state->redo_char_point + n);
34420 num = (nk_size)(NK_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point);
34421 NK_MEMCPY(state->undo_char + state->redo_char_point,
34422 state->undo_char + state->redo_char_point-n, num *
sizeof(
char));
34423 for (i = state->redo_point; i < k; ++i) {
34424 if (state->undo_rec[i].char_storage >= 0) {
34425 state->undo_rec[i].char_storage = (short)
34426 (state->undo_rec[i].char_storage + n);
34430 ++state->redo_point;
34431 num = (nk_size)(NK_TEXTEDIT_UNDOSTATECOUNT - state->redo_point);
34432 if (num) NK_MEMCPY(state->undo_rec + state->redo_point-1,
34433 state->undo_rec + state->redo_point, num *
sizeof(state->undo_rec[0]));
34451 nk_textedit_flush_redo(state);
34455 if (state->undo_point == NK_TEXTEDIT_UNDOSTATECOUNT)
34456 nk_textedit_discard_undo(state);
34460 if (numchars > NK_TEXTEDIT_UNDOCHARCOUNT) {
34461 state->undo_point = 0;
34462 state->undo_char_point = 0;
34468 while (state->undo_char_point + numchars > NK_TEXTEDIT_UNDOCHARCOUNT)
34469 nk_textedit_discard_undo(state);
34470 return &state->undo_rec[state->undo_point++];
34485 int insert_len,
int delete_len)
34492 r->insert_length = (short) insert_len;
34493 r->delete_length = (short) delete_len;
34495 if (insert_len == 0) {
34496 r->char_storage = -1;
34499 r->char_storage = state->undo_char_point;
34500 state->undo_char_point = (short)(state->undo_char_point + insert_len);
34501 return &state->undo_char[r->char_storage];
34519 if (s->undo_point == 0)
34523 u = s->undo_rec[s->undo_point-1];
34524 r = &s->undo_rec[s->redo_point-1];
34525 r->char_storage = -1;
34527 r->insert_length = u.delete_length;
34528 r->delete_length = u.insert_length;
34529 r->where = u.where;
34531 if (u.delete_length)
34541 if (s->undo_char_point + u.delete_length >= NK_TEXTEDIT_UNDOCHARCOUNT) {
34544 r->insert_length = 0;
34548 while (s->undo_char_point + u.delete_length > s->redo_char_point) {
34550 nk_textedit_discard_redo(s);
34552 if (s->redo_point == NK_TEXTEDIT_UNDOSTATECOUNT)
34556 r = &s->undo_rec[s->redo_point-1];
34557 r->char_storage = (short)(s->redo_char_point - u.delete_length);
34558 s->redo_char_point = (short)(s->redo_char_point - u.delete_length);
34561 for (i=0; i < u.delete_length; ++i)
34562 s->undo_char[r->char_storage + i] =
34563 nk_str_rune_at(&state->string, u.where + i);
34566 nk_str_delete_runes(&state->string, u.where, u.delete_length);
34570 if (u.insert_length) {
34572 nk_str_insert_text_runes(&state->string, u.where,
34573 &s->undo_char[u.char_storage], u.insert_length);
34574 s->undo_char_point = (short)(s->undo_char_point - u.insert_length);
34576 state->cursor = (short)(u.where + u.insert_length);
34596 if (s->redo_point == NK_TEXTEDIT_UNDOSTATECOUNT)
34600 u = &s->undo_rec[s->undo_point];
34601 r = s->undo_rec[s->redo_point];
34605 u->delete_length = r.insert_length;
34606 u->insert_length = r.delete_length;
34607 u->where = r.where;
34608 u->char_storage = -1;
34610 if (r.delete_length) {
34613 if (s->undo_char_point + u->insert_length > s->redo_char_point) {
34614 u->insert_length = 0;
34615 u->delete_length = 0;
34618 u->char_storage = s->undo_char_point;
34619 s->undo_char_point = (short)(s->undo_char_point + u->insert_length);
34622 for (i=0; i < u->insert_length; ++i) {
34623 s->undo_char[u->char_storage + i] =
34624 nk_str_rune_at(&state->string, u->where + i);
34627 nk_str_delete_runes(&state->string, r.where, r.delete_length);
34630 if (r.insert_length) {
34632 nk_str_insert_text_runes(&state->string, r.where,
34633 &s->undo_char[r.char_storage], r.insert_length);
34635 state->cursor = r.where + r.insert_length;
34653 nk_textedit_makeundo_insert(
struct nk_text_edit *state,
int where,
int length)
34655 nk_textedit_createundo(&state->undo, where, 0, length);
34670 nk_textedit_makeundo_delete(
struct nk_text_edit *state,
int where,
int length)
34673 nk_rune *p = nk_textedit_createundo(&state->undo, where, length, 0);
34675 for (i=0; i < length; ++i)
34676 p[i] = nk_str_rune_at(&state->string, where+i);
34691 nk_textedit_makeundo_replace(
struct nk_text_edit *state,
int where,
34692 int old_length,
int new_length)
34695 nk_rune *p = nk_textedit_createundo(&state->undo, where, old_length, new_length);
34697 for (i=0; i < old_length; ++i)
34698 p[i] = nk_str_rune_at(&state->string, where+i);
34713 nk_textedit_clear_state(
struct nk_text_edit *state,
enum nk_text_edit_type type,
34714 nk_plugin_filter filter)
34717 state->undo.undo_point = 0;
34718 state->undo.undo_char_point = 0;
34719 state->undo.redo_point = NK_TEXTEDIT_UNDOSTATECOUNT;
34720 state->undo.redo_char_point = NK_TEXTEDIT_UNDOCHARCOUNT;
34721 state->select_end = state->select_start = 0;
34723 state->has_preferred_x = 0;
34724 state->preferred_x = 0;
34725 state->cursor_at_end_of_line = 0;
34726 state->initialized = 1;
34727 state->single_line = (
unsigned char)(type == NK_TEXT_EDIT_SINGLE_LINE);
34728 state->mode = NK_TEXT_EDIT_MODE_VIEW;
34729 state->filter = filter;
34730 state->scrollbar =
nk_vec2(0,0);
34745 nk_textedit_init_fixed(
struct nk_text_edit *state,
void *memory, nk_size size)
34749 if (!state || !memory || !size)
return;
34751 nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0);
34752 nk_str_init_fixed(&state->string, memory, size);
34771 if (!state || !alloc)
return;
34773 nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0);
34774 nk_str_init(&state->string, alloc, size);
34776 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
34791 if (!state)
return;
34793 nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0);
34794 nk_str_init_default(&state->string);
34811 state->select_start = 0;
34812 state->select_end = state->string.len;
34828 if (!state)
return;
34829 nk_str_free(&state->string);
34855 NK_UNUSED(unicode);
34871 nk_filter_ascii(
const struct nk_text_edit *box, nk_rune unicode)
34874 if (unicode > 128)
return nk_false;
34875 else return nk_true;
34889 nk_filter_float(
const struct nk_text_edit *box, nk_rune unicode)
34892 if ((unicode < '0' || unicode >
'9') && unicode !=
'.' && unicode !=
'-')
34894 else return nk_true;
34908 nk_filter_decimal(
const struct nk_text_edit *box, nk_rune unicode)
34911 if ((unicode < '0' || unicode >
'9') && unicode !=
'-')
34913 else return nk_true;
34927 nk_filter_hex(
const struct nk_text_edit *box, nk_rune unicode)
34930 if ((unicode < '0' || unicode >
'9') &&
34931 (unicode < 'a' || unicode >
'f') &&
34932 (unicode < 'A' || unicode >
'F'))
34934 else return nk_true;
34948 nk_filter_oct(
const struct nk_text_edit *box, nk_rune unicode)
34951 if (unicode < '0' || unicode >
'7')
34953 else return nk_true;
34967 nk_filter_binary(
const struct nk_text_edit *box, nk_rune unicode)
34970 if (unicode !=
'0' && unicode !=
'1')
34972 else return nk_true;
34992 const struct nk_style_edit *style,
float pos_x,
float pos_y,
34993 float x_offset,
const char *text,
int byte_len,
float row_height,
34995 struct nk_color foreground, nk_bool is_selected)
35000 if (!text || !byte_len || !out || !style)
return;
35002 {
int glyph_len = 0;
35003 nk_rune unicode = 0;
35005 float line_width = 0;
35007 const char *line = text;
35008 float line_offset = 0;
35009 int line_count = 0;
35011 struct nk_text txt;
35013 txt.background = background;
35014 txt.text = foreground;
35016 foreground = nk_rgb_factor(foreground, style->color_factor);
35017 background = nk_rgb_factor(background, style->color_factor);
35019 glyph_len = nk_utf_decode(text+text_len, &unicode, byte_len-text_len);
35020 if (!glyph_len)
return;
35021 while ((text_len < byte_len) && glyph_len)
35023 if (unicode ==
'\n') {
35026 label.y = pos_y + line_offset;
35027 label.h = row_height;
35028 label.w = line_width;
35031 label.x += x_offset;
35035 nk_widget_text(out, label, line, (
int)((text + text_len) - line),
35036 &txt, NK_TEXT_CENTERED, font);
35041 line = text + text_len;
35042 line_offset += row_height;
35043 glyph_len = nk_utf_decode(text + text_len, &unicode, (
int)(byte_len-text_len));
35046 if (unicode ==
'\r') {
35048 glyph_len = nk_utf_decode(text + text_len, &unicode, byte_len-text_len);
35051 glyph_width = font->
width(font->userdata, font->
height, text+text_len, glyph_len);
35052 line_width += (float)glyph_width;
35053 text_len += glyph_len;
35054 glyph_len = nk_utf_decode(text + text_len, &unicode, byte_len-text_len);
35057 if (line_width > 0) {
35060 label.y = pos_y + line_offset;
35061 label.h = row_height;
35062 label.w = line_width;
35065 label.x += x_offset;
35069 nk_widget_text(out, label, line, (
int)((text + text_len) - line),
35070 &txt, NK_TEXT_LEFT, font);
35086 struct nk_rect bounds, nk_flags flags, nk_plugin_filter filter,
35093 char prev_state = 0;
35094 char is_hovered = 0;
35095 char select_all = 0;
35096 char cursor_follow = 0;
35103 if (!state || !out || !style)
35107 area.x = bounds.x + style->padding.x + style->border;
35108 area.y = bounds.y + style->padding.y + style->border;
35109 area.w = bounds.w - (2.0f * style->padding.x + 2 * style->border);
35110 area.h = bounds.h - (2.0f * style->padding.y + 2 * style->border);
35111 if (flags & NK_EDIT_MULTILINE)
35112 area.w = NK_MAX(0, area.w - style->scrollbar_size.x);
35113 row_height = (flags & NK_EDIT_MULTILINE)? font->
height + style->row_padding: area.h;
35116 old_clip = out->clip;
35117 nk_unify(&clip, &old_clip, area.x, area.y, area.x + area.w, area.y + area.h);
35120 prev_state = (char)edit->active;
35121 is_hovered = (
char)nk_input_is_mouse_hovering_rect(in, bounds);
35122 if (in && in->mouse.buttons[NK_BUTTON_LEFT].clicked && in->mouse.buttons[NK_BUTTON_LEFT].down) {
35123 edit->active = NK_INBOX(in->mouse.pos.x, in->mouse.pos.y,
35124 bounds.x, bounds.y, bounds.w, bounds.h);
35128 if (!prev_state && edit->active) {
35129 const enum nk_text_edit_type type = (flags & NK_EDIT_MULTILINE) ?
35130 NK_TEXT_EDIT_MULTI_LINE: NK_TEXT_EDIT_SINGLE_LINE;
35132 struct nk_vec2 oldscrollbar = edit->scrollbar;
35133 nk_textedit_clear_state(edit, type, filter);
35134 edit->scrollbar = oldscrollbar;
35135 if (flags & NK_EDIT_AUTO_SELECT)
35136 select_all = nk_true;
35137 if (flags & NK_EDIT_GOTO_END_ON_ACTIVATE) {
35138 edit->cursor = edit->string.len;
35141 }
else if (!edit->active) edit->mode = NK_TEXT_EDIT_MODE_VIEW;
35142 if (flags & NK_EDIT_READ_ONLY)
35143 edit->mode = NK_TEXT_EDIT_MODE_VIEW;
35144 else if (flags & NK_EDIT_ALWAYS_INSERT_MODE)
35145 edit->mode = NK_TEXT_EDIT_MODE_INSERT;
35148 if (prev_state != edit->active)
35152 if (edit->active && in)
35154 int shift_mod = in->keyboard.keys[NK_KEY_SHIFT].down;
35155 const float mouse_x = (in->mouse.pos.x - area.x) + edit->scrollbar.x;
35156 const float mouse_y = (in->mouse.pos.y - area.y) + edit->scrollbar.y;
35159 is_hovered = (char)nk_input_is_mouse_hovering_rect(in, area);
35161 nk_textedit_select_all(edit);
35162 }
else if (is_hovered && in->mouse.buttons[NK_BUTTON_LEFT].down &&
35163 in->mouse.buttons[NK_BUTTON_LEFT].clicked) {
35164 nk_textedit_click(edit, mouse_x, mouse_y, font, row_height);
35165 }
else if (is_hovered && in->mouse.buttons[NK_BUTTON_LEFT].down &&
35166 (in->mouse.delta.x != 0.0f || in->mouse.delta.y != 0.0f)) {
35167 nk_textedit_drag(edit, mouse_x, mouse_y, font, row_height);
35168 cursor_follow = nk_true;
35169 }
else if (is_hovered && in->mouse.buttons[NK_BUTTON_RIGHT].clicked &&
35170 in->mouse.buttons[NK_BUTTON_RIGHT].down) {
35171 nk_textedit_key(edit, NK_KEY_TEXT_WORD_LEFT, nk_false, font, row_height);
35172 nk_textedit_key(edit, NK_KEY_TEXT_WORD_RIGHT, nk_true, font, row_height);
35173 cursor_follow = nk_true;
35177 int old_mode = edit->mode;
35178 for (i = 0; i < NK_KEY_MAX; ++i) {
35179 if (i == NK_KEY_ENTER || i == NK_KEY_TAB)
continue;
35180 if (nk_input_is_key_pressed(in, (
enum nk_keys)i)) {
35181 nk_textedit_key(edit, (
enum nk_keys)i, shift_mod, font, row_height);
35182 cursor_follow = nk_true;
35185 if (old_mode != edit->mode) {
35186 in->keyboard.text_len = 0;
35190 edit->filter = filter;
35191 if (in->keyboard.text_len) {
35192 nk_textedit_text(edit, in->keyboard.text, in->keyboard.text_len);
35193 cursor_follow = nk_true;
35194 in->keyboard.text_len = 0;
35198 if (nk_input_is_key_pressed(in, NK_KEY_ENTER)) {
35199 cursor_follow = nk_true;
35200 if (flags & NK_EDIT_CTRL_ENTER_NEWLINE && shift_mod)
35201 nk_textedit_text(edit,
"\n", 1);
35202 else if (flags & NK_EDIT_SIG_ENTER)
35204 else nk_textedit_text(edit,
"\n", 1);
35208 {
int copy= nk_input_is_key_pressed(in, NK_KEY_COPY);
35209 int cut = nk_input_is_key_pressed(in, NK_KEY_CUT);
35210 if ((copy || cut) && (flags & NK_EDIT_CLIPBOARD))
35215 int b = edit->select_start;
35216 int e = edit->select_end;
35218 int begin = NK_MIN(b, e);
35219 int end = NK_MAX(b, e);
35220 text = nk_str_at_const(&edit->string, begin, &unicode, &glyph_len);
35221 if (edit->clip.copy)
35222 edit->clip.copy(edit->clip.userdata, text, end - begin);
35223 if (cut && !(flags & NK_EDIT_READ_ONLY)){
35224 nk_textedit_cut(edit);
35225 cursor_follow = nk_true;
35230 {
int paste = nk_input_is_key_pressed(in, NK_KEY_PASTE);
35231 if (paste && (flags & NK_EDIT_CLIPBOARD) && edit->clip.paste) {
35232 edit->clip.paste(edit->clip.userdata, edit);
35233 cursor_follow = nk_true;
35237 {
int tab = nk_input_is_key_pressed(in, NK_KEY_TAB);
35238 if (tab && (flags & NK_EDIT_ALLOW_TAB)) {
35239 nk_textedit_text(edit,
" ", 4);
35240 cursor_follow = nk_true;
35247 else nk_widget_state_reset(state);
35253 {
const char *text = nk_str_get_const(&edit->string);
35254 int len = nk_str_len_char(&edit->string);
35259 background = &style->active;
35261 background = &style->hover;
35262 else background = &style->normal;
35265 switch(background->type) {
35266 case NK_STYLE_ITEM_IMAGE:
35267 nk_draw_image(out, bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
35269 case NK_STYLE_ITEM_NINE_SLICE:
35270 nk_draw_nine_slice(out, bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor));
35272 case NK_STYLE_ITEM_COLOR:
35273 nk_fill_rect(out, bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor));
35274 nk_stroke_rect(out, bounds, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor));
35279 area.w = NK_MAX(0, area.w - style->cursor_size);
35282 int total_lines = 1;
35286 const char *cursor_ptr = 0;
35287 const char *select_begin_ptr = 0;
35288 const char *select_end_ptr = 0;
35295 int selection_begin = NK_MIN(edit->select_start, edit->select_end);
35296 int selection_end = NK_MAX(edit->select_start, edit->select_end);
35299 float line_width = 0.0f;
35305 nk_rune unicode = 0;
35310 glyph_len = nk_utf_decode(text, &unicode, len);
35311 glyph_width = font->
width(font->userdata, font->
height, text, glyph_len);
35315 while ((text_len < len) && glyph_len)
35318 if (!cursor_ptr && glyphs == edit->cursor)
35323 const char *remaining;
35326 cursor_pos.y = (float)(total_lines-1) * row_height;
35327 row_size = nk_text_calculate_text_bounds(font, text+row_begin,
35328 text_len-row_begin, row_height, &remaining,
35329 &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
35330 cursor_pos.x = row_size.x;
35331 cursor_ptr = text + text_len;
35335 if (!select_begin_ptr && edit->select_start != edit->select_end &&
35336 glyphs == selection_begin)
35341 const char *remaining;
35344 selection_offset_start.y = (float)(NK_MAX(total_lines-1,0)) * row_height;
35345 row_size = nk_text_calculate_text_bounds(font, text+row_begin,
35346 text_len-row_begin, row_height, &remaining,
35347 &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
35348 selection_offset_start.x = row_size.x;
35349 select_begin_ptr = text + text_len;
35353 if (!select_end_ptr && edit->select_start != edit->select_end &&
35354 glyphs == selection_end)
35359 const char *remaining;
35362 selection_offset_end.y = (float)(total_lines-1) * row_height;
35363 row_size = nk_text_calculate_text_bounds(font, text+row_begin,
35364 text_len-row_begin, row_height, &remaining,
35365 &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
35366 selection_offset_end.x = row_size.x;
35367 select_end_ptr = text + text_len;
35369 if (unicode ==
'\n') {
35370 text_size.x = NK_MAX(text_size.x, line_width);
35375 row_begin = text_len;
35376 glyph_len = nk_utf_decode(text + text_len, &unicode, len-text_len);
35377 glyph_width = font->
width(font->userdata, font->
height, text+text_len, glyph_len);
35382 text_len += glyph_len;
35383 line_width += (float)glyph_width;
35385 glyph_len = nk_utf_decode(text + text_len, &unicode, len-text_len);
35386 glyph_width = font->
width(font->userdata, font->
height,
35387 text+text_len, glyph_len);
35390 text_size.y = (float)total_lines * row_height;
35393 if (!cursor_ptr && edit->cursor == edit->string.len) {
35394 cursor_pos.x = line_width;
35395 cursor_pos.y = text_size.y - row_height;
35403 if (!(flags & NK_EDIT_NO_HORIZONTAL_SCROLL)) {
35405 const float scroll_increment = area.w * 0.25f;
35406 if (cursor_pos.x < edit->scrollbar.x)
35407 edit->scrollbar.x = (float)(
int)NK_MAX(0.0f, cursor_pos.x - scroll_increment);
35408 if (cursor_pos.x >= edit->scrollbar.x + area.w)
35409 edit->scrollbar.x = (float)(
int)NK_MAX(0.0f, cursor_pos.x - area.w + scroll_increment);
35410 }
else edit->scrollbar.x = 0;
35412 if (flags & NK_EDIT_MULTILINE) {
35414 if (cursor_pos.y < edit->scrollbar.y)
35415 edit->scrollbar.y = NK_MAX(0.0f, cursor_pos.y - row_height);
35416 if (cursor_pos.y >= edit->scrollbar.y + row_height)
35417 edit->scrollbar.y = edit->scrollbar.y + row_height;
35418 }
else edit->scrollbar.y = 0;
35422 if (flags & NK_EDIT_MULTILINE)
35426 float scroll_target;
35427 float scroll_offset;
35432 scroll.x = (bounds.x + bounds.w - style->border) - style->scrollbar_size.x;
35433 scroll.w = style->scrollbar_size.x;
35435 scroll_offset = edit->scrollbar.y;
35436 scroll_step = scroll.h * 0.10f;
35437 scroll_inc = scroll.h * 0.01f;
35438 scroll_target = text_size.y;
35439 edit->scrollbar.y = nk_do_scrollbarv(&ws, out, scroll, 0,
35440 scroll_offset, scroll_target, scroll_step, scroll_inc,
35441 &style->scrollbar, in, font);
35446 {
struct nk_color background_color;
35448 struct nk_color sel_background_color;
35451 struct nk_color cursor_text_color;
35453 nk_push_scissor(out, clip);
35457 background = &style->active;
35458 text_color = style->text_active;
35459 sel_text_color = style->selected_text_hover;
35460 sel_background_color = style->selected_hover;
35461 cursor_color = style->cursor_hover;
35462 cursor_text_color = style->cursor_text_hover;
35464 background = &style->hover;
35465 text_color = style->text_hover;
35466 sel_text_color = style->selected_text_hover;
35467 sel_background_color = style->selected_hover;
35468 cursor_text_color = style->cursor_text_hover;
35469 cursor_color = style->cursor_hover;
35471 background = &style->normal;
35472 text_color = style->text_normal;
35473 sel_text_color = style->selected_text_normal;
35474 sel_background_color = style->selected_normal;
35475 cursor_color = style->cursor_normal;
35476 cursor_text_color = style->cursor_text_normal;
35478 if (background->type == NK_STYLE_ITEM_IMAGE)
35479 background_color = nk_rgba(0,0,0,0);
35481 background_color = background->data.color;
35483 cursor_color = nk_rgb_factor(cursor_color, style->color_factor);
35484 cursor_text_color = nk_rgb_factor(cursor_text_color, style->color_factor);
35486 if (edit->select_start == edit->select_end) {
35488 const char *begin = nk_str_get_const(&edit->string);
35489 int l = nk_str_len_char(&edit->string);
35490 nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
35491 area.y - edit->scrollbar.y, 0, begin, l, row_height, font,
35492 background_color, text_color, nk_false);
35495 if (edit->select_start != edit->select_end && selection_begin > 0){
35497 const char *begin = nk_str_get_const(&edit->string);
35498 NK_ASSERT(select_begin_ptr);
35499 nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
35500 area.y - edit->scrollbar.y, 0, begin, (
int)(select_begin_ptr - begin),
35501 row_height, font, background_color, text_color, nk_false);
35503 if (edit->select_start != edit->select_end) {
35505 NK_ASSERT(select_begin_ptr);
35506 if (!select_end_ptr) {
35507 const char *begin = nk_str_get_const(&edit->string);
35508 select_end_ptr = begin + nk_str_len_char(&edit->string);
35510 nk_edit_draw_text(out, style,
35511 area.x - edit->scrollbar.x,
35512 area.y + selection_offset_start.y - edit->scrollbar.y,
35513 selection_offset_start.x,
35514 select_begin_ptr, (
int)(select_end_ptr - select_begin_ptr),
35515 row_height, font, sel_background_color, sel_text_color, nk_true);
35517 if ((edit->select_start != edit->select_end &&
35518 selection_end < edit->
string.len))
35521 const char *begin = select_end_ptr;
35522 const char *end = nk_str_get_const(&edit->string) +
35523 nk_str_len_char(&edit->string);
35524 NK_ASSERT(select_end_ptr);
35525 nk_edit_draw_text(out, style,
35526 area.x - edit->scrollbar.x,
35527 area.y + selection_offset_end.y - edit->scrollbar.y,
35528 selection_offset_end.x,
35529 begin, (
int)(end - begin), row_height, font,
35530 background_color, text_color, nk_true);
35535 if (edit->select_start == edit->select_end)
35537 if (edit->cursor >= nk_str_len(&edit->string) ||
35538 (cursor_ptr && *cursor_ptr ==
'\n')) {
35541 cursor.w = style->cursor_size;
35542 cursor.h = font->
height;
35543 cursor.x = area.x + cursor_pos.x - edit->scrollbar.x;
35544 cursor.y = area.y + cursor_pos.y + row_height/2.0f - cursor.h/2.0f;
35545 cursor.y -= edit->scrollbar.y;
35551 struct nk_text txt;
35554 NK_ASSERT(cursor_ptr);
35555 glyph_len = nk_utf_decode(cursor_ptr, &unicode, 4);
35557 label.x = area.x + cursor_pos.x - edit->scrollbar.x;
35558 label.y = area.y + cursor_pos.y - edit->scrollbar.y;
35559 label.w = font->
width(font->userdata, font->
height, cursor_ptr, glyph_len);
35560 label.h = row_height;
35563 txt.background = cursor_color;;
35564 txt.text = cursor_text_color;
35566 nk_widget_text(out, label, cursor_ptr, glyph_len, &txt, NK_TEXT_LEFT, font);
35571 int l = nk_str_len_char(&edit->string);
35572 const char *begin = nk_str_get_const(&edit->string);
35577 nk_push_scissor(out, clip);
35579 background = &style->active;
35580 text_color = style->text_active;
35582 background = &style->hover;
35583 text_color = style->text_hover;
35585 background = &style->normal;
35586 text_color = style->text_normal;
35588 if (background->type == NK_STYLE_ITEM_IMAGE)
35589 background_color = nk_rgba(0,0,0,0);
35591 background_color = background->data.color;
35593 background_color = nk_rgb_factor(background_color, style->color_factor);
35594 text_color = nk_rgb_factor(text_color, style->color_factor);
35596 nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
35597 area.y - edit->scrollbar.y, 0, begin, l, row_height, font,
35598 background_color, text_color, nk_false);
35600 nk_push_scissor(out, old_clip);}
35615 nk_edit_focus(
struct nk_context *ctx, nk_flags flags)
35621 NK_ASSERT(ctx->current);
35622 if (!ctx || !ctx->current)
return;
35624 win = ctx->current;
35625 hash = win->edit.seq;
35626 win->edit.active = nk_true;
35627 win->edit.name = hash;
35628 if (flags & NK_EDIT_ALWAYS_INSERT_MODE)
35629 win->edit.mode = NK_TEXT_EDIT_MODE_INSERT;
35646 NK_ASSERT(ctx->current);
35647 if (!ctx || !ctx->current)
return;
35649 win = ctx->current;
35650 win->edit.active = nk_false;
35651 win->edit.name = 0;
35665 nk_edit_string(
struct nk_context *ctx, nk_flags flags,
35666 char *memory,
int *len,
int max, nk_plugin_filter filter)
35676 if (!ctx || !memory || !len)
35680 win = ctx->current;
35681 hash = win->edit.seq;
35683 nk_textedit_clear_state(&ctx->
text_edit, (flags & NK_EDIT_MULTILINE)?
35684 NK_TEXT_EDIT_MULTI_LINE: NK_TEXT_EDIT_SINGLE_LINE, filter);
35686 if (win->edit.active && hash == win->edit.name) {
35687 if (flags & NK_EDIT_NO_CURSOR)
35688 edit->cursor = nk_utf_len(memory, *len);
35689 else edit->cursor = win->edit.cursor;
35690 if (!(flags & NK_EDIT_SELECTABLE)) {
35691 edit->select_start = win->edit.cursor;
35692 edit->select_end = win->edit.cursor;
35694 edit->select_start = win->edit.sel_start;
35695 edit->select_end = win->edit.sel_end;
35697 edit->mode = win->edit.mode;
35698 edit->scrollbar.x = (float)win->edit.scrollbar.x;
35699 edit->scrollbar.y = (
float)win->edit.scrollbar.y;
35700 edit->active = nk_true;
35701 }
else edit->active = nk_false;
35703 max = NK_MAX(1, max);
35704 *len = NK_MIN(*len, max-1);
35705 nk_str_init_fixed(&edit->string, memory, (nk_size)max);
35706 edit->string.buffer.
allocated = (nk_size)*len;
35707 edit->string.len = nk_utf_len(memory, *len);
35708 state = nk_edit_buffer(ctx, flags, edit, filter);
35709 *len = (int)edit->string.buffer.
allocated;
35711 if (edit->active) {
35712 win->edit.cursor = edit->cursor;
35713 win->edit.sel_start = edit->select_start;
35714 win->edit.sel_end = edit->select_end;
35715 win->edit.mode = edit->mode;
35716 win->edit.scrollbar.x = (nk_uint)edit->scrollbar.x;
35717 win->edit.scrollbar.y = (nk_uint)edit->scrollbar.y;
35732 nk_edit_buffer(
struct nk_context *ctx, nk_flags flags,
35742 nk_flags ret_flags = 0;
35743 unsigned char prev_state;
35749 NK_ASSERT(ctx->current);
35750 NK_ASSERT(ctx->current->layout);
35751 if (!ctx || !ctx->current || !ctx->current->layout)
35754 win = ctx->current;
35755 style = &ctx->style;
35756 state = nk_widget(&bounds, ctx);
35757 if (!state)
return state;
35759 flags |= NK_EDIT_READ_ONLY;
35760 in = (win->layout->flags &
NK_WINDOW_ROM) ? 0 : &ctx->input;
35763 hash = win->edit.seq++;
35764 if (win->edit.active && hash == win->edit.name) {
35765 if (flags & NK_EDIT_NO_CURSOR)
35766 edit->cursor = edit->string.len;
35767 if (!(flags & NK_EDIT_SELECTABLE)) {
35768 edit->select_start = edit->cursor;
35769 edit->select_end = edit->cursor;
35771 if (flags & NK_EDIT_CLIPBOARD)
35772 edit->clip = ctx->clip;
35773 edit->active = (
unsigned char)win->edit.active;
35774 }
else edit->active = nk_false;
35775 edit->mode = win->edit.mode;
35778 prev_state = (
unsigned char)edit->active;
35779 in = (flags & NK_EDIT_READ_ONLY) ? 0: in;
35780 ret_flags = nk_do_edit(&ctx->last_widget_state, &win->buffer, bounds, flags,
35781 filter, edit, &style->edit, in, style->font);
35784 ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_TEXT];
35785 if (edit->active && prev_state != edit->active) {
35787 win->edit.active = nk_true;
35788 win->edit.name = hash;
35789 }
else if (prev_state && !edit->active) {
35791 win->edit.active = nk_false;
35792 }
return ret_flags;
35806 nk_edit_string_zero_terminated(
struct nk_context *ctx, nk_flags flags,
35807 char *buffer,
int max, nk_plugin_filter filter)
35810 int len = nk_strlen(buffer);
35811 result = nk_edit_string(ctx, flags, buffer, &len, max, filter);
35812 buffer[NK_MIN(NK_MAX(max-1,0), len)] =
'\0';
35837 nk_drag_behavior(nk_flags *state,
const struct nk_input *in,
35838 struct nk_rect drag,
struct nk_property_variant *variant,
35839 float inc_per_pixel)
35841 int left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
35842 int left_mouse_click_in_cursor = in &&
35843 nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, drag, nk_true);
35845 nk_widget_state_reset(state);
35846 if (nk_input_is_mouse_hovering_rect(in, drag))
35849 if (left_mouse_down && left_mouse_click_in_cursor) {
35850 float delta, pixels;
35851 pixels = in->mouse.delta.x;
35852 delta = pixels * inc_per_pixel;
35853 switch (variant->kind) {
35855 case NK_PROPERTY_INT:
35856 variant->value.i = variant->value.i + (int)delta;
35857 variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
35859 case NK_PROPERTY_FLOAT:
35860 variant->value.f = variant->value.f + (float)delta;
35861 variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
35863 case NK_PROPERTY_DOUBLE:
35864 variant->value.d = variant->value.d + (double)delta;
35865 variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
35872 else if (nk_input_is_mouse_prev_hovering_rect(in, drag))
35887 nk_property_behavior(nk_flags *ws,
const struct nk_input *in,
35889 struct nk_rect empty,
int *state,
struct nk_property_variant *variant,
35890 float inc_per_pixel)
35892 nk_widget_state_reset(ws);
35893 if (in && *state == NK_PROPERTY_DEFAULT) {
35894 if (nk_button_behavior(ws, edit, in, NK_BUTTON_DEFAULT))
35895 *state = NK_PROPERTY_EDIT;
35896 else if (nk_input_is_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, label, nk_true))
35897 *state = NK_PROPERTY_DRAG;
35898 else if (nk_input_is_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, empty, nk_true))
35899 *state = NK_PROPERTY_DRAG;
35901 if (*state == NK_PROPERTY_DRAG) {
35902 nk_drag_behavior(ws, in, property, variant, inc_per_pixel);
35919 const struct nk_rect *bounds,
const struct nk_rect *label, nk_flags state,
35920 const char *name,
int len,
const struct nk_user_font *font)
35922 struct nk_text text;
35927 background = &style->active;
35928 text.text = style->label_active;
35930 background = &style->hover;
35931 text.text = style->label_hover;
35933 background = &style->normal;
35934 text.text = style->label_normal;
35937 text.text = nk_rgb_factor(text.text, style->color_factor);
35940 switch(background->type) {
35941 case NK_STYLE_ITEM_IMAGE:
35942 text.background = nk_rgba(0, 0, 0, 0);
35943 nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
35945 case NK_STYLE_ITEM_NINE_SLICE:
35946 text.background = nk_rgba(0, 0, 0, 0);
35947 nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor));
35949 case NK_STYLE_ITEM_COLOR:
35950 text.background = background->data.color;
35951 nk_fill_rect(out, *bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor));
35952 nk_stroke_rect(out, *bounds, style->rounding, style->border, nk_rgb_factor(background->data.color, style->color_factor));
35958 if (name && name[0] !=
'#') {
35959 nk_widget_text(out, *label, name, len, &text, NK_TEXT_CENTERED, font);
35973 nk_do_property(nk_flags *ws,
35975 const char *name,
struct nk_property_variant *variant,
35976 float inc_per_pixel,
char *buffer,
int *len,
35977 int *state,
int *cursor,
int *select_begin,
int *select_end,
35979 enum nk_property_filter filter,
struct nk_input *in,
35981 enum nk_button_behavior behavior)
35983 const nk_plugin_filter filters[] = {
35987 nk_bool active, old;
35988 int num_len = 0, name_len = 0;
35989 char string[NK_MAX_NUMBER_BUFFER];
36002 left.h = font->
height/2;
36004 left.x =
property.x + style->border + style->padding.x;
36005 left.y =
property.y + style->border +
property.h/2.0f - left.h/2;
36008 if (name && name[0] !=
'#') {
36009 name_len = nk_strlen(name);
36011 size = font->
width(font->userdata, font->
height, name, name_len);
36012 label.x = left.x + left.w + style->padding.x;
36013 label.w = (float)size + 2 * style->padding.x;
36014 label.y = property.y + style->border + style->padding.y;
36015 label.h = property.h - (2 * style->border + 2 * style->padding.y);
36021 right.x =
property.x +
property.w - (right.w + style->padding.x);
36024 if (*state == NK_PROPERTY_EDIT) {
36025 size = font->
width(font->userdata, font->
height, buffer, *len);
36026 size += style->edit.cursor_size;
36030 switch (variant->kind) {
36032 case NK_PROPERTY_INT:
36033 nk_itoa(
string, variant->value.i);
36034 num_len = nk_strlen(
string);
36036 case NK_PROPERTY_FLOAT:
36037 NK_DTOA(
string, (
double)variant->value.f);
36038 num_len = nk_string_float_limit(
string, NK_MAX_FLOAT_PRECISION);
36040 case NK_PROPERTY_DOUBLE:
36041 NK_DTOA(
string, variant->value.d);
36042 num_len = nk_string_float_limit(
string, NK_MAX_FLOAT_PRECISION);
36045 size = font->
width(font->userdata, font->
height,
string, num_len);
36050 edit.w = (float)size + 2 * style->padding.x;
36051 edit.w = NK_MIN(edit.w, right.x - (label.x + label.w));
36052 edit.x = right.x - (edit.w + style->padding.x);
36053 edit.y =
property.y + style->border;
36054 edit.h =
property.h - (2 * style->border);
36057 empty.w = edit.x - (label.x + label.w);
36058 empty.x = label.x + label.w;
36059 empty.y =
property.y;
36060 empty.h =
property.h;
36063 old = (*state == NK_PROPERTY_EDIT);
36064 nk_property_behavior(ws, in, property, label, edit, empty, state, variant, inc_per_pixel);
36067 if (style->draw_begin) style->draw_begin(out, style->userdata);
36068 nk_draw_property(out, style, &property, &label, *ws, name, name_len, font);
36069 if (style->draw_end) style->draw_end(out, style->userdata);
36072 if (nk_do_button_symbol(ws, out, left, style->sym_left, behavior, &style->dec_button, in, font)) {
36073 switch (variant->kind) {
36075 case NK_PROPERTY_INT:
36076 variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i - variant->step.i, variant->max_value.i);
break;
36077 case NK_PROPERTY_FLOAT:
36078 variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f - variant->step.f, variant->max_value.f);
break;
36079 case NK_PROPERTY_DOUBLE:
36080 variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d - variant->step.d, variant->max_value.d);
break;
36084 if (nk_do_button_symbol(ws, out, right, style->sym_right, behavior, &style->inc_button, in, font)) {
36085 switch (variant->kind) {
36087 case NK_PROPERTY_INT:
36088 variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i + variant->step.i, variant->max_value.i);
break;
36089 case NK_PROPERTY_FLOAT:
36090 variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f + variant->step.f, variant->max_value.f);
break;
36091 case NK_PROPERTY_DOUBLE:
36092 variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d + variant->step.d, variant->max_value.d);
break;
36095 if (old != NK_PROPERTY_EDIT && (*state == NK_PROPERTY_EDIT)) {
36097 NK_MEMCPY(buffer, dst, (nk_size)*length);
36098 *cursor = nk_utf_len(buffer, *length);
36103 }
else active = (*state == NK_PROPERTY_EDIT);
36106 nk_textedit_clear_state(text_edit, NK_TEXT_EDIT_SINGLE_LINE, filters[filter]);
36107 text_edit->active = (
unsigned char)active;
36108 text_edit->string.len = *length;
36109 text_edit->cursor = NK_CLAMP(0, *cursor, *length);
36110 text_edit->select_start = NK_CLAMP(0,*select_begin, *length);
36111 text_edit->select_end = NK_CLAMP(0,*select_end, *length);
36112 text_edit->string.buffer.
allocated = (nk_size)*length;
36113 text_edit->string.buffer.
memory.size = NK_MAX_NUMBER_BUFFER;
36114 text_edit->string.buffer.
memory.ptr = dst;
36115 text_edit->string.buffer.
size = NK_MAX_NUMBER_BUFFER;
36116 text_edit->mode = NK_TEXT_EDIT_MODE_INSERT;
36117 nk_do_edit(ws, out, edit, (
int)NK_EDIT_FIELD|(
int)NK_EDIT_AUTO_SELECT,
36118 filters[filter], text_edit, &style->edit, (*state == NK_PROPERTY_EDIT) ? in: 0, font);
36120 *length = text_edit->string.len;
36121 *cursor = text_edit->cursor;
36122 *select_begin = text_edit->select_start;
36123 *select_end = text_edit->select_end;
36124 if (text_edit->active && nk_input_is_key_pressed(in, NK_KEY_ENTER))
36125 text_edit->active = nk_false;
36127 if (active && !text_edit->active) {
36129 *state = NK_PROPERTY_DEFAULT;
36130 buffer[*len] =
'\0';
36131 switch (variant->kind) {
36133 case NK_PROPERTY_INT:
36134 variant->value.i = nk_strtoi(buffer, 0);
36135 variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
36137 case NK_PROPERTY_FLOAT:
36138 nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
36139 variant->value.f = nk_strtof(buffer, 0);
36140 variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
36142 case NK_PROPERTY_DOUBLE:
36143 nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
36144 variant->value.d = nk_strtod(buffer, 0);
36145 variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
36163 NK_LIB
struct nk_property_variant
36164 nk_property_variant_int(int value, int min_value, int max_value, int step)
36166 struct nk_property_variant result;
36167 result.kind = NK_PROPERTY_INT;
36168 result.value.i = value;
36169 result.min_value.i = min_value;
36170 result.max_value.i = max_value;
36171 result.step.i = step;
36187 NK_LIB
struct nk_property_variant
36188 nk_property_variant_float(float value, float min_value, float max_value, float step)
36190 struct nk_property_variant result;
36191 result.kind = NK_PROPERTY_FLOAT;
36192 result.value.f = value;
36193 result.min_value.f = min_value;
36194 result.max_value.f = max_value;
36195 result.step.f = step;
36210 NK_LIB
struct nk_property_variant
36211 nk_property_variant_double(double value, double min_value, double max_value,
36214 struct nk_property_variant result;
36215 result.kind = NK_PROPERTY_DOUBLE;
36216 result.value.d = value;
36217 result.min_value.d = min_value;
36218 result.max_value.d = max_value;
36219 result.step.d = step;
36235 nk_property(
struct nk_context *ctx,
const char *name,
struct nk_property_variant *variant,
36236 float inc_per_pixel,
const enum nk_property_filter filter)
36251 int *select_begin = 0;
36252 int *select_end = 0;
36255 char dummy_buffer[NK_MAX_NUMBER_BUFFER];
36256 int dummy_state = NK_PROPERTY_DEFAULT;
36257 int dummy_length = 0;
36258 int dummy_cursor = 0;
36259 int dummy_select_begin = 0;
36260 int dummy_select_end = 0;
36263 NK_ASSERT(ctx->current);
36264 NK_ASSERT(ctx->current->layout);
36265 if (!ctx || !ctx->current || !ctx->current->layout)
36268 win = ctx->current;
36269 layout = win->layout;
36270 style = &ctx->style;
36271 s = nk_widget(&bounds, ctx);
36275 if (name[0] ==
'#') {
36276 hash = nk_murmur_hash(name, (
int)nk_strlen(name), win->property.seq++);
36278 }
else hash = nk_murmur_hash(name, (
int)nk_strlen(name), 42);
36281 if (win->property.active && hash == win->property.name) {
36282 buffer = win->property.buffer;
36283 len = &win->property.length;
36284 cursor = &win->property.cursor;
36285 state = &win->property.state;
36286 select_begin = &win->property.select_start;
36287 select_end = &win->property.select_end;
36289 buffer = dummy_buffer;
36290 len = &dummy_length;
36291 cursor = &dummy_cursor;
36292 state = &dummy_state;
36293 select_begin = &dummy_select_begin;
36294 select_end = &dummy_select_end;
36298 old_state = *state;
36302 nk_do_property(&ctx->last_widget_state, &win->buffer, bounds, name,
36303 variant, inc_per_pixel, buffer, len, state, cursor, select_begin,
36304 select_end, &style->property, filter, in, style->font, &ctx->
text_edit,
36305 ctx->button_behavior);
36307 if (in && *state != NK_PROPERTY_DEFAULT && !win->property.active) {
36309 win->property.active = 1;
36310 NK_MEMCPY(win->property.buffer, buffer, (nk_size)*len);
36311 win->property.length = *len;
36312 win->property.cursor = *cursor;
36313 win->property.state = *state;
36314 win->property.name = hash;
36315 win->property.select_start = *select_begin;
36316 win->property.select_end = *select_end;
36317 if (*state == NK_PROPERTY_DRAG) {
36318 ctx->input.mouse.grab = nk_true;
36319 ctx->input.mouse.grabbed = nk_true;
36323 if (*state == NK_PROPERTY_DEFAULT && old_state != NK_PROPERTY_DEFAULT) {
36324 if (old_state == NK_PROPERTY_DRAG) {
36325 ctx->input.mouse.grab = nk_false;
36326 ctx->input.mouse.grabbed = nk_false;
36327 ctx->input.mouse.ungrab = nk_true;
36329 win->property.select_start = 0;
36330 win->property.select_end = 0;
36331 win->property.active = 0;
36346 nk_property_int(
struct nk_context *ctx,
const char *name,
36347 int min,
int *val,
int max,
int step,
float inc_per_pixel)
36349 struct nk_property_variant variant;
36354 if (!ctx || !ctx->current || !name || !val)
return;
36355 variant = nk_property_variant_int(*val, min, max, step);
36356 nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_INT);
36357 *val = variant.value.i;
36372 float min,
float *val,
float max,
float step,
float inc_per_pixel)
36374 struct nk_property_variant variant;
36379 if (!ctx || !ctx->current || !name || !val)
return;
36380 variant = nk_property_variant_float(*val, min, max, step);
36381 nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
36382 *val = variant.value.f;
36397 double min,
double *val,
double max,
double step,
float inc_per_pixel)
36399 struct nk_property_variant variant;
36404 if (!ctx || !ctx->current || !name || !val)
return;
36405 variant = nk_property_variant_double(*val, min, max, step);
36406 nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
36407 *val = variant.value.d;
36424 int max,
int step,
float inc_per_pixel)
36426 struct nk_property_variant variant;
36430 if (!ctx || !ctx->current || !name)
return val;
36431 variant = nk_property_variant_int(val, min, max, step);
36432 nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_INT);
36433 val = variant.value.i;
36450 float val,
float max,
float step,
float inc_per_pixel)
36452 struct nk_property_variant variant;
36456 if (!ctx || !ctx->current || !name)
return val;
36457 variant = nk_property_variant_float(val, min, max, step);
36458 nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
36459 val = variant.value.f;
36476 double val,
double max,
double step,
float inc_per_pixel)
36478 struct nk_property_variant variant;
36482 if (!ctx || !ctx->current || !name)
return val;
36483 variant = nk_property_variant_double(val, min, max, step);
36484 nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
36485 val = variant.value.d;
36510 nk_chart_begin_colored(
struct nk_context *ctx,
enum nk_chart_type type,
36512 int count,
float min_value,
float max_value)
36520 struct nk_rect bounds = {0, 0, 0, 0};
36523 NK_ASSERT(ctx->current);
36524 NK_ASSERT(ctx->current->layout);
36526 if (!ctx || !ctx->current || !ctx->current->layout)
return 0;
36527 if (!nk_widget(&bounds, ctx)) {
36528 chart = &ctx->current->layout->chart;
36529 nk_zero(chart,
sizeof(*chart));
36533 win = ctx->current;
36534 config = &ctx->style;
36535 chart = &win->layout->chart;
36536 style = &config->chart;
36539 nk_zero(chart,
sizeof(*chart));
36540 chart->x = bounds.x + style->padding.x;
36541 chart->y = bounds.y + style->padding.y;
36542 chart->w = bounds.w - 2 * style->padding.x;
36543 chart->h = bounds.h - 2 * style->padding.y;
36544 chart->w = NK_MAX(chart->w, 2 * style->padding.x);
36545 chart->h = NK_MAX(chart->h, 2 * style->padding.y);
36548 {
struct nk_chart_slot *slot = &chart->slots[chart->slot++];
36550 slot->count = count;
36551 slot->color = nk_rgb_factor(color, style->color_factor);
36552 slot->highlight = highlight;
36553 slot->min = NK_MIN(min_value, max_value);
36554 slot->max = NK_MAX(min_value, max_value);
36555 slot->range = slot->max - slot->min;
36556 slot->show_markers = style->show_markers;}
36559 background = &style->background;
36561 switch(background->type) {
36562 case NK_STYLE_ITEM_IMAGE:
36563 nk_draw_image(&win->buffer, bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
36565 case NK_STYLE_ITEM_NINE_SLICE:
36566 nk_draw_nine_slice(&win->buffer, bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor));
36568 case NK_STYLE_ITEM_COLOR:
36569 nk_fill_rect(&win->buffer, bounds, style->rounding, nk_rgb_factor(style->border_color, style->color_factor));
36570 nk_fill_rect(&win->buffer, nk_shrink_rect(bounds, style->border),
36571 style->rounding, nk_rgb_factor(style->background.data.color, style->color_factor));
36588 nk_chart_begin(
struct nk_context *ctx,
const enum nk_chart_type type,
36589 int count,
float min_value,
float max_value)
36591 return nk_chart_begin_colored(ctx, type, ctx->style.chart.color,
36592 ctx->style.chart.selected_color, count, min_value, max_value);
36606 nk_chart_add_slot_colored(
struct nk_context *ctx,
const enum nk_chart_type type,
36608 int count,
float min_value,
float max_value)
36613 NK_ASSERT(ctx->current);
36614 NK_ASSERT(ctx->current->layout);
36615 NK_ASSERT(ctx->current->layout->chart.slot < NK_CHART_MAX_SLOT);
36616 if (!ctx || !ctx->current || !ctx->current->layout)
return;
36617 if (ctx->current->layout->chart.slot >= NK_CHART_MAX_SLOT)
return;
36619 style = &ctx->style.chart;
36622 {
struct nk_chart *chart = &ctx->current->layout->chart;
36625 slot->count = count;
36626 slot->color = nk_rgb_factor(color, style->color_factor);
36627 slot->highlight = highlight;
36628 slot->min = NK_MIN(min_value, max_value);
36629 slot->max = NK_MAX(min_value, max_value);
36630 slot->range = slot->max - slot->min;
36631 slot->show_markers = style->show_markers;}
36645 nk_chart_add_slot(
struct nk_context *ctx,
const enum nk_chart_type type,
36646 int count,
float min_value,
float max_value)
36648 nk_chart_add_slot_colored(ctx, type, ctx->style.chart.color,
36649 ctx->style.chart.selected_color, count, min_value, max_value);
36664 struct nk_chart *g,
float value,
int slot)
36666 struct nk_panel *layout = win->layout;
36667 const struct nk_input *i = ctx->current->widgets_disabled ? 0 : &ctx->input;
36678 NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT);
36679 step = g->w / (float)g->slots[slot].count;
36680 range = g->slots[slot].max - g->slots[slot].min;
36681 ratio = (value - g->slots[slot].min) / range;
36683 if (g->slots[slot].index == 0) {
36685 g->slots[slot].last.x = g->x;
36686 g->slots[slot].last.y = (g->y + g->h) - ratio * (
float)g->h;
36688 bounds.x = g->slots[slot].last.x - 2;
36689 bounds.y = g->slots[slot].last.y - 2;
36690 bounds.w = bounds.h = 4;
36692 color = g->slots[slot].color;
36694 NK_INBOX(i->mouse.pos.x,i->mouse.pos.y, g->slots[slot].last.x-3, g->slots[slot].last.y-3, 6, 6)){
36695 ret = nk_input_is_mouse_hovering_rect(i, bounds) ? NK_CHART_HOVERING : 0;
36696 ret |= (i->mouse.buttons[NK_BUTTON_LEFT].down &&
36697 i->mouse.buttons[NK_BUTTON_LEFT].clicked) ? NK_CHART_CLICKED: 0;
36698 color = g->slots[slot].highlight;
36700 if (g->slots[slot].show_markers) {
36703 g->slots[slot].index += 1;
36708 color = g->slots[slot].color;
36709 cur.x = g->x + (float)(step * (
float)g->slots[slot].index);
36710 cur.y = (g->y + g->h) - (ratio * (
float)g->h);
36711 nk_stroke_line(out, g->slots[slot].last.x, g->slots[slot].last.y, cur.x, cur.y, 1.0f, color);
36713 bounds.x = cur.x - 3;
36714 bounds.y = cur.y - 3;
36715 bounds.w = bounds.h = 6;
36719 if (nk_input_is_mouse_hovering_rect(i, bounds)) {
36720 ret = NK_CHART_HOVERING;
36721 ret |= (!i->mouse.buttons[NK_BUTTON_LEFT].down &&
36722 i->mouse.buttons[NK_BUTTON_LEFT].clicked) ? NK_CHART_CLICKED: 0;
36723 color = g->slots[slot].highlight;
36726 if (g->slots[slot].show_markers) {
36731 g->slots[slot].last.x = cur.x;
36732 g->slots[slot].last.y = cur.y;
36733 g->slots[slot].index += 1;
36749 struct nk_chart *chart,
float value,
int slot)
36752 const struct nk_input *in = ctx->current->widgets_disabled ? 0 : &ctx->input;
36753 struct nk_panel *layout = win->layout;
36758 struct nk_rect item = {0,0,0,0};
36760 NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT);
36761 if (chart->slots[slot].index >= chart->slots[slot].count)
36763 if (chart->slots[slot].count) {
36764 float padding = (float)(chart->slots[slot].count-1);
36765 item.w = (chart->w - padding) / (
float)(chart->slots[slot].count);
36769 color = chart->slots[slot].color;;
36770 item.h = chart->h * NK_ABS((value/chart->slots[slot].range));
36772 ratio = (value + NK_ABS(chart->slots[slot].min)) / NK_ABS(chart->slots[slot].range);
36773 item.y = (chart->y + chart->h) - chart->h * ratio;
36775 ratio = (value - chart->slots[slot].max) / chart->slots[slot].range;
36776 item.y = chart->y + (chart->h * NK_ABS(ratio)) - item.h;
36778 item.x = chart->x + ((float)chart->slots[slot].index * item.w);
36779 item.x = item.x + ((float)chart->slots[slot].index);
36783 NK_INBOX(in->mouse.pos.x,in->mouse.pos.y,item.x,item.y,item.w,item.h)) {
36784 ret = NK_CHART_HOVERING;
36785 ret |= (!in->mouse.buttons[NK_BUTTON_LEFT].down &&
36786 in->mouse.buttons[NK_BUTTON_LEFT].clicked) ? NK_CHART_CLICKED: 0;
36787 color = chart->slots[slot].highlight;
36790 chart->slots[slot].index += 1;
36806 nk_chart_push_slot(
struct nk_context *ctx,
float value,
int slot)
36812 NK_ASSERT(ctx->current);
36813 NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT);
36814 NK_ASSERT(slot < ctx->current->layout->chart.slot);
36815 if (!ctx || !ctx->current || slot >= NK_CHART_MAX_SLOT)
return nk_false;
36816 if (slot >= ctx->current->layout->chart.slot)
return nk_false;
36818 win = ctx->current;
36819 if (win->layout->chart.slot < slot)
return nk_false;
36820 switch (win->layout->chart.slots[slot].type) {
36821 case NK_CHART_LINES:
36822 flags = nk_chart_push_line(ctx, win, &win->layout->chart, value, slot);
break;
36823 case NK_CHART_COLUMN:
36824 flags = nk_chart_push_column(ctx, win, &win->layout->chart, value, slot);
break;
36843 nk_chart_push(
struct nk_context *ctx,
float value)
36845 return nk_chart_push_slot(ctx, value, 0);
36864 NK_ASSERT(ctx->current);
36865 if (!ctx || !ctx->current)
36868 win = ctx->current;
36869 chart = &win->layout->chart;
36870 NK_MEMSET(chart, 0,
sizeof(*chart));
36886 nk_plot(
struct nk_context *ctx,
enum nk_chart_type type,
const float *values,
36887 int count,
int offset)
36895 if (!ctx || !values || !count)
return;
36897 min_value = values[offset];
36898 max_value = values[offset];
36899 for (i = 0; i < count; ++i) {
36900 min_value = NK_MIN(values[i + offset], min_value);
36901 max_value = NK_MAX(values[i + offset], max_value);
36904 if (nk_chart_begin(ctx, type, count, min_value, max_value)) {
36905 for (i = 0; i < count; ++i)
36906 nk_chart_push(ctx, values[i + offset]);
36923 nk_plot_function(
struct nk_context *ctx,
enum nk_chart_type type,
void *userdata,
36924 float(*value_getter)(
void* user,
int index),
int count,
int offset)
36931 NK_ASSERT(value_getter);
36932 if (!ctx || !value_getter || !count)
return;
36934 max_value = min_value = value_getter(userdata, offset);
36935 for (i = 0; i < count; ++i) {
36936 float value = value_getter(userdata, i + offset);
36937 min_value = NK_MIN(value, min_value);
36938 max_value = NK_MAX(value, max_value);
36941 if (nk_chart_begin(ctx, type, count, min_value, max_value)) {
36942 for (i = 0; i < count; ++i)
36943 nk_chart_push(ctx, value_getter(userdata, i + offset));
36968 nk_color_picker_behavior(nk_flags *state,
36974 nk_bool value_changed = 0;
36975 nk_bool hsv_changed = 0;
36979 NK_ASSERT(hue_bar);
36983 nk_colorf_hsva_fv(hsva, *color);
36984 if (nk_button_behavior(state, *matrix, in, NK_BUTTON_REPEATER)) {
36985 hsva[1] = NK_SATURATE((in->mouse.pos.x - matrix->x) / (matrix->w-1));
36986 hsva[2] = 1.0f - NK_SATURATE((in->mouse.pos.y - matrix->y) / (matrix->h-1));
36987 value_changed = hsv_changed = 1;
36990 if (nk_button_behavior(state, *hue_bar, in, NK_BUTTON_REPEATER)) {
36991 hsva[0] = NK_SATURATE((in->mouse.pos.y - hue_bar->y) / (hue_bar->h-1));
36992 value_changed = hsv_changed = 1;
36996 if (nk_button_behavior(state, *alpha_bar, in, NK_BUTTON_REPEATER)) {
36997 hsva[3] = 1.0f - NK_SATURATE((in->mouse.pos.y - alpha_bar->y) / (alpha_bar->h-1));
37001 nk_widget_state_reset(state);
37003 *color = nk_hsva_colorfv(hsva);
37006 if (value_changed) {
37007 color->a = hsva[3];
37011 if (nk_input_is_mouse_hovering_rect(in, *bounds))
37015 else if (nk_input_is_mouse_prev_hovering_rect(in, *bounds))
37017 return value_changed;
37035 NK_STORAGE
const struct nk_color black = {0,0,0,255};
37036 NK_STORAGE
const struct nk_color white = {255, 255, 255, 255};
37037 NK_STORAGE
const struct nk_color black_trans = {0,0,0,0};
37039 const float crosshair_size = 7.0f;
37047 NK_ASSERT(hue_bar);
37050 nk_colorf_hsva_fv(hsva, col);
37051 for (i = 0; i < 6; ++i) {
37052 NK_GLOBAL
const struct nk_color hue_colors[] = {
37053 {255, 0, 0, 255}, {255,255,0,255}, {0,255,0,255}, {0, 255,255,255},
37054 {0,0,255,255}, {255, 0, 255, 255}, {255, 0, 0, 255}
37056 nk_fill_rect_multi_color(o,
37057 nk_rect(hue_bar->x, hue_bar->y + (
float)i * (hue_bar->h/6.0f) + 0.5f,
37058 hue_bar->w, (hue_bar->h/6.0f) + 0.5f), hue_colors[i], hue_colors[i],
37059 hue_colors[i+1], hue_colors[i+1]);
37061 line_y = (float)(
int)(hue_bar->y + hsva[0] * matrix->h + 0.5f);
37062 nk_stroke_line(o, hue_bar->x-1, line_y, hue_bar->x + hue_bar->w + 2,
37063 line_y, 1, nk_rgb(255,255,255));
37067 float alpha = NK_SATURATE(col.a);
37068 line_y = (float)(
int)(alpha_bar->y + (1.0f - alpha) * matrix->h + 0.5f);
37070 nk_fill_rect_multi_color(o, *alpha_bar, white, white, black, black);
37071 nk_stroke_line(o, alpha_bar->x-1, line_y, alpha_bar->x + alpha_bar->w + 2,
37072 line_y, 1, nk_rgb(255,255,255));
37076 temp = nk_hsv_f(hsva[0], 1.0f, 1.0f);
37077 nk_fill_rect_multi_color(o, *matrix, white, temp, temp, white);
37078 nk_fill_rect_multi_color(o, *matrix, black_trans, black_trans, black, black);
37081 {
struct nk_vec2 p;
float S = hsva[1];
float V = hsva[2];
37082 p.x = (float)(
int)(matrix->x + S * matrix->w);
37083 p.y = (float)(
int)(matrix->y + (1.0f - V) * matrix->h);
37084 nk_stroke_line(o, p.x - crosshair_size, p.y, p.x-2, p.y, 1.0f, white);
37085 nk_stroke_line(o, p.x + crosshair_size + 1, p.y, p.x+3, p.y, 1.0f, white);
37086 nk_stroke_line(o, p.x, p.y + crosshair_size + 1, p.x, p.y+3, 1.0f, white);
37087 nk_stroke_line(o, p.x, p.y - crosshair_size, p.x, p.y-2, 1.0f, white);}
37100 nk_do_color_picker(nk_flags *state,
37102 enum nk_color_format fmt,
struct nk_rect bounds,
37116 if (!out || !col || !state || !font)
37120 bounds.x += padding.x;
37121 bounds.y += padding.x;
37122 bounds.w -= 2 * padding.x;
37123 bounds.h -= 2 * padding.y;
37125 matrix.x = bounds.x;
37126 matrix.y = bounds.y;
37127 matrix.h = bounds.h;
37128 matrix.w = bounds.w - (3 * padding.x + 2 * bar_w);
37131 hue_bar.y = bounds.y;
37132 hue_bar.h = matrix.h;
37133 hue_bar.x = matrix.x + matrix.w + padding.x;
37135 alpha_bar.x = hue_bar.x + hue_bar.w + padding.x;
37136 alpha_bar.y = bounds.y;
37137 alpha_bar.w = bar_w;
37138 alpha_bar.h = matrix.h;
37140 ret = nk_color_picker_behavior(state, &bounds, &matrix, &hue_bar,
37141 (fmt == NK_RGBA) ? &alpha_bar:0, col, in);
37142 nk_draw_color_picker(out, &matrix, &hue_bar, (fmt == NK_RGBA) ? &alpha_bar:0, *col);
37158 enum nk_color_format fmt)
37170 NK_ASSERT(ctx->current);
37171 NK_ASSERT(ctx->current->layout);
37172 if (!ctx || !ctx->current || !ctx->current->layout || !color)
37175 win = ctx->current;
37176 config = &ctx->style;
37177 layout = win->layout;
37178 state = nk_widget(&bounds, ctx);
37179 if (!state)
return 0;
37181 return nk_do_color_picker(&ctx->last_widget_state, &win->buffer, color, fmt, bounds,
37182 nk_vec2(0,0), in, config->font);
37197 enum nk_color_format fmt)
37199 nk_color_pick(ctx, &color, fmt);
37234 NK_ASSERT(ctx->current);
37235 NK_ASSERT(ctx->current->layout);
37236 if (!ctx || !ctx->current || !ctx->current->layout)
37239 popup = win->popup.win;
37242 body.y = header.y + header.h-ctx->style.window.combo_border;
37245 hash = win->popup.combo_count++;
37246 is_open = (popup) ? nk_true:nk_false;
37247 is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_COMBO);
37248 if ((is_clicked && is_open && !is_active) || (is_open && !is_active) ||
37249 (!is_open && !is_active && !is_clicked))
return 0;
37250 if (!nk_nonblock_begin(ctx, 0, body,
37251 (is_clicked && is_open)?
nk_rect(0,0,0,0):header, NK_PANEL_COMBO)) return 0;
37253 win->popup.type = NK_PANEL_COMBO;
37254 win->popup.name = hash;
37270 nk_combo_begin_text(
struct nk_context *ctx,
const char *selected,
int len,
37278 int is_clicked = nk_false;
37281 struct nk_text text;
37284 NK_ASSERT(selected);
37285 NK_ASSERT(ctx->current);
37286 NK_ASSERT(ctx->current->layout);
37287 if (!ctx || !ctx->current || !ctx->current->layout || !selected)
37290 win = ctx->current;
37291 style = &ctx->style;
37292 s = nk_widget(&header, ctx);
37297 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
37298 is_clicked = nk_true;
37302 background = &style->combo.active;
37303 text.text = style->combo.label_active;
37305 background = &style->combo.hover;
37306 text.text = style->combo.label_hover;
37308 background = &style->combo.normal;
37309 text.text = style->combo.label_normal;
37312 text.text = nk_rgb_factor(text.text, style->combo.color_factor);
37314 switch(background->type) {
37315 case NK_STYLE_ITEM_IMAGE:
37316 text.background = nk_rgba(0, 0, 0, 0);
37317 nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor));
37319 case NK_STYLE_ITEM_NINE_SLICE:
37320 text.background = nk_rgba(0, 0, 0, 0);
37321 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor));
37323 case NK_STYLE_ITEM_COLOR:
37324 text.background = background->data.color;
37325 nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor));
37326 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor));
37334 int draw_button_symbol;
37336 enum nk_symbol_type sym;
37338 sym = style->combo.sym_hover;
37339 else if (is_clicked)
37340 sym = style->combo.sym_active;
37342 sym = style->combo.sym_normal;
37345 draw_button_symbol = sym != NK_SYMBOL_NONE;
37348 button.w = header.h - 2 * style->combo.button_padding.y;
37349 button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
37350 button.y = header.y + style->combo.button_padding.y;
37351 button.h = button.w;
37353 content.x = button.x + style->combo.button.padding.x;
37354 content.y = button.y + style->combo.button.padding.y;
37355 content.w = button.w - 2 * style->combo.button.padding.x;
37356 content.h = button.h - 2 * style->combo.button.padding.y;
37360 label.x = header.x + style->combo.content_padding.x;
37361 label.y = header.y + style->combo.content_padding.y;
37362 label.h = header.h - 2 * style->combo.content_padding.y;
37363 if (draw_button_symbol)
37364 label.w = button.x - (style->combo.content_padding.x + style->combo.spacing.x) - label.x;
37366 label.w = header.w - 2 * style->combo.content_padding.x;
37367 nk_widget_text(&win->buffer, label, selected, len, &text,
37368 NK_TEXT_LEFT, ctx->style.font);
37371 if (draw_button_symbol)
37372 nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
37373 &ctx->style.combo.button, sym, style->font);
37375 return nk_combo_begin(ctx, win, size, is_clicked, header);
37390 nk_combo_begin_label(
struct nk_context *ctx,
const char *selected,
struct nk_vec2 size)
37392 return nk_combo_begin_text(ctx, selected, nk_strlen(selected), size);
37414 int is_clicked = nk_false;
37419 NK_ASSERT(ctx->current);
37420 NK_ASSERT(ctx->current->layout);
37421 if (!ctx || !ctx->current || !ctx->current->layout)
37424 win = ctx->current;
37425 style = &ctx->style;
37426 s = nk_widget(&header, ctx);
37431 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
37432 is_clicked = nk_true;
37436 background = &style->combo.active;
37438 background = &style->combo.hover;
37439 else background = &style->combo.normal;
37441 switch(background->type) {
37442 case NK_STYLE_ITEM_IMAGE:
37443 nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor));
37445 case NK_STYLE_ITEM_NINE_SLICE:
37446 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor));
37448 case NK_STYLE_ITEM_COLOR:
37449 nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor));
37450 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor));
37457 int draw_button_symbol;
37459 enum nk_symbol_type sym;
37461 sym = style->combo.sym_hover;
37462 else if (is_clicked)
37463 sym = style->combo.sym_active;
37464 else sym = style->combo.sym_normal;
37467 draw_button_symbol = sym != NK_SYMBOL_NONE;
37470 button.w = header.h - 2 * style->combo.button_padding.y;
37471 button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
37472 button.y = header.y + style->combo.button_padding.y;
37473 button.h = button.w;
37475 content.x = button.x + style->combo.button.padding.x;
37476 content.y = button.y + style->combo.button.padding.y;
37477 content.w = button.w - 2 * style->combo.button.padding.x;
37478 content.h = button.h - 2 * style->combo.button.padding.y;
37481 bounds.h = header.h - 4 * style->combo.content_padding.y;
37482 bounds.y = header.y + 2 * style->combo.content_padding.y;
37483 bounds.x = header.x + 2 * style->combo.content_padding.x;
37484 if (draw_button_symbol)
37485 bounds.w = (button.x - (style->combo.content_padding.x + style->combo.spacing.x)) - bounds.x;
37487 bounds.w = header.w - 4 * style->combo.content_padding.x;
37488 nk_fill_rect(&win->buffer, bounds, 0, nk_rgb_factor(color, style->combo.color_factor));
37491 if (draw_button_symbol)
37492 nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
37493 &ctx->style.combo.button, sym, style->font);
37495 return nk_combo_begin(ctx, win, size, is_clicked, header);
37510 nk_combo_begin_symbol(
struct nk_context *ctx,
enum nk_symbol_type symbol,
struct nk_vec2 size)
37517 int is_clicked = nk_false;
37524 NK_ASSERT(ctx->current);
37525 NK_ASSERT(ctx->current->layout);
37526 if (!ctx || !ctx->current || !ctx->current->layout)
37529 win = ctx->current;
37530 style = &ctx->style;
37531 s = nk_widget(&header, ctx);
37536 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
37537 is_clicked = nk_true;
37541 background = &style->combo.active;
37542 symbol_color = style->combo.symbol_active;
37544 background = &style->combo.hover;
37545 symbol_color = style->combo.symbol_hover;
37547 background = &style->combo.normal;
37548 symbol_color = style->combo.symbol_hover;
37551 symbol_color = nk_rgb_factor(symbol_color, style->combo.color_factor);
37553 switch(background->type) {
37554 case NK_STYLE_ITEM_IMAGE:
37555 sym_background = nk_rgba(0, 0, 0, 0);
37556 nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor));
37558 case NK_STYLE_ITEM_NINE_SLICE:
37559 sym_background = nk_rgba(0, 0, 0, 0);
37560 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor));
37562 case NK_STYLE_ITEM_COLOR:
37563 sym_background = background->data.color;
37564 nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor));
37565 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor));
37569 struct nk_rect bounds = {0,0,0,0};
37573 enum nk_symbol_type sym;
37575 sym = style->combo.sym_hover;
37576 else if (is_clicked)
37577 sym = style->combo.sym_active;
37578 else sym = style->combo.sym_normal;
37581 button.w = header.h - 2 * style->combo.button_padding.y;
37582 button.x = (header.x + header.w - header.h) - style->combo.button_padding.y;
37583 button.y = header.y + style->combo.button_padding.y;
37584 button.h = button.w;
37586 content.x = button.x + style->combo.button.padding.x;
37587 content.y = button.y + style->combo.button.padding.y;
37588 content.w = button.w - 2 * style->combo.button.padding.x;
37589 content.h = button.h - 2 * style->combo.button.padding.y;
37592 bounds.h = header.h - 2 * style->combo.content_padding.y;
37593 bounds.y = header.y + style->combo.content_padding.y;
37594 bounds.x = header.x + style->combo.content_padding.x;
37595 bounds.w = (button.x - style->combo.content_padding.y) - bounds.x;
37596 nk_draw_symbol(&win->buffer, symbol, bounds, sym_background, symbol_color,
37597 1.0f, style->font);
37600 nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state,
37601 &ctx->style.combo.button, sym, style->font);
37603 return nk_combo_begin(ctx, win, size, is_clicked, header);
37618 nk_combo_begin_symbol_text(
struct nk_context *ctx,
const char *selected,
int len,
37619 enum nk_symbol_type symbol,
struct nk_vec2 size)
37626 int is_clicked = nk_false;
37630 struct nk_text text;
37633 NK_ASSERT(ctx->current);
37634 NK_ASSERT(ctx->current->layout);
37635 if (!ctx || !ctx->current || !ctx->current->layout)
37638 win = ctx->current;
37639 style = &ctx->style;
37640 s = nk_widget(&header, ctx);
37644 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
37645 is_clicked = nk_true;
37649 background = &style->combo.active;
37650 symbol_color = style->combo.symbol_active;
37651 text.text = style->combo.label_active;
37653 background = &style->combo.hover;
37654 symbol_color = style->combo.symbol_hover;
37655 text.text = style->combo.label_hover;
37657 background = &style->combo.normal;
37658 symbol_color = style->combo.symbol_normal;
37659 text.text = style->combo.label_normal;
37662 text.text = nk_rgb_factor(text.text, style->combo.color_factor);
37663 symbol_color = nk_rgb_factor(symbol_color, style->combo.color_factor);
37665 switch(background->type) {
37666 case NK_STYLE_ITEM_IMAGE:
37667 text.background = nk_rgba(0, 0, 0, 0);
37668 nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor));
37670 case NK_STYLE_ITEM_NINE_SLICE:
37671 text.background = nk_rgba(0, 0, 0, 0);
37672 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor));
37674 case NK_STYLE_ITEM_COLOR:
37675 text.background = background->data.color;
37676 nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor));
37677 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor));
37686 enum nk_symbol_type sym;
37688 sym = style->combo.sym_hover;
37689 else if (is_clicked)
37690 sym = style->combo.sym_active;
37691 else sym = style->combo.sym_normal;
37694 button.w = header.h - 2 * style->combo.button_padding.y;
37695 button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
37696 button.y = header.y + style->combo.button_padding.y;
37697 button.h = button.w;
37699 content.x = button.x + style->combo.button.padding.x;
37700 content.y = button.y + style->combo.button.padding.y;
37701 content.w = button.w - 2 * style->combo.button.padding.x;
37702 content.h = button.h - 2 * style->combo.button.padding.y;
37703 nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
37704 &ctx->style.combo.button, sym, style->font);
37707 image.x = header.x + style->combo.content_padding.x;
37708 image.y = header.y + style->combo.content_padding.y;
37709 image.h = header.h - 2 * style->combo.content_padding.y;
37711 nk_draw_symbol(&win->buffer, symbol, image, text.background, symbol_color,
37712 1.0f, style->font);
37716 label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x;
37717 label.y = header.y + style->combo.content_padding.y;
37718 label.w = (button.x - style->combo.content_padding.x) - label.x;
37719 label.h = header.h - 2 * style->combo.content_padding.y;
37720 nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font);
37722 return nk_combo_begin(ctx, win, size, is_clicked, header);
37744 int is_clicked = nk_false;
37749 NK_ASSERT(ctx->current);
37750 NK_ASSERT(ctx->current->layout);
37751 if (!ctx || !ctx->current || !ctx->current->layout)
37754 win = ctx->current;
37755 style = &ctx->style;
37756 s = nk_widget(&header, ctx);
37761 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
37762 is_clicked = nk_true;
37766 background = &style->combo.active;
37768 background = &style->combo.hover;
37769 else background = &style->combo.normal;
37771 switch (background->type) {
37772 case NK_STYLE_ITEM_IMAGE:
37773 nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor));
37775 case NK_STYLE_ITEM_NINE_SLICE:
37776 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor));
37778 case NK_STYLE_ITEM_COLOR:
37779 nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor));
37780 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor));
37784 struct nk_rect bounds = {0,0,0,0};
37787 int draw_button_symbol;
37789 enum nk_symbol_type sym;
37791 sym = style->combo.sym_hover;
37792 else if (is_clicked)
37793 sym = style->combo.sym_active;
37794 else sym = style->combo.sym_normal;
37797 draw_button_symbol = sym != NK_SYMBOL_NONE;
37800 button.w = header.h - 2 * style->combo.button_padding.y;
37801 button.x = (header.x + header.w - header.h) - style->combo.button_padding.y;
37802 button.y = header.y + style->combo.button_padding.y;
37803 button.h = button.w;
37805 content.x = button.x + style->combo.button.padding.x;
37806 content.y = button.y + style->combo.button.padding.y;
37807 content.w = button.w - 2 * style->combo.button.padding.x;
37808 content.h = button.h - 2 * style->combo.button.padding.y;
37811 bounds.h = header.h - 2 * style->combo.content_padding.y;
37812 bounds.y = header.y + style->combo.content_padding.y;
37813 bounds.x = header.x + style->combo.content_padding.x;
37814 if (draw_button_symbol)
37815 bounds.w = (button.x - style->combo.content_padding.y) - bounds.x;
37817 bounds.w = header.w - 2 * style->combo.content_padding.x;
37818 nk_draw_image(&win->buffer, bounds, &img, nk_rgb_factor(nk_white, style->combo.color_factor));
37821 if (draw_button_symbol)
37822 nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state,
37823 &ctx->style.combo.button, sym, style->font);
37825 return nk_combo_begin(ctx, win, size, is_clicked, header);
37840 nk_combo_begin_image_text(
struct nk_context *ctx,
const char *selected,
int len,
37848 int is_clicked = nk_false;
37851 struct nk_text text;
37854 NK_ASSERT(ctx->current);
37855 NK_ASSERT(ctx->current->layout);
37856 if (!ctx || !ctx->current || !ctx->current->layout)
37859 win = ctx->current;
37860 style = &ctx->style;
37861 s = nk_widget(&header, ctx);
37865 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
37866 is_clicked = nk_true;
37870 background = &style->combo.active;
37871 text.text = style->combo.label_active;
37873 background = &style->combo.hover;
37874 text.text = style->combo.label_hover;
37876 background = &style->combo.normal;
37877 text.text = style->combo.label_normal;
37880 text.text = nk_rgb_factor(text.text, style->combo.color_factor);
37882 switch(background->type) {
37883 case NK_STYLE_ITEM_IMAGE:
37884 text.background = nk_rgba(0, 0, 0, 0);
37885 nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor));
37887 case NK_STYLE_ITEM_NINE_SLICE:
37888 text.background = nk_rgba(0, 0, 0, 0);
37889 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor));
37891 case NK_STYLE_ITEM_COLOR:
37892 text.background = background->data.color;
37893 nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor));
37894 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor));
37902 int draw_button_symbol;
37904 enum nk_symbol_type sym;
37906 sym = style->combo.sym_hover;
37907 else if (is_clicked)
37908 sym = style->combo.sym_active;
37909 else sym = style->combo.sym_normal;
37912 draw_button_symbol = sym != NK_SYMBOL_NONE;
37915 button.w = header.h - 2 * style->combo.button_padding.y;
37916 button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
37917 button.y = header.y + style->combo.button_padding.y;
37918 button.h = button.w;
37920 content.x = button.x + style->combo.button.padding.x;
37921 content.y = button.y + style->combo.button.padding.y;
37922 content.w = button.w - 2 * style->combo.button.padding.x;
37923 content.h = button.h - 2 * style->combo.button.padding.y;
37924 if (draw_button_symbol)
37925 nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
37926 &ctx->style.combo.button, sym, style->font);
37929 image.x = header.x + style->combo.content_padding.x;
37930 image.y = header.y + style->combo.content_padding.y;
37931 image.h = header.h - 2 * style->combo.content_padding.y;
37933 nk_draw_image(&win->buffer, image, &img, nk_rgb_factor(nk_white, style->combo.color_factor));
37937 label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x;
37938 label.y = header.y + style->combo.content_padding.y;
37939 label.h = header.h - 2 * style->combo.content_padding.y;
37940 if (draw_button_symbol)
37941 label.w = (button.x - style->combo.content_padding.x) - label.x;
37943 label.w = (header.x + header.w - style->combo.content_padding.x) - label.x;
37944 nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font);
37946 return nk_combo_begin(ctx, win, size, is_clicked, header);
37959 nk_combo_begin_symbol_label(
struct nk_context *ctx,
37960 const char *selected,
enum nk_symbol_type type,
struct nk_vec2 size)
37962 return nk_combo_begin_symbol_text(ctx, selected, nk_strlen(selected), type, size);
37975 nk_combo_begin_image_label(
struct nk_context *ctx,
37978 return nk_combo_begin_image_text(ctx, selected, nk_strlen(selected), img, size);
37994 nk_combo_item_text(
struct nk_context *ctx,
const char *text,
int len,nk_flags align)
37996 return nk_contextual_item_text(ctx, text, len, align);
38011 nk_combo_item_label(
struct nk_context *ctx,
const char *label, nk_flags align)
38013 return nk_contextual_item_label(ctx, label, align);
38028 nk_combo_item_image_text(
struct nk_context *ctx,
struct nk_image img,
const char *text,
38029 int len, nk_flags alignment)
38031 return nk_contextual_item_image_text(ctx, img, text, len, alignment);
38046 const char *text, nk_flags alignment)
38048 return nk_contextual_item_image_label(ctx, img, text, alignment);
38062 nk_combo_item_symbol_text(
struct nk_context *ctx,
enum nk_symbol_type sym,
38063 const char *text,
int len, nk_flags alignment)
38065 return nk_contextual_item_symbol_text(ctx, sym, text, len, alignment);
38079 nk_combo_item_symbol_label(
struct nk_context *ctx,
enum nk_symbol_type sym,
38080 const char *label, nk_flags alignment)
38082 return nk_contextual_item_symbol_label(ctx, sym, label, alignment);
38094 NK_API
void nk_combo_end(
struct nk_context *ctx)
38096 nk_contextual_end(ctx);
38108 NK_API
void nk_combo_close(
struct nk_context *ctx)
38110 nk_contextual_close(ctx);
38125 nk_combo(
struct nk_context *ctx,
const char *
const *items,
int count,
38126 int selected,
int item_height,
struct nk_vec2 size)
38131 struct nk_vec2 window_padding;
38135 NK_ASSERT(ctx->current);
38136 if (!ctx || !items ||!count)
38139 item_spacing = ctx->style.window.spacing;
38140 window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
38141 max_height = count * item_height + count * (int)item_spacing.y;
38142 max_height += (
int)item_spacing.y * 2 + (int)window_padding.y * 2;
38143 size.y = NK_MIN(size.y, (
float)max_height);
38144 if (nk_combo_begin_label(ctx, items[selected], size)) {
38146 for (i = 0; i < count; ++i) {
38147 if (nk_combo_item_label(ctx, items[i], NK_TEXT_LEFT))
38166 nk_combo_separator(
struct nk_context *ctx,
const char *items_separated_by_separator,
38167 int separator,
int selected,
int count,
int item_height,
struct nk_vec2 size)
38172 struct nk_vec2 window_padding;
38173 const char *current_item;
38178 NK_ASSERT(items_separated_by_separator);
38179 if (!ctx || !items_separated_by_separator)
38183 item_spacing = ctx->style.window.spacing;
38184 window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
38185 max_height = count * item_height + count * (int)item_spacing.y;
38186 max_height += (
int)item_spacing.y * 2 + (int)window_padding.y * 2;
38187 size.y = NK_MIN(size.y, (
float)max_height);
38190 current_item = items_separated_by_separator;
38191 for (i = 0; i < count; ++i) {
38192 iter = current_item;
38193 while (*iter && *iter != separator) iter++;
38194 length = (int)(iter - current_item);
38195 if (i == selected)
break;
38196 current_item = iter + 1;
38199 if (nk_combo_begin_text(ctx, current_item, length, size)) {
38200 current_item = items_separated_by_separator;
38202 for (i = 0; i < count; ++i) {
38203 iter = current_item;
38204 while (*iter && *iter != separator) iter++;
38205 length = (int)(iter - current_item);
38206 if (nk_combo_item_text(ctx, current_item, length, NK_TEXT_LEFT))
38208 current_item = current_item + length + 1;
38226 nk_combo_string(
struct nk_context *ctx,
const char *items_separated_by_zeros,
38227 int selected,
int count,
int item_height,
struct nk_vec2 size)
38229 return nk_combo_separator(ctx, items_separated_by_zeros,
'\0', selected, count, item_height, size);
38244 nk_combo_callback(
struct nk_context *ctx,
void(*item_getter)(
void*,
int,
const char**),
38245 void *userdata,
int selected,
int count,
int item_height,
struct nk_vec2 size)
38250 struct nk_vec2 window_padding;
38254 NK_ASSERT(item_getter);
38255 if (!ctx || !item_getter)
38259 item_spacing = ctx->style.window.spacing;
38260 window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
38261 max_height = count * item_height + count * (int)item_spacing.y;
38262 max_height += (
int)item_spacing.y * 2 + (int)window_padding.y * 2;
38263 size.y = NK_MIN(size.y, (
float)max_height);
38265 item_getter(userdata, selected, &item);
38266 if (nk_combo_begin_label(ctx, item, size)) {
38268 for (i = 0; i < count; ++i) {
38269 item_getter(userdata, i, &item);
38270 if (nk_combo_item_label(ctx, item, NK_TEXT_LEFT))
38289 nk_combobox(
struct nk_context *ctx,
const char *
const *items,
int count,
38290 int *selected,
int item_height,
struct nk_vec2 size)
38292 *selected = nk_combo(ctx, items, count, *selected, item_height, size);
38306 nk_combobox_string(
struct nk_context *ctx,
const char *items_separated_by_zeros,
38307 int *selected,
int count,
int item_height,
struct nk_vec2 size)
38309 *selected = nk_combo_string(ctx, items_separated_by_zeros, *selected, count, item_height, size);
38323 nk_combobox_separator(
struct nk_context *ctx,
const char *items_separated_by_separator,
38324 int separator,
int *selected,
int count,
int item_height,
struct nk_vec2 size)
38326 *selected = nk_combo_separator(ctx, items_separated_by_separator, separator,
38327 *selected, count, item_height, size);
38340 nk_combobox_callback(
struct nk_context *ctx,
38341 void(*item_getter)(
void* data,
int id,
const char **out_text),
38342 void *userdata,
int *selected,
int count,
int item_height,
struct nk_vec2 size)
38344 *selected = nk_combo_callback(ctx, item_getter, userdata, *selected, count, item_height, size);
38367 nk_tooltip_begin(
struct nk_context *ctx,
float width)
38376 NK_ASSERT(ctx->current);
38377 NK_ASSERT(ctx->current->layout);
38378 if (!ctx || !ctx->current || !ctx->current->layout)
38382 win = ctx->current;
38384 if (win->popup.win && ((
int)win->popup.type & (
int)NK_PANEL_SET_NONBLOCK))
38387 w = nk_iceilf(width);
38388 h = nk_iceilf(nk_null_rect.h);
38389 x = nk_ifloorf(in->mouse.pos.x + 1) - (int)win->layout->clip.x;
38390 y = nk_ifloorf(in->mouse.pos.y + 1) - (int)win->layout->clip.y;
38392 bounds.x = (
float)x;
38393 bounds.y = (float)y;
38394 bounds.w = (float)w;
38395 bounds.h = (float)h;
38397 ret = nk_popup_begin(ctx, NK_POPUP_DYNAMIC,
38398 "__##Tooltip##__", NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER, bounds);
38400 win->popup.type = NK_PANEL_TOOLTIP;
38401 ctx->current->layout->type = NK_PANEL_TOOLTIP;
38419 NK_ASSERT(ctx->current);
38420 if (!ctx || !ctx->current)
return;
38421 ctx->current->seq--;
38422 nk_popup_close(ctx);
38437 nk_tooltip(
struct nk_context *ctx,
const char *text)
38447 NK_ASSERT(ctx->current);
38448 NK_ASSERT(ctx->current->layout);
38450 if (!ctx || !ctx->current || !ctx->current->layout || !text)
38454 style = &ctx->style;
38455 padding = style->window.padding;
38458 text_len = nk_strlen(text);
38459 text_width = style->font->
width(style->font->userdata,
38460 style->font->
height, text, text_len);
38461 text_width += (4 * padding.x);
38462 text_height = (style->font->
height + 2 * padding.y);
38465 if (nk_tooltip_begin(ctx, (
float)text_width)) {
38467 nk_text(ctx, text, text_len, NK_TEXT_LEFT);
38468 nk_tooltip_end(ctx);
38471 #ifdef NK_INCLUDE_STANDARD_VARARGS
38484 nk_tooltipf(
struct nk_context *ctx,
const char *fmt, ...)
38487 va_start(args, fmt);
38488 nk_tooltipfv(ctx, fmt, args);
38504 nk_tooltipfv(
struct nk_context *ctx,
const char *fmt, va_list args)
38507 nk_strfmt(buf, NK_LEN(buf), fmt, args);
38508 nk_tooltip(ctx, buf);
NK_API void nk_tree_pop(struct nk_context *)
Ends a collapsabale UI section.
NK_API void nk_free(struct nk_context *)
Frees all memory allocated by nuklear; Not needed if context was initialized with nk_init_fixed.
NK_API nk_bool nk_group_begin(struct nk_context *, const char *title, nk_flags)
Starts a new widget group.
NK_API struct nk_vec2 nk_window_get_content_region_max(const struct nk_context *ctx)
NK_API void nk_layout_row_end(struct nk_context *)
Finished previously started row.
NK_API void nk_input_end(struct nk_context *)
End the input mirroring process by resetting mouse grabbing state to ensure the mouse cursor is not g...
NK_API void nk_window_close(struct nk_context *ctx, const char *name)
Closes a window and marks it for being freed at the end of the frame.
NK_API void nk_spacer(struct nk_context *ctx)
Spacer is a dummy widget that consumes space as usual but doesn't draw anything.
NK_API void nk_input_begin(struct nk_context *)
Begins the input mirroring process by resetting text, scroll mouse, previous mouse position and movem...
NK_API float nk_propertyf(struct nk_context *, const char *name, float min, float val, float max, float step, float inc_per_pixel)
Float property modifying a passed in value and returning the new value.
NK_API void nk_rule_horizontal(struct nk_context *ctx, struct nk_color color, nk_bool rounding)
Line for visual separation.
NK_API void nk_layout_space_end(struct nk_context *)
Marks the end of the layout space.
NK_API nk_bool nk_init_fixed(struct nk_context *, void *memory, nk_size size, const struct nk_user_font *)
Initializes a nk_context struct from single fixed size memory block Should be used if you want comple...
NK_API void nk_property_float(struct nk_context *, const char *name, float min, float *val, float max, float step, float inc_per_pixel)
Float property directly modifying a passed in value !!!
@ NK_WINDOW_CLOSED
Directly closes and frees the window at the end of the frame.
@ NK_WINDOW_MINIMIZED
marks the window as minimized
@ NK_WINDOW_HIDDEN
Hides window and stops any window interaction and drawing.
@ NK_WINDOW_ROM
sets window widgets into a read only mode and does not allow input changes
@ NK_WINDOW_NOT_INTERACTIVE
prevents all interaction caused by input to either window or widgets inside
@ NK_WINDOW_DYNAMIC
special window type growing up in height while being filled to a certain maximum height
@ NK_WINDOW_REMOVE_ROM
Removes read only mode at the end of the window.
NK_API void nk_layout_row(struct nk_context *, enum nk_layout_format, float height, int cols, const float *ratio)
Specifies row columns in array as either window ratio or size.
NK_API void nk_draw_image(struct nk_command_buffer *, struct nk_rect, const struct nk_image *, struct nk_color)
misc
NK_API nk_bool nk_window_is_hovered(const struct nk_context *ctx)
Return if the current window is being hovered.
NK_API void nk_window_collapse_if(struct nk_context *ctx, const char *name, enum nk_collapse_states state, int cond)
Updates collapse state of a window with given name if given condition is met.
NK_API struct nk_vec2 nk_layout_space_to_screen(const struct nk_context *ctx, struct nk_vec2 vec)
Converts vector from nk_layout_space coordinate space into screen space.
#define NK_UTF_INVALID
internal invalid utf8 rune
#define NK_BOOL
could be char, use int for drop-in replacement backwards compatibility
NK_API nk_bool nk_init_custom(struct nk_context *, struct nk_buffer *cmds, struct nk_buffer *pool, const struct nk_user_font *)
Initializes a nk_context struct from two different either fixed or growing buffers.
NK_API nk_bool nk_tree_image_push_hashed(struct nk_context *, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states initial_state, const char *hash, int len, int seed)
Start a collapsible UI section with internal state management with full control over internal unique ...
NK_API void nk_window_set_scroll(struct nk_context *ctx, nk_uint offset_x, nk_uint offset_y)
Sets the scroll offset for the current window.
NK_API void nk_group_scrolled_end(struct nk_context *)
Ends a widget group after calling nk_group_scrolled_offset_begin or nk_group_scrolled_begin.
NK_API struct nk_vec2 nk_window_get_size(const struct nk_context *ctx)
NK_API void nk_layout_row_template_push_dynamic(struct nk_context *)
Adds a dynamic column that dynamically grows and can go to zero if not enough space.
NK_API nk_bool nk_window_is_active(const struct nk_context *ctx, const char *name)
Same as nk_window_has_focus for some reason.
NK_API void nk_group_get_scroll(struct nk_context *, const char *id, nk_uint *x_offset, nk_uint *y_offset)
Gets the scroll position of the given group.
NK_API struct nk_vec2 nk_layout_space_to_local(const struct nk_context *ctx, struct nk_vec2 vec)
Converts vector from layout space into screen space.
NK_API void nk_window_set_focus(struct nk_context *ctx, const char *name)
Sets the window with given name as active.
NK_API nk_bool nk_item_is_any_active(const struct nk_context *ctx)
#define NK_UTF_SIZE
describes the number of bytes a glyph consists of
NK_API void nk_input_unicode(struct nk_context *, nk_rune)
Converts a unicode rune into UTF-8 and copies the result into an internal text buffer.
NK_API nk_bool nk_window_is_any_hovered(const struct nk_context *ctx)
NK_API nk_bool nk_window_is_hidden(const struct nk_context *ctx, const char *name)
NK_API void nk_input_key(struct nk_context *, enum nk_keys, nk_bool down)
Mirrors the state of a specific key to nuklear.
NK_API void nk_stroke_line(struct nk_command_buffer *b, float x0, float y0, float x1, float y1, float line_thickness, struct nk_color)
shape outlines
NK_API void nk_property_double(struct nk_context *, const char *name, double min, double *val, double max, double step, float inc_per_pixel)
Double property directly modifying a passed in value.
NK_API void nk_fill_rect(struct nk_command_buffer *, struct nk_rect, float rounding, struct nk_color)
filled shades
NK_API void nk_layout_row_template_push_static(struct nk_context *, float width)
Adds a static column that does not grow and will always have the same size.
NK_API struct nk_vec2 nk_window_get_content_region_size(const struct nk_context *ctx)
NK_API void nk_window_get_scroll(const struct nk_context *ctx, nk_uint *offset_x, nk_uint *offset_y)
Gets the scroll offset for the current window.
NK_API nk_bool nk_group_scrolled_offset_begin(struct nk_context *, nk_uint *x_offset, nk_uint *y_offset, const char *title, nk_flags flags)
starts a new widget group.
NK_API nk_bool nk_tree_state_image_push(struct nk_context *, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states *state)
Start a collapsible UI section with image and label header and external state management.
NK_API void nk_window_set_position(struct nk_context *ctx, const char *name, struct nk_vec2 pos)
Updates position of window with passed name.
NK_API void nk_window_show(struct nk_context *ctx, const char *name, enum nk_show_states state)
updates visibility state of a window with given name
NK_API nk_bool nk_window_is_collapsed(const struct nk_context *ctx, const char *name)
NK_API struct nk_command_buffer * nk_window_get_canvas(const struct nk_context *ctx)
NK_API void nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols)
Sets current row layout to share horizontal space between cols number of widgets evenly.
NK_API void nk_window_collapse(struct nk_context *ctx, const char *name, enum nk_collapse_states state)
Updates collapse state of a window with given name.
NK_API nk_bool nk_filter_default(const struct nk_text_edit *, nk_rune unicode)
filter function
NK_API const struct nk_command * nk__begin(struct nk_context *)
Returns a draw command list iterator to iterate all draw commands accumulated over one frame.
NK_API void nk_layout_row_template_end(struct nk_context *)
Marks the end of the row template.
NK_API nk_bool nk_window_has_focus(const struct nk_context *ctx)
NK_API void nk_layout_reset_min_row_height(struct nk_context *)
Reset the currently used minimum row height back to font_height + text_padding + padding
@ NK_WIDGET_STATE_LEFT
!< widget is currently activated
@ NK_WIDGET_STATE_ACTIVED
!< widget is being hovered
@ NK_WIDGET_STATE_ENTERED
!< widget is neither active nor hovered
@ NK_WIDGET_STATE_HOVER
!< widget has been hovered on the current frame
@ NK_WIDGET_STATE_ACTIVE
!< widget is being hovered
@ NK_WIDGET_STATE_HOVERED
!< widget is from this frame on not hovered anymore
NK_API struct nk_rect nk_layout_space_rect_to_local(const struct nk_context *ctx, struct nk_rect bounds)
Converts rectangle from layout space into screen space.
NK_API void nk_window_set_bounds(struct nk_context *ctx, const char *name, struct nk_rect bounds)
Updates position and size of window with passed in name.
NK_API struct nk_rect nk_window_get_bounds(const struct nk_context *ctx)
NK_API nk_bool nk_tree_state_push(struct nk_context *, enum nk_tree_type, const char *title, enum nk_collapse_states *state)
Start a collapsible UI section with external state management.
NK_API struct nk_panel * nk_window_get_panel(const struct nk_context *ctx)
NK_API nk_bool nk_tree_push_hashed(struct nk_context *, enum nk_tree_type, const char *title, enum nk_collapse_states initial_state, const char *hash, int len, int seed)
Start a collapsible UI section with internal state management with full control over internal unique ...
NK_API void nk_layout_set_min_row_height(struct nk_context *, float height)
Sets the currently used minimum row height.
NK_API void nk_window_show_if(struct nk_context *ctx, const char *name, enum nk_show_states state, int cond)
Updates visibility state of a window with given name if a given condition is met.
NK_API float nk_window_get_height(const struct nk_context *ctx)
NK_API void nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt, float row_height, int cols)
Starts a new dynamic or fixed row with given height and columns.
NK_API nk_bool nk_group_begin_titled(struct nk_context *, const char *name, const char *title, nk_flags)
Starts a new widget group.
NK_API nk_bool nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, struct nk_rect bounds, nk_flags flags)
Extended window start with separated title and identifier to allow multiple.
#define nk_foreach(c, ctx)
Iterates over each draw command inside the context draw command list.
NK_API void nk_layout_space_push(struct nk_context *, struct nk_rect bounds)
Pushes position and size of the next widget in own coordinate space either as pixel or ratio.
NK_API nk_bool nk_begin(struct nk_context *ctx, const char *title, struct nk_rect bounds, nk_flags flags)
Starts a new window; needs to be called every frame for every.
NK_API void nk_window_set_size(struct nk_context *ctx, const char *name, struct nk_vec2 size)
Updates size of window with passed in name.
NK_API void nk_input_button(struct nk_context *, enum nk_buttons, int x, int y, nk_bool down)
Mirrors the state of a specific mouse button to nuklear.
NK_API void nk_group_set_scroll(struct nk_context *, const char *id, nk_uint x_offset, nk_uint y_offset)
Sets the scroll position of the given group.
NK_API void nk_layout_row_template_begin(struct nk_context *, float row_height)
Begins the row template declaration.
NK_API nk_bool nk_init(struct nk_context *, const struct nk_allocator *, const struct nk_user_font *)
Initializes a nk_context struct with memory allocation callbacks for nuklear to allocate memory from.
NK_API float nk_layout_ratio_from_pixel(const struct nk_context *ctx, float pixel_width)
Utility functions to calculate window ratio from pixel size.
NK_API void nk_tree_state_pop(struct nk_context *)
Ends a collapsabale UI section.
NK_API void nk_layout_row_push(struct nk_context *, float value)
Specifies either window ratio or width of a single column.
NK_API struct nk_rect nk_layout_widget_bounds(const struct nk_context *ctx)
Returns the width of the next row allocate by one of the layouting functions.
NK_API struct nk_rect nk_layout_space_rect_to_screen(const struct nk_context *ctx, struct nk_rect bounds)
Converts rectangle from screen space into layout space.
NK_API struct nk_vec2 nk_window_get_content_region_min(const struct nk_context *ctx)
NK_API void nk_input_char(struct nk_context *, char)
Copies a single ASCII character into an internal text buffer.
NK_API float nk_window_get_width(const struct nk_context *ctx)
NK_API void nk_input_scroll(struct nk_context *, struct nk_vec2 val)
Copies the last mouse scroll value to nuklear.
@ NK_WIDGET_DISABLED
The widget is manually disabled and acts like NK_WIDGET_ROM.
@ NK_WIDGET_ROM
The widget is partially visible and cannot be updated.
@ NK_WIDGET_VALID
The widget is completely inside the window and can be updated and drawn.
@ NK_WIDGET_INVALID
The widget cannot be seen and is completely out of view.
NK_API double nk_propertyd(struct nk_context *, const char *name, double min, double val, double max, double step, float inc_per_pixel)
Float property modifying a passed in value and returning the new value.
NK_API void nk_input_motion(struct nk_context *, int x, int y)
Mirrors current mouse position to nuklear.
NK_API void nk_layout_space_begin(struct nk_context *, enum nk_layout_format, float height, int widget_count)
Begins a new layouting space that allows to specify each widgets position and size.
NK_API struct nk_rect nk_layout_space_bounds(const struct nk_context *ctx)
Utility function to calculate total space allocated for nk_layout_space
NK_API struct nk_rect nk_window_get_content_region(const struct nk_context *ctx)
NK_API nk_bool nk_window_is_closed(const struct nk_context *ctx, const char *name)
NK_API const struct nk_command * nk__next(struct nk_context *, const struct nk_command *)
Returns draw command pointer pointing to the next command inside the draw command list.
NK_API void nk_clear(struct nk_context *)
Resets the context state at the end of the frame.
NK_API void nk_end(struct nk_context *ctx)
Needs to be called at the end of the window building process to process scaling, scrollbars and gener...
NK_API void nk_group_end(struct nk_context *)
Ends a widget group.
NK_API void nk_layout_row_template_push_variable(struct nk_context *, float min_width)
Adds a variable column that dynamically grows but does not shrink below specified pixel width.
NK_API struct nk_vec2 nk_window_get_position(const struct nk_context *ctx)
@ NK_EDIT_INACTIVE
!< edit widget is currently being modified
@ NK_EDIT_DEACTIVATED
!< edit widget went from state inactive to state active
@ NK_EDIT_COMMITED
!< edit widget went from state active to state inactive
@ NK_EDIT_ACTIVATED
!< edit widget is not active and is not being modified
NK_API int nk_propertyi(struct nk_context *, const char *name, int min, int val, int max, int step, float inc_per_pixel)
Integer property modifying a passed in value and returning the new value.
NK_API nk_bool nk_group_scrolled_begin(struct nk_context *, struct nk_scroll *off, const char *title, nk_flags)
Starts a new widget group.
NK_API void nk_input_glyph(struct nk_context *, const nk_glyph)
Converts an encoded unicode rune into UTF-8 and copies the result into an internal text buffer.
NK_API void nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols)
Sets current row layout to fill cols number of widgets in row with same @item_width horizontal size.
NK_API void nk_textedit_init(struct nk_text_edit *, const struct nk_allocator *, nk_size size)
text editor
NK_API struct nk_window * nk_window_find(const struct nk_context *ctx, const char *name)
Finds and returns a window from passed name.
struct nk_allocator pool
!< buffer marker to free a buffer to a certain offset
struct nk_memory memory
!< memory management type
enum nk_allocation_type type
!< allocator callback for dynamic buffers
nk_size needed
!< total amount of memory allocated
nk_size size
!< number of allocation calls
nk_size allocated
!< growing factor for dynamic memory management
float grow_factor
!< memory and size of the current memory block
nk_size calls
!< totally consumed memory given that enough memory is present
command base and header of every command inside the buffer
struct nk_text_edit text_edit
text editor objects are quite big because of an internal undo/redo stack.
struct nk_command_buffer overlay
draw buffer used for overlay drawing operation like cursor
enum nk_anti_aliasing shape_AA
!< line anti-aliasing flag can be turned off if you are tight on memory
enum nk_anti_aliasing line_AA
!< global alpha value
nk_size vertex_alignment
!< sizeof one vertex for vertex packing
nk_size vertex_size
!< describes the vertex output format and packing
const struct nk_draw_vertex_layout_element * vertex_layout
!< handle to texture with a white pixel for shape drawing
unsigned arc_segment_count
!< number of segments used for circles: default to 22
unsigned circle_segment_count
!< shape anti-aliasing flag can be turned off if you are tight on memory
unsigned curve_segment_count
!< number of segments used for arcs: default to 22
struct nk_draw_null_texture tex_null
!< number of segments used for curves: default to 22
struct nk_vec2 uv
!< texture handle to a texture with a white pixel
==============================================================
nk_text_width_f width
!< max height of the font
float height
!< user provided font handle