220#ifndef NK_SINGLE_FILE
221 #define NK_SINGLE_FILE
243#define NK_UNDEFINED (-1.0f)
244#define NK_UTF_INVALID 0xFFFD
247 #define NK_INPUT_MAX 16
249#ifndef NK_MAX_NUMBER_BUFFER
250 #define NK_MAX_NUMBER_BUFFER 64
252#ifndef NK_SCROLLBAR_HIDING_TIMEOUT
253 #define NK_SCROLLBAR_HIDING_TIMEOUT 4.0f
265 #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199409L))
266 #define NK_API static inline
267 #elif defined(__cplusplus)
268 #define NK_API static inline
270 #define NK_API static
273 #define NK_API extern
277 #ifdef NK_SINGLE_FILE
278 #define NK_LIB static
280 #define NK_LIB extern
284#define NK_INTERN static
285#define NK_STORAGE static
286#define NK_GLOBAL static
288#define NK_FLAG(x) (1 << (x))
289#define NK_STRINGIFY(x) #x
290#define NK_MACRO_STRINGIFY(x) NK_STRINGIFY(x)
291#define NK_STRING_JOIN_IMMEDIATE(arg1, arg2) arg1 ## arg2
292#define NK_STRING_JOIN_DELAY(arg1, arg2) NK_STRING_JOIN_IMMEDIATE(arg1, arg2)
293#define NK_STRING_JOIN(arg1, arg2) NK_STRING_JOIN_DELAY(arg1, arg2)
296 #define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__COUNTER__)
298 #define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__LINE__)
301#ifndef NK_STATIC_ASSERT
302 #define NK_STATIC_ASSERT(exp) typedef char NK_UNIQUE_NAME(_dummy_array)[(exp)?1:-1]
307 #define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__COUNTER__)
309 #define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__LINE__)
313#define NK_MIN(a,b) ((a) < (b) ? (a) : (b))
314#define NK_MAX(a,b) ((a) < (b) ? (b) : (a))
315#define NK_CLAMP(i,v,x) (NK_MAX(NK_MIN(v,x), i))
317#ifdef NK_INCLUDE_STANDARD_VARARGS
319 #if defined(_MSC_VER) && (_MSC_VER >= 1600)
321 #define NK_PRINTF_FORMAT_STRING _Printf_format_string_
323 #define NK_PRINTF_FORMAT_STRING
325 #if defined(__GNUC__)
326 #define NK_PRINTF_VARARG_FUNC(fmtargnumber) __attribute__((format(__printf__, fmtargnumber, fmtargnumber+1)))
327 #define NK_PRINTF_VALIST_FUNC(fmtargnumber) __attribute__((format(__printf__, fmtargnumber, 0)))
329 #define NK_PRINTF_VARARG_FUNC(fmtargnumber)
330 #define NK_PRINTF_VALIST_FUNC(fmtargnumber)
341 #ifdef NK_INCLUDE_FIXED_TYPES
343 #define NK_INT8 int8_t
344 #define NK_UINT8 uint8_t
345 #define NK_INT16 int16_t
346 #define NK_UINT16 uint16_t
347 #define NK_INT32 int32_t
348 #define NK_UINT32 uint32_t
349 #define NK_SIZE_TYPE uintptr_t
350 #define NK_POINTER_TYPE uintptr_t
353 #define NK_INT8 signed char
356 #define NK_UINT8 unsigned char
359 #define NK_INT16 signed short
362 #define NK_UINT16 unsigned short
365 #if defined(_MSC_VER)
366 #define NK_INT32 __int32
368 #define NK_INT32 signed int
372 #if defined(_MSC_VER)
373 #define NK_UINT32 unsigned __int32
375 #define NK_UINT32 unsigned int
379 #if defined(_WIN64) && defined(_MSC_VER)
380 #define NK_SIZE_TYPE unsigned __int64
381 #elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
382 #define NK_SIZE_TYPE unsigned __int32
383 #elif defined(__GNUC__) || defined(__clang__)
384 #if defined(__x86_64__) || defined(__ppc64__) || defined(__PPC64__) || defined(__aarch64__)
385 #define NK_SIZE_TYPE unsigned long
387 #define NK_SIZE_TYPE unsigned int
390 #define NK_SIZE_TYPE unsigned long
393 #ifndef NK_POINTER_TYPE
394 #if defined(_WIN64) && defined(_MSC_VER)
395 #define NK_POINTER_TYPE unsigned __int64
396 #elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
397 #define NK_POINTER_TYPE unsigned __int32
398 #elif defined(__GNUC__) || defined(__clang__)
399 #if defined(__x86_64__) || defined(__ppc64__) || defined(__PPC64__) || defined(__aarch64__)
400 #define NK_POINTER_TYPE unsigned long
402 #define NK_POINTER_TYPE unsigned int
405 #define NK_POINTER_TYPE unsigned long
411 #ifdef NK_INCLUDE_STANDARD_BOOL
419typedef NK_INT8 nk_char;
420typedef NK_UINT8 nk_uchar;
421typedef NK_UINT8 nk_byte;
422typedef NK_INT16 nk_short;
423typedef NK_UINT16 nk_ushort;
424typedef NK_INT32 nk_int;
425typedef NK_UINT32 nk_uint;
426typedef NK_SIZE_TYPE nk_size;
427typedef NK_POINTER_TYPE nk_ptr;
430typedef nk_uint nk_hash;
431typedef nk_uint nk_flags;
432typedef nk_uint nk_rune;
437NK_STATIC_ASSERT(
sizeof(nk_short) == 2);
438NK_STATIC_ASSERT(
sizeof(nk_ushort) == 2);
439NK_STATIC_ASSERT(
sizeof(nk_uint) == 4);
440NK_STATIC_ASSERT(
sizeof(nk_int) == 4);
441NK_STATIC_ASSERT(
sizeof(nk_byte) == 1);
442NK_STATIC_ASSERT(
sizeof(nk_flags) >= 4);
443NK_STATIC_ASSERT(
sizeof(nk_rune) >= 4);
444NK_STATIC_ASSERT(
sizeof(nk_size) >=
sizeof(
void*));
445NK_STATIC_ASSERT(
sizeof(nk_ptr) >=
sizeof(
void*));
446#ifdef NK_INCLUDE_STANDARD_BOOL
447NK_STATIC_ASSERT(
sizeof(nk_bool) ==
sizeof(
bool));
449NK_STATIC_ASSERT(
sizeof(nk_bool) >= 2);
460struct nk_draw_command;
468struct nk_draw_vertex_layout_element;
472struct nk_style_slide;
483enum {nk_false, nk_true};
497enum nk_heading {NK_UP, NK_RIGHT, NK_DOWN, NK_LEFT};
498enum nk_button_behavior {NK_BUTTON_DEFAULT, NK_BUTTON_REPEATER};
499enum nk_modify {NK_FIXED = nk_false, NK_MODIFIABLE = nk_true};
500enum nk_orientation {NK_VERTICAL, NK_HORIZONTAL};
501enum nk_collapse_states {NK_MINIMIZED = nk_false, NK_MAXIMIZED = nk_true};
502enum nk_show_states {NK_HIDDEN = nk_false, NK_SHOWN = nk_true};
503enum nk_chart_type {NK_CHART_LINES, NK_CHART_COLUMN, NK_CHART_MAX};
504enum nk_chart_event {NK_CHART_HOVERING = 0x01, NK_CHART_CLICKED = 0x02};
505enum nk_color_format {NK_RGB, NK_RGBA};
506enum nk_popup_type {NK_POPUP_STATIC, NK_POPUP_DYNAMIC};
507enum nk_layout_format {NK_DYNAMIC, NK_STATIC};
508enum nk_tree_type {NK_TREE_NODE, NK_TREE_TAB};
510typedef void*(*nk_plugin_alloc)(
nk_handle,
void *old, nk_size);
511typedef void (*nk_plugin_free)(
nk_handle,
void *old);
512typedef nk_bool(*nk_plugin_filter)(
const struct nk_text_edit*, nk_rune unicode);
514typedef void(*nk_plugin_copy)(
nk_handle,
const char*,
int len);
518 nk_plugin_alloc alloc;
524 NK_SYMBOL_UNDERSCORE,
525 NK_SYMBOL_CIRCLE_SOLID,
526 NK_SYMBOL_CIRCLE_OUTLINE,
527 NK_SYMBOL_RECT_SOLID,
528 NK_SYMBOL_RECT_OUTLINE,
529 NK_SYMBOL_TRIANGLE_UP,
530 NK_SYMBOL_TRIANGLE_DOWN,
531 NK_SYMBOL_TRIANGLE_LEFT,
532 NK_SYMBOL_TRIANGLE_RIGHT,
535 NK_SYMBOL_TRIANGLE_UP_OUTLINE,
536 NK_SYMBOL_TRIANGLE_DOWN_OUTLINE,
537 NK_SYMBOL_TRIANGLE_LEFT_OUTLINE,
538 NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE,
581#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
694#ifdef NK_INCLUDE_COMMAND_USERDATA
793 NK_KEY_TEXT_INSERT_MODE,
794 NK_KEY_TEXT_REPLACE_MODE,
795 NK_KEY_TEXT_RESET_MODE,
796 NK_KEY_TEXT_LINE_START,
797 NK_KEY_TEXT_LINE_END,
802 NK_KEY_TEXT_SELECT_ALL,
803 NK_KEY_TEXT_WORD_LEFT,
804 NK_KEY_TEXT_WORD_RIGHT,
1189enum nk_anti_aliasing {NK_ANTI_ALIASING_OFF, NK_ANTI_ALIASING_ON};
1190enum nk_convert_result {
1191 NK_CONVERT_SUCCESS = 0,
1192 NK_CONVERT_INVALID_PARAM = 1,
1193 NK_CONVERT_COMMAND_BUFFER_FULL = NK_FLAG(1),
1194 NK_CONVERT_VERTEX_BUFFER_FULL = NK_FLAG(2),
1195 NK_CONVERT_ELEMENT_BUFFER_FULL = NK_FLAG(3)
1254#define nk_foreach(c, ctx) for((c) = nk__begin(ctx); (c) != 0; (c) = nk__next(ctx,c))
1256#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
1302NK_API
const struct nk_draw_command* nk__draw_begin(
const struct nk_context*,
const struct nk_buffer*);
1321NK_API
const struct nk_draw_command* nk__draw_end(
const struct nk_context*,
const struct nk_buffer*);
1340NK_API
const struct nk_draw_command* nk__draw_next(
const struct nk_draw_command*,
const struct nk_buffer*,
const struct nk_context*);
1357#define nk_draw_foreach(cmd,ctx, b) for((cmd)=nk__draw_begin(ctx, b); (cmd)!=0; (cmd)=nk__draw_next(cmd, b, ctx))
1507enum nk_panel_flags {
1508 NK_WINDOW_BORDER = NK_FLAG(0),
1509 NK_WINDOW_MOVABLE = NK_FLAG(1),
1510 NK_WINDOW_SCALABLE = NK_FLAG(2),
1511 NK_WINDOW_CLOSABLE = NK_FLAG(3),
1512 NK_WINDOW_MINIMIZABLE = NK_FLAG(4),
1513 NK_WINDOW_NO_SCROLLBAR = NK_FLAG(5),
1514 NK_WINDOW_TITLE = NK_FLAG(6),
1515 NK_WINDOW_SCROLL_AUTO_HIDE = NK_FLAG(7),
1516 NK_WINDOW_BACKGROUND = NK_FLAG(8),
1517 NK_WINDOW_SCALE_LEFT = NK_FLAG(9),
1518 NK_WINDOW_NO_INPUT = NK_FLAG(10)
2429enum nk_widget_align {
2430 NK_WIDGET_ALIGN_LEFT = 0x01,
2431 NK_WIDGET_ALIGN_CENTERED = 0x02,
2432 NK_WIDGET_ALIGN_RIGHT = 0x04,
2433 NK_WIDGET_ALIGN_TOP = 0x08,
2434 NK_WIDGET_ALIGN_MIDDLE = 0x10,
2435 NK_WIDGET_ALIGN_BOTTOM = 0x20
2437enum nk_widget_alignment {
2438 NK_WIDGET_LEFT = NK_WIDGET_ALIGN_MIDDLE|NK_WIDGET_ALIGN_LEFT,
2439 NK_WIDGET_CENTERED = NK_WIDGET_ALIGN_MIDDLE|NK_WIDGET_ALIGN_CENTERED,
2440 NK_WIDGET_RIGHT = NK_WIDGET_ALIGN_MIDDLE|NK_WIDGET_ALIGN_RIGHT
3102#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__)
3121#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)
3143NK_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);
3167#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__)
3189#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)
3277#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__)
3278#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)
3279NK_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);
3280NK_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);
3281NK_API
void nk_tree_element_pop(
struct nk_context*);
3290 int begin, end, count;
3294 nk_uint *scroll_pointer;
3295 nk_uint scroll_value;
3297NK_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);
3311 NK_WIDGET_STATE_MODIFIED = NK_FLAG(1),
3312 NK_WIDGET_STATE_INACTIVE = NK_FLAG(2),
3325NK_API
float nk_widget_width(
const struct nk_context*);
3326NK_API
float nk_widget_height(
const struct nk_context*);
3327NK_API nk_bool nk_widget_is_hovered(
const struct nk_context*);
3328NK_API nk_bool nk_widget_is_mouse_clicked(
const struct nk_context*,
enum nk_buttons);
3329NK_API nk_bool nk_widget_has_mouse_click_down(
const struct nk_context*,
enum nk_buttons, nk_bool down);
3330NK_API
void nk_spacing(
struct nk_context*,
int cols);
3331NK_API
void nk_widget_disable_begin(
struct nk_context* ctx);
3332NK_API
void nk_widget_disable_end(
struct nk_context* ctx);
3339 NK_TEXT_ALIGN_LEFT = 0x01,
3340 NK_TEXT_ALIGN_CENTERED = 0x02,
3341 NK_TEXT_ALIGN_RIGHT = 0x04,
3342 NK_TEXT_ALIGN_TOP = 0x08,
3343 NK_TEXT_ALIGN_MIDDLE = 0x10,
3344 NK_TEXT_ALIGN_BOTTOM = 0x20
3346enum nk_text_alignment {
3347 NK_TEXT_LEFT = NK_TEXT_ALIGN_MIDDLE|NK_TEXT_ALIGN_LEFT,
3348 NK_TEXT_CENTERED = NK_TEXT_ALIGN_MIDDLE|NK_TEXT_ALIGN_CENTERED,
3349 NK_TEXT_RIGHT = NK_TEXT_ALIGN_MIDDLE|NK_TEXT_ALIGN_RIGHT
3351NK_API
void nk_text(
struct nk_context*,
const char*,
int, nk_flags);
3352NK_API
void nk_text_colored(
struct nk_context*,
const char*,
int, nk_flags,
struct nk_color);
3353NK_API
void nk_text_wrap(
struct nk_context*,
const char*,
int);
3354NK_API
void nk_text_wrap_colored(
struct nk_context*,
const char*,
int,
struct nk_color);
3355NK_API
void nk_label(
struct nk_context*,
const char*, nk_flags align);
3356NK_API
void nk_label_colored(
struct nk_context*,
const char*, nk_flags align,
struct nk_color);
3357NK_API
void nk_label_wrap(
struct nk_context*,
const char*);
3361#ifdef NK_INCLUDE_STANDARD_VARARGS
3362NK_API
void nk_labelf(
struct nk_context*, nk_flags, NK_PRINTF_FORMAT_STRING
const char*, ...) NK_PRINTF_VARARG_FUNC(3);
3363NK_API
void nk_labelf_colored(struct
nk_context*, nk_flags, struct
nk_color, NK_PRINTF_FORMAT_STRING const
char*,...) NK_PRINTF_VARARG_FUNC(4);
3364NK_API
void nk_labelf_wrap(struct
nk_context*, NK_PRINTF_FORMAT_STRING const
char*,...) NK_PRINTF_VARARG_FUNC(2);
3365NK_API
void nk_labelf_colored_wrap(struct
nk_context*, struct
nk_color, NK_PRINTF_FORMAT_STRING const
char*,...) NK_PRINTF_VARARG_FUNC(3);
3366NK_API
void nk_labelfv(struct
nk_context*, nk_flags, NK_PRINTF_FORMAT_STRING const
char*, va_list) NK_PRINTF_VALIST_FUNC(3);
3367NK_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);
3368NK_API
void nk_labelfv_wrap(struct
nk_context*, NK_PRINTF_FORMAT_STRING const
char*, va_list) NK_PRINTF_VALIST_FUNC(2);
3369NK_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);
3370NK_API
void nk_value_bool(struct
nk_context*, const
char *prefix,
int);
3371NK_API
void nk_value_int(struct
nk_context*, const
char *prefix,
int);
3372NK_API
void nk_value_uint(struct
nk_context*, const
char *prefix,
unsigned int);
3373NK_API
void nk_value_float(struct
nk_context*, const
char *prefix,
float);
3374NK_API
void nk_value_color_byte(struct
nk_context*, const
char *prefix, struct
nk_color);
3375NK_API
void nk_value_color_float(struct
nk_context*, const
char *prefix, struct
nk_color);
3376NK_API
void nk_value_color_hex(struct
nk_context*, const
char *prefix, struct
nk_color);
3383NK_API nk_bool nk_button_text(
struct nk_context*,
const char *title,
int len);
3384NK_API nk_bool nk_button_label(
struct nk_context*,
const char *title);
3386NK_API nk_bool nk_button_symbol(
struct nk_context*,
enum nk_symbol_type);
3388NK_API nk_bool nk_button_symbol_label(
struct nk_context*,
enum nk_symbol_type,
const char*, nk_flags text_alignment);
3389NK_API nk_bool nk_button_symbol_text(
struct nk_context*,
enum nk_symbol_type,
const char*,
int, nk_flags alignment);
3390NK_API nk_bool nk_button_image_label(
struct nk_context*,
struct nk_image img,
const char*, nk_flags text_alignment);
3391NK_API nk_bool nk_button_image_text(
struct nk_context*,
struct nk_image img,
const char*,
int, nk_flags alignment);
3396NK_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);
3397NK_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);
3400NK_API
void nk_button_set_behavior(
struct nk_context*,
enum nk_button_behavior);
3401NK_API nk_bool nk_button_push_behavior(
struct nk_context*,
enum nk_button_behavior);
3402NK_API nk_bool nk_button_pop_behavior(
struct nk_context*);
3408NK_API nk_bool nk_check_label(
struct nk_context*,
const char*, nk_bool active);
3409NK_API nk_bool nk_check_text(
struct nk_context*,
const char*,
int, nk_bool active);
3410NK_API nk_bool nk_check_text_align(
struct nk_context*,
const char*,
int, nk_bool active, nk_flags widget_alignment, nk_flags text_alignment);
3411NK_API
unsigned nk_check_flags_label(
struct nk_context*,
const char*,
unsigned int flags,
unsigned int value);
3412NK_API
unsigned nk_check_flags_text(
struct nk_context*,
const char*,
int,
unsigned int flags,
unsigned int value);
3413NK_API nk_bool nk_checkbox_label(
struct nk_context*,
const char*, nk_bool *active);
3414NK_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);
3415NK_API nk_bool nk_checkbox_text(
struct nk_context*,
const char*,
int, nk_bool *active);
3416NK_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);
3417NK_API nk_bool nk_checkbox_flags_label(
struct nk_context*,
const char*,
unsigned int *flags,
unsigned int value);
3418NK_API nk_bool nk_checkbox_flags_text(
struct nk_context*,
const char*,
int,
unsigned int *flags,
unsigned int value);
3424NK_API nk_bool nk_radio_label(
struct nk_context*,
const char*, nk_bool *active);
3425NK_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);
3426NK_API nk_bool nk_radio_text(
struct nk_context*,
const char*,
int, nk_bool *active);
3427NK_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);
3428NK_API nk_bool nk_option_label(
struct nk_context*,
const char*, nk_bool active);
3429NK_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);
3430NK_API nk_bool nk_option_text(
struct nk_context*,
const char*,
int, nk_bool active);
3431NK_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);
3437NK_API nk_bool nk_selectable_label(
struct nk_context*,
const char*, nk_flags align, nk_bool *value);
3438NK_API nk_bool nk_selectable_text(
struct nk_context*,
const char*,
int, nk_flags align, nk_bool *value);
3439NK_API nk_bool nk_selectable_image_label(
struct nk_context*,
struct nk_image,
const char*, nk_flags align, nk_bool *value);
3440NK_API nk_bool nk_selectable_image_text(
struct nk_context*,
struct nk_image,
const char*,
int, nk_flags align, nk_bool *value);
3441NK_API nk_bool nk_selectable_symbol_label(
struct nk_context*,
enum nk_symbol_type,
const char*, nk_flags align, nk_bool *value);
3442NK_API nk_bool nk_selectable_symbol_text(
struct nk_context*,
enum nk_symbol_type,
const char*,
int, nk_flags align, nk_bool *value);
3444NK_API nk_bool nk_select_label(
struct nk_context*,
const char*, nk_flags align, nk_bool value);
3445NK_API nk_bool nk_select_text(
struct nk_context*,
const char*,
int, nk_flags align, nk_bool value);
3446NK_API nk_bool nk_select_image_label(
struct nk_context*,
struct nk_image,
const char*, nk_flags align, nk_bool value);
3447NK_API nk_bool nk_select_image_text(
struct nk_context*,
struct nk_image,
const char*,
int, nk_flags align, nk_bool value);
3448NK_API nk_bool nk_select_symbol_label(
struct nk_context*,
enum nk_symbol_type,
const char*, nk_flags align, nk_bool value);
3449NK_API nk_bool nk_select_symbol_text(
struct nk_context*,
enum nk_symbol_type,
const char*,
int, nk_flags align, nk_bool value);
3456NK_API
float nk_slide_float(
struct nk_context*,
float min,
float val,
float max,
float step);
3457NK_API
int nk_slide_int(
struct nk_context*,
int min,
int val,
int max,
int step);
3458NK_API nk_bool nk_slider_float(
struct nk_context*,
float min,
float *val,
float max,
float step);
3459NK_API nk_bool nk_slider_int(
struct nk_context*,
int min,
int *val,
int max,
int step);
3466NK_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);
3467NK_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);
3474NK_API nk_bool nk_progress(
struct nk_context*, nk_size *cur, nk_size max, nk_bool modifyable);
3475NK_API nk_size nk_prog(
struct nk_context*, nk_size cur, nk_size max, nk_bool modifyable);
3581NK_API
void nk_property_int(
struct nk_context*,
const char *name,
int min,
int *val,
int max,
int step,
float inc_per_pixel);
3673NK_API
float nk_propertyf(
struct nk_context*,
const char *name,
float min,
float val,
float max,
float step,
float inc_per_pixel);
3696NK_API
double nk_propertyd(
struct nk_context*,
const char *name,
double min,
double val,
double max,
double step,
float inc_per_pixel);
3704 NK_EDIT_DEFAULT = 0,
3705 NK_EDIT_READ_ONLY = NK_FLAG(0),
3706 NK_EDIT_AUTO_SELECT = NK_FLAG(1),
3707 NK_EDIT_SIG_ENTER = NK_FLAG(2),
3708 NK_EDIT_ALLOW_TAB = NK_FLAG(3),
3709 NK_EDIT_NO_CURSOR = NK_FLAG(4),
3710 NK_EDIT_SELECTABLE = NK_FLAG(5),
3711 NK_EDIT_CLIPBOARD = NK_FLAG(6),
3712 NK_EDIT_CTRL_ENTER_NEWLINE = NK_FLAG(7),
3713 NK_EDIT_NO_HORIZONTAL_SCROLL = NK_FLAG(8),
3714 NK_EDIT_ALWAYS_INSERT_MODE = NK_FLAG(9),
3715 NK_EDIT_MULTILINE = NK_FLAG(10),
3716 NK_EDIT_GOTO_END_ON_ACTIVATE = NK_FLAG(11)
3719 NK_EDIT_SIMPLE = NK_EDIT_ALWAYS_INSERT_MODE,
3720 NK_EDIT_FIELD = NK_EDIT_SIMPLE|NK_EDIT_SELECTABLE|NK_EDIT_CLIPBOARD,
3721 NK_EDIT_BOX = NK_EDIT_ALWAYS_INSERT_MODE| NK_EDIT_SELECTABLE| NK_EDIT_MULTILINE|NK_EDIT_ALLOW_TAB|NK_EDIT_CLIPBOARD,
3722 NK_EDIT_EDITOR = NK_EDIT_SELECTABLE|NK_EDIT_MULTILINE|NK_EDIT_ALLOW_TAB| NK_EDIT_CLIPBOARD
3725 NK_EDIT_ACTIVE = NK_FLAG(0),
3731NK_API nk_flags nk_edit_string(
struct nk_context*, nk_flags,
char *buffer,
int *len,
int max, nk_plugin_filter);
3732NK_API nk_flags nk_edit_string_zero_terminated(
struct nk_context*, nk_flags,
char *buffer,
int max, nk_plugin_filter);
3734NK_API
void nk_edit_focus(
struct nk_context*, nk_flags flags);
3735NK_API
void nk_edit_unfocus(
struct nk_context*);
3741NK_API nk_bool nk_chart_begin(
struct nk_context*,
enum nk_chart_type,
int num,
float min,
float max);
3742NK_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);
3743NK_API
void nk_chart_add_slot(
struct nk_context *ctx,
const enum nk_chart_type,
int count,
float min_value,
float max_value);
3744NK_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);
3745NK_API nk_flags nk_chart_push(
struct nk_context*,
float);
3746NK_API nk_flags nk_chart_push_slot(
struct nk_context*,
float,
int);
3748NK_API
void nk_plot(
struct nk_context*,
enum nk_chart_type,
const float *values,
int count,
int offset);
3749NK_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);
3755NK_API nk_bool nk_popup_begin(
struct nk_context*,
enum nk_popup_type,
const char*, nk_flags,
struct nk_rect bounds);
3756NK_API
void nk_popup_close(
struct nk_context*);
3758NK_API
void nk_popup_get_scroll(
const struct nk_context*, nk_uint *offset_x, nk_uint *offset_y);
3759NK_API
void nk_popup_set_scroll(
struct nk_context*, nk_uint offset_x, nk_uint offset_y);
3765NK_API
int nk_combo(
struct nk_context*,
const char *
const *items,
int count,
int selected,
int item_height,
struct nk_vec2 size);
3766NK_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);
3767NK_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);
3768NK_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);
3769NK_API
void nk_combobox(
struct nk_context*,
const char *
const *items,
int count,
int *selected,
int item_height,
struct nk_vec2 size);
3770NK_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);
3771NK_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);
3772NK_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);
3778NK_API nk_bool nk_combo_begin_text(
struct nk_context*,
const char *selected,
int,
struct nk_vec2 size);
3779NK_API nk_bool nk_combo_begin_label(
struct nk_context*,
const char *selected,
struct nk_vec2 size);
3781NK_API nk_bool nk_combo_begin_symbol(
struct nk_context*,
enum nk_symbol_type,
struct nk_vec2 size);
3782NK_API nk_bool nk_combo_begin_symbol_label(
struct nk_context*,
const char *selected,
enum nk_symbol_type,
struct nk_vec2 size);
3783NK_API nk_bool nk_combo_begin_symbol_text(
struct nk_context*,
const char *selected,
int,
enum nk_symbol_type,
struct nk_vec2 size);
3785NK_API nk_bool nk_combo_begin_image_label(
struct nk_context*,
const char *selected,
struct nk_image,
struct nk_vec2 size);
3786NK_API nk_bool nk_combo_begin_image_text(
struct nk_context*,
const char *selected,
int,
struct nk_image,
struct nk_vec2 size);
3787NK_API nk_bool nk_combo_item_label(
struct nk_context*,
const char*, nk_flags alignment);
3788NK_API nk_bool nk_combo_item_text(
struct nk_context*,
const char*,
int, nk_flags alignment);
3789NK_API nk_bool nk_combo_item_image_label(
struct nk_context*,
struct nk_image,
const char*, nk_flags alignment);
3790NK_API nk_bool nk_combo_item_image_text(
struct nk_context*,
struct nk_image,
const char*,
int,nk_flags alignment);
3791NK_API nk_bool nk_combo_item_symbol_label(
struct nk_context*,
enum nk_symbol_type,
const char*, nk_flags alignment);
3792NK_API nk_bool nk_combo_item_symbol_text(
struct nk_context*,
enum nk_symbol_type,
const char*,
int, nk_flags alignment);
3793NK_API
void nk_combo_close(
struct nk_context*);
3801NK_API nk_bool nk_contextual_item_text(
struct nk_context*,
const char*,
int,nk_flags align);
3802NK_API nk_bool nk_contextual_item_label(
struct nk_context*,
const char*, nk_flags align);
3803NK_API nk_bool nk_contextual_item_image_label(
struct nk_context*,
struct nk_image,
const char*, nk_flags alignment);
3804NK_API nk_bool nk_contextual_item_image_text(
struct nk_context*,
struct nk_image,
const char*,
int len, nk_flags alignment);
3805NK_API nk_bool nk_contextual_item_symbol_label(
struct nk_context*,
enum nk_symbol_type,
const char*, nk_flags alignment);
3806NK_API nk_bool nk_contextual_item_symbol_text(
struct nk_context*,
enum nk_symbol_type,
const char*,
int, nk_flags alignment);
3807NK_API
void nk_contextual_close(
struct nk_context*);
3808NK_API
void nk_contextual_end(
struct nk_context*);
3814NK_API
void nk_tooltip(
struct nk_context*,
const char*);
3815#ifdef NK_INCLUDE_STANDARD_VARARGS
3816NK_API
void nk_tooltipf(
struct nk_context*, NK_PRINTF_FORMAT_STRING
const char*, ...) NK_PRINTF_VARARG_FUNC(2);
3817NK_API
void nk_tooltipfv(struct
nk_context*, NK_PRINTF_FORMAT_STRING const
char*, va_list) NK_PRINTF_VALIST_FUNC(2);
3819NK_API nk_bool nk_tooltip_begin(
struct nk_context*,
float width);
3820NK_API
void nk_tooltip_end(
struct nk_context*);
3826NK_API
void nk_menubar_begin(
struct nk_context*);
3827NK_API
void nk_menubar_end(
struct nk_context*);
3828NK_API nk_bool nk_menu_begin_text(
struct nk_context*,
const char* title,
int title_len, nk_flags align,
struct nk_vec2 size);
3829NK_API nk_bool nk_menu_begin_label(
struct nk_context*,
const char*, nk_flags align,
struct nk_vec2 size);
3831NK_API nk_bool nk_menu_begin_image_text(
struct nk_context*,
const char*,
int,nk_flags align,
struct nk_image,
struct nk_vec2 size);
3832NK_API nk_bool nk_menu_begin_image_label(
struct nk_context*,
const char*, nk_flags align,
struct nk_image,
struct nk_vec2 size);
3833NK_API nk_bool nk_menu_begin_symbol(
struct nk_context*,
const char*,
enum nk_symbol_type,
struct nk_vec2 size);
3834NK_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);
3835NK_API nk_bool nk_menu_begin_symbol_label(
struct nk_context*,
const char*, nk_flags align,
enum nk_symbol_type,
struct nk_vec2 size);
3836NK_API nk_bool nk_menu_item_text(
struct nk_context*,
const char*,
int,nk_flags align);
3837NK_API nk_bool nk_menu_item_label(
struct nk_context*,
const char*, nk_flags alignment);
3838NK_API nk_bool nk_menu_item_image_label(
struct nk_context*,
struct nk_image,
const char*, nk_flags alignment);
3839NK_API nk_bool nk_menu_item_image_text(
struct nk_context*,
struct nk_image,
const char*,
int len, nk_flags alignment);
3840NK_API nk_bool nk_menu_item_symbol_text(
struct nk_context*,
enum nk_symbol_type,
const char*,
int, nk_flags alignment);
3841NK_API nk_bool nk_menu_item_symbol_label(
struct nk_context*,
enum nk_symbol_type,
const char*, nk_flags alignment);
3842NK_API
void nk_menu_close(
struct nk_context*);
3850#define NK_WIDGET_DISABLED_FACTOR 0.5f
3852enum nk_style_colors {
3858 NK_COLOR_BUTTON_HOVER,
3859 NK_COLOR_BUTTON_ACTIVE,
3861 NK_COLOR_TOGGLE_HOVER,
3862 NK_COLOR_TOGGLE_CURSOR,
3864 NK_COLOR_SELECT_ACTIVE,
3866 NK_COLOR_SLIDER_CURSOR,
3867 NK_COLOR_SLIDER_CURSOR_HOVER,
3868 NK_COLOR_SLIDER_CURSOR_ACTIVE,
3871 NK_COLOR_EDIT_CURSOR,
3874 NK_COLOR_CHART_COLOR,
3875 NK_COLOR_CHART_COLOR_HIGHLIGHT,
3877 NK_COLOR_SCROLLBAR_CURSOR,
3878 NK_COLOR_SCROLLBAR_CURSOR_HOVER,
3879 NK_COLOR_SCROLLBAR_CURSOR_ACTIVE,
3880 NK_COLOR_TAB_HEADER,
3882 NK_COLOR_KNOB_CURSOR,
3883 NK_COLOR_KNOB_CURSOR_HOVER,
3884 NK_COLOR_KNOB_CURSOR_ACTIVE,
3887enum nk_style_cursor {
3891 NK_CURSOR_RESIZE_VERTICAL,
3892 NK_CURSOR_RESIZE_HORIZONTAL,
3893 NK_CURSOR_RESIZE_TOP_LEFT_DOWN_RIGHT,
3894 NK_CURSOR_RESIZE_TOP_RIGHT_DOWN_LEFT,
3897NK_API
void nk_style_default(
struct nk_context*);
3899NK_API
void nk_style_load_cursor(
struct nk_context*,
enum nk_style_cursor,
const struct nk_cursor*);
3901NK_API
const char* nk_style_get_color_by_name(
enum nk_style_colors);
3903NK_API nk_bool nk_style_set_cursor(
struct nk_context*,
enum nk_style_cursor);
3904NK_API
void nk_style_show_cursor(
struct nk_context*);
3905NK_API
void nk_style_hide_cursor(
struct nk_context*);
3908NK_API nk_bool nk_style_push_float(
struct nk_context*,
float*,
float);
3911NK_API nk_bool nk_style_push_flags(
struct nk_context*, nk_flags*, nk_flags);
3914NK_API nk_bool nk_style_pop_font(
struct nk_context*);
3915NK_API nk_bool nk_style_pop_float(
struct nk_context*);
3916NK_API nk_bool nk_style_pop_vec2(
struct nk_context*);
3917NK_API nk_bool nk_style_pop_style_item(
struct nk_context*);
3918NK_API nk_bool nk_style_pop_flags(
struct nk_context*);
3919NK_API nk_bool nk_style_pop_color(
struct nk_context*);
3925NK_API
struct nk_color nk_rgb(int r, int g, int b);
3926NK_API
struct nk_color nk_rgb_iv(const int *rgb);
3927NK_API
struct nk_color nk_rgb_bv(const nk_byte* rgb);
3928NK_API
struct nk_color nk_rgb_f(float r, float g, float b);
3929NK_API
struct nk_color nk_rgb_fv(const float *rgb);
3931NK_API
struct nk_color nk_rgb_hex(const char *rgb);
3934NK_API
struct nk_color nk_rgba(int r, int g, int b, int a);
3935NK_API
struct nk_color nk_rgba_u32(nk_uint);
3936NK_API
struct nk_color nk_rgba_iv(const int *rgba);
3937NK_API
struct nk_color nk_rgba_bv(const nk_byte *rgba);
3938NK_API
struct nk_color nk_rgba_f(float r, float g, float b, float a);
3939NK_API
struct nk_color nk_rgba_fv(const float *rgba);
3941NK_API
struct nk_color nk_rgba_hex(const char *rgb);
3943NK_API
struct nk_colorf nk_hsva_colorf(float h, float s, float v, float a);
3944NK_API
struct nk_colorf nk_hsva_colorfv(const float *c);
3945NK_API
void nk_colorf_hsva_f(
float *out_h,
float *out_s,
float *out_v,
float *out_a,
struct nk_colorf in);
3946NK_API
void nk_colorf_hsva_fv(
float *hsva,
struct nk_colorf in);
3948NK_API
struct nk_color nk_hsv(int h, int s, int v);
3949NK_API
struct nk_color nk_hsv_iv(const int *hsv);
3950NK_API
struct nk_color nk_hsv_bv(const nk_byte *hsv);
3951NK_API
struct nk_color nk_hsv_f(float h, float s, float v);
3952NK_API
struct nk_color nk_hsv_fv(const float *hsv);
3954NK_API
struct nk_color nk_hsva(int h, int s, int v, int a);
3955NK_API
struct nk_color nk_hsva_iv(const int *hsva);
3956NK_API
struct nk_color nk_hsva_bv(const nk_byte *hsva);
3957NK_API
struct nk_color nk_hsva_f(float h, float s, float v, float a);
3958NK_API
struct nk_color nk_hsva_fv(const float *hsva);
3961NK_API
void nk_color_f(
float *r,
float *g,
float *b,
float *a,
struct nk_color);
3962NK_API
void nk_color_fv(
float *rgba_out,
struct nk_color);
3964NK_API
void nk_color_d(
double *r,
double *g,
double *b,
double *a,
struct nk_color);
3965NK_API
void nk_color_dv(
double *rgba_out,
struct nk_color);
3967NK_API nk_uint nk_color_u32(
struct nk_color);
3968NK_API
void nk_color_hex_rgba(
char *output,
struct nk_color);
3969NK_API
void nk_color_hex_rgb(
char *output,
struct nk_color);
3971NK_API
void nk_color_hsv_i(
int *out_h,
int *out_s,
int *out_v,
struct nk_color);
3972NK_API
void nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v,
struct nk_color);
3973NK_API
void nk_color_hsv_iv(
int *hsv_out,
struct nk_color);
3974NK_API
void nk_color_hsv_bv(nk_byte *hsv_out,
struct nk_color);
3975NK_API
void nk_color_hsv_f(
float *out_h,
float *out_s,
float *out_v,
struct nk_color);
3976NK_API
void nk_color_hsv_fv(
float *hsv_out,
struct nk_color);
3978NK_API
void nk_color_hsva_i(
int *h,
int *s,
int *v,
int *a,
struct nk_color);
3979NK_API
void nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a,
struct nk_color);
3980NK_API
void nk_color_hsva_iv(
int *hsva_out,
struct nk_color);
3981NK_API
void nk_color_hsva_bv(nk_byte *hsva_out,
struct nk_color);
3982NK_API
void nk_color_hsva_f(
float *out_h,
float *out_s,
float *out_v,
float *out_a,
struct nk_color);
3983NK_API
void nk_color_hsva_fv(
float *hsva_out,
struct nk_color);
3992NK_API
struct nk_image nk_image_ptr(void*);
3993NK_API
struct nk_image nk_image_id(int);
3994NK_API nk_bool nk_image_is_subimage(
const struct nk_image* img);
3995NK_API
struct nk_image nk_subimage_ptr(void*, nk_ushort w, nk_ushort h,
struct nk_rect sub_region);
3996NK_API
struct nk_image nk_subimage_id(int, nk_ushort w, nk_ushort h, struct
nk_rect sub_region);
4003NK_API
struct nk_nine_slice nk_nine_slice_handle(
nk_handle, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b);
4004NK_API
struct nk_nine_slice nk_nine_slice_ptr(void*, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b);
4005NK_API
struct nk_nine_slice nk_nine_slice_id(int, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b);
4006NK_API
int nk_nine_slice_is_sub9slice(
const struct nk_nine_slice* img);
4007NK_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);
4008NK_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);
4009NK_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);
4015NK_API nk_hash nk_murmur_hash(
const void *key,
int len, nk_hash seed);
4016NK_API
void nk_triangle_from_direction(
struct nk_vec2 *result,
struct nk_rect r,
float pad_x,
float pad_y,
enum nk_heading);
4020NK_API
struct nk_vec2 nk_vec2v(const float *xy);
4021NK_API
struct nk_vec2 nk_vec2iv(const int *xy);
4023NK_API
struct nk_rect nk_get_null_rect(void);
4024NK_API
struct nk_rect nk_rect(float x, float y, float w, float h);
4027NK_API
struct nk_rect nk_rectv(const float *xywh);
4028NK_API
struct nk_rect nk_rectiv(const int *xywh);
4036NK_API
int nk_strlen(
const char *str);
4037NK_API
int nk_stricmp(
const char *s1,
const char *s2);
4038NK_API
int nk_stricmpn(
const char *s1,
const char *s2,
int n);
4039NK_API
int nk_strtoi(
const char *str,
char **endptr);
4040NK_API
float nk_strtof(
const char *str,
char **endptr);
4042#define NK_STRTOD nk_strtod
4043NK_API
double nk_strtod(
const char *str,
char **endptr);
4045NK_API
int nk_strfilter(
const char *text,
const char *regexp);
4046NK_API
int nk_strmatch_fuzzy_string(
char const *str,
char const *pattern,
int *out_score);
4047NK_API
int nk_strmatch_fuzzy_text(
const char *txt,
int txt_len,
const char *pattern,
int *out_score);
4053NK_API
int nk_utf_decode(
const char*, nk_rune*,
int);
4054NK_API
int nk_utf_encode(nk_rune,
char*,
int);
4055NK_API
int nk_utf_len(
const char*,
int byte_len);
4056NK_API
const char* nk_utf_at(
const char *buffer,
int length,
int index, nk_rune *unicode,
int *len);
4214struct nk_user_font_glyph;
4215typedef float(*nk_text_width_f)(
nk_handle,
float h,
const char*,
int len);
4216typedef void(*nk_query_font_glyph_f)(
nk_handle handle,
float font_height,
4217 struct nk_user_font_glyph *glyph,
4218 nk_rune codepoint, nk_rune next_codepoint);
4220#if defined(NK_INCLUDE_VERTEX_BUFFER_OUTPUT) || defined(NK_INCLUDE_SOFTWARE_FONT)
4221struct nk_user_font_glyph {
4224 float width, height;
4233#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
4234 nk_query_font_glyph_f query;
4239#ifdef NK_INCLUDE_FONT_BAKING
4240enum nk_font_coord_type {
4246struct nk_baked_font {
4250 nk_rune glyph_offset;
4251 nk_rune glyph_count;
4252 const nk_rune *ranges;
4255struct nk_font_config {
4256 struct nk_font_config *next;
4260 unsigned char ttf_data_owned_by_atlas;
4261 unsigned char merge_mode;
4262 unsigned char pixel_snap;
4263 unsigned char oversample_v, oversample_h;
4264 unsigned char padding[3];
4267 enum nk_font_coord_type coord_type;
4269 const nk_rune *range;
4270 struct nk_baked_font *font;
4271 nk_rune fallback_glyph;
4272 struct nk_font_config *n;
4273 struct nk_font_config *p;
4276struct nk_font_glyph {
4279 float x0, y0, x1, y1, w, h;
4280 float u0, v0, u1, v1;
4284 struct nk_font *next;
4286 struct nk_baked_font info;
4288 struct nk_font_glyph *glyphs;
4289 const struct nk_font_glyph *fallback;
4290 nk_rune fallback_codepoint;
4292 struct nk_font_config *config;
4295enum nk_font_atlas_format {
4296 NK_FONT_ATLAS_ALPHA8,
4297 NK_FONT_ATLAS_RGBA32
4300struct nk_font_atlas {
4309 struct nk_cursor cursors[NK_CURSOR_COUNT];
4312 struct nk_font_glyph *glyphs;
4313 struct nk_font *default_font;
4314 struct nk_font *fonts;
4315 struct nk_font_config *config;
4320NK_API
const nk_rune *nk_font_default_glyph_ranges(
void);
4321NK_API
const nk_rune *nk_font_chinese_glyph_ranges(
void);
4322NK_API
const nk_rune *nk_font_cyrillic_glyph_ranges(
void);
4323NK_API
const nk_rune *nk_font_korean_glyph_ranges(
void);
4325#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4326NK_API
void nk_font_atlas_init_default(
struct nk_font_atlas*);
4328NK_API
void nk_font_atlas_init(
struct nk_font_atlas*,
const struct nk_allocator*);
4329NK_API
void nk_font_atlas_init_custom(
struct nk_font_atlas*,
const struct nk_allocator *persistent,
const struct nk_allocator *transient);
4330NK_API
void nk_font_atlas_begin(
struct nk_font_atlas*);
4331NK_API
struct nk_font_config nk_font_config(float pixel_height);
4332NK_API
struct nk_font *nk_font_atlas_add(
struct nk_font_atlas*,
const struct nk_font_config*);
4333#ifdef NK_INCLUDE_DEFAULT_FONT
4334NK_API
struct nk_font* nk_font_atlas_add_default(
struct nk_font_atlas*,
float height,
const struct nk_font_config*);
4336NK_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);
4337#ifdef NK_INCLUDE_STANDARD_IO
4338NK_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*);
4340NK_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*);
4341NK_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);
4342NK_API
const void* nk_font_atlas_bake(
struct nk_font_atlas*,
int *width,
int *height,
enum nk_font_atlas_format);
4344NK_API
const struct nk_font_glyph* nk_font_find_glyph(
const struct nk_font*, nk_rune unicode);
4345NK_API
void nk_font_atlas_cleanup(
struct nk_font_atlas *atlas);
4346NK_API
void nk_font_atlas_clear(
struct nk_font_atlas*);
4395enum nk_allocation_type {
4400enum nk_buffer_allocation_type {
4424#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4425NK_API
void nk_buffer_init_default(
struct nk_buffer*);
4428NK_API
void nk_buffer_init_fixed(
struct nk_buffer*,
void *memory, nk_size size);
4430NK_API
void nk_buffer_push(
struct nk_buffer*,
enum nk_buffer_allocation_type type,
const void *memory, nk_size size, nk_size align);
4431NK_API
void nk_buffer_mark(
struct nk_buffer*,
enum nk_buffer_allocation_type type);
4432NK_API
void nk_buffer_reset(
struct nk_buffer*,
enum nk_buffer_allocation_type type);
4433NK_API
void nk_buffer_clear(
struct nk_buffer*);
4434NK_API
void nk_buffer_free(
struct nk_buffer*);
4435NK_API
void *nk_buffer_memory(
struct nk_buffer*);
4436NK_API
const void *nk_buffer_memory_const(
const struct nk_buffer*);
4437NK_API nk_size nk_buffer_total(
const struct nk_buffer*);
4454#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4455NK_API
void nk_str_init_default(
struct nk_str*);
4459NK_API
void nk_str_clear(
struct nk_str*);
4460NK_API
void nk_str_free(
struct nk_str*);
4462NK_API
int nk_str_append_text_char(
struct nk_str*,
const char*,
int);
4463NK_API
int nk_str_append_str_char(
struct nk_str*,
const char*);
4464NK_API
int nk_str_append_text_utf8(
struct nk_str*,
const char*,
int);
4465NK_API
int nk_str_append_str_utf8(
struct nk_str*,
const char*);
4466NK_API
int nk_str_append_text_runes(
struct nk_str*,
const nk_rune*,
int);
4467NK_API
int nk_str_append_str_runes(
struct nk_str*,
const nk_rune*);
4469NK_API
int nk_str_insert_at_char(
struct nk_str*,
int pos,
const char*,
int);
4470NK_API
int nk_str_insert_at_rune(
struct nk_str*,
int pos,
const char*,
int);
4472NK_API
int nk_str_insert_text_char(
struct nk_str*,
int pos,
const char*,
int);
4473NK_API
int nk_str_insert_str_char(
struct nk_str*,
int pos,
const char*);
4474NK_API
int nk_str_insert_text_utf8(
struct nk_str*,
int pos,
const char*,
int);
4475NK_API
int nk_str_insert_str_utf8(
struct nk_str*,
int pos,
const char*);
4476NK_API
int nk_str_insert_text_runes(
struct nk_str*,
int pos,
const nk_rune*,
int);
4477NK_API
int nk_str_insert_str_runes(
struct nk_str*,
int pos,
const nk_rune*);
4479NK_API
void nk_str_remove_chars(
struct nk_str*,
int len);
4480NK_API
void nk_str_remove_runes(
struct nk_str *str,
int len);
4481NK_API
void nk_str_delete_chars(
struct nk_str*,
int pos,
int len);
4482NK_API
void nk_str_delete_runes(
struct nk_str*,
int pos,
int len);
4484NK_API
char *nk_str_at_char(
struct nk_str*,
int pos);
4485NK_API
char *nk_str_at_rune(
struct nk_str*,
int pos, nk_rune *unicode,
int *len);
4486NK_API nk_rune nk_str_rune_at(
const struct nk_str*,
int pos);
4487NK_API
const char *nk_str_at_char_const(
const struct nk_str*,
int pos);
4488NK_API
const char *nk_str_at_const(
const struct nk_str*,
int pos, nk_rune *unicode,
int *len);
4490NK_API
char *nk_str_get(
struct nk_str*);
4491NK_API
const char *nk_str_get_const(
const struct nk_str*);
4492NK_API
int nk_str_len(
const struct nk_str*);
4493NK_API
int nk_str_len_char(
const struct nk_str*);
4526#ifndef NK_TEXTEDIT_UNDOSTATECOUNT
4527#define NK_TEXTEDIT_UNDOSTATECOUNT 99
4530#ifndef NK_TEXTEDIT_UNDOCHARCOUNT
4531#define NK_TEXTEDIT_UNDOCHARCOUNT 999
4537 nk_plugin_paste paste;
4538 nk_plugin_copy copy;
4543 short insert_length;
4544 short delete_length;
4550 nk_rune undo_char[NK_TEXTEDIT_UNDOCHARCOUNT];
4553 short undo_char_point;
4554 short redo_char_point;
4557enum nk_text_edit_type {
4558 NK_TEXT_EDIT_SINGLE_LINE,
4559 NK_TEXT_EDIT_MULTI_LINE
4562enum nk_text_edit_mode {
4563 NK_TEXT_EDIT_MODE_VIEW,
4564 NK_TEXT_EDIT_MODE_INSERT,
4565 NK_TEXT_EDIT_MODE_REPLACE
4571 nk_plugin_filter filter;
4578 unsigned char cursor_at_end_of_line;
4579 unsigned char initialized;
4580 unsigned char has_preferred_x;
4581 unsigned char single_line;
4582 unsigned char active;
4583 unsigned char padding1;
4590NK_API nk_bool nk_filter_ascii(
const struct nk_text_edit*, nk_rune unicode);
4591NK_API nk_bool nk_filter_float(
const struct nk_text_edit*, nk_rune unicode);
4592NK_API nk_bool nk_filter_decimal(
const struct nk_text_edit*, nk_rune unicode);
4593NK_API nk_bool nk_filter_hex(
const struct nk_text_edit*, nk_rune unicode);
4594NK_API nk_bool nk_filter_oct(
const struct nk_text_edit*, nk_rune unicode);
4595NK_API nk_bool nk_filter_binary(
const struct nk_text_edit*, nk_rune unicode);
4598#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4599NK_API
void nk_textedit_init_default(
struct nk_text_edit*);
4602NK_API
void nk_textedit_init_fixed(
struct nk_text_edit*,
void *memory, nk_size size);
4604NK_API
void nk_textedit_text(
struct nk_text_edit*,
const char*,
int total_len);
4605NK_API
void nk_textedit_delete(
struct nk_text_edit*,
int where,
int len);
4606NK_API
void nk_textedit_delete_selection(
struct nk_text_edit*);
4607NK_API
void nk_textedit_select_all(
struct nk_text_edit*);
4609NK_API nk_bool nk_textedit_paste(
struct nk_text_edit*,
char const*,
int len);
4667enum nk_command_type {
4673 NK_COMMAND_RECT_FILLED,
4674 NK_COMMAND_RECT_MULTI_COLOR,
4676 NK_COMMAND_CIRCLE_FILLED,
4678 NK_COMMAND_ARC_FILLED,
4679 NK_COMMAND_TRIANGLE,
4680 NK_COMMAND_TRIANGLE_FILLED,
4682 NK_COMMAND_POLYGON_FILLED,
4683 NK_COMMAND_POLYLINE,
4691 enum nk_command_type type;
4693#ifdef NK_INCLUDE_COMMAND_USERDATA
4701 unsigned short w, h;
4706 unsigned short line_thickness;
4714 unsigned short line_thickness;
4723 unsigned short rounding;
4724 unsigned short line_thickness;
4726 unsigned short w, h;
4732 unsigned short rounding;
4734 unsigned short w, h;
4741 unsigned short w, h;
4750 unsigned short line_thickness;
4768 unsigned short line_thickness;
4769 unsigned short w, h;
4776 unsigned short w, h;
4784 unsigned short line_thickness;
4800 unsigned short line_thickness;
4801 unsigned short point_count;
4808 unsigned short point_count;
4815 unsigned short line_thickness;
4816 unsigned short point_count;
4823 unsigned short w, h;
4828typedef void (*nk_command_custom_callback)(
void *canvas,
short x,
short y,
4829 unsigned short w,
unsigned short h,
nk_handle callback_data);
4833 unsigned short w, h;
4835 nk_command_custom_callback callback;
4844 unsigned short w, h;
4850enum nk_command_clipping {
4851 NK_CLIPPING_OFF = nk_false,
4852 NK_CLIPPING_ON = nk_true
4860 nk_size begin, end, last;
4865NK_API
void nk_stroke_curve(
struct nk_command_buffer*,
float,
float,
float,
float,
float,
float,
float,
float,
float line_thickness,
struct nk_color);
4868NK_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);
4869NK_API
void nk_stroke_triangle(
struct nk_command_buffer*,
float,
float,
float,
float,
float,
float,
float line_thichness,
struct nk_color);
4870NK_API
void nk_stroke_polyline(
struct nk_command_buffer*,
const float *points,
int point_count,
float line_thickness,
struct nk_color col);
4871NK_API
void nk_stroke_polygon(
struct nk_command_buffer*,
const float *points,
int point_count,
float line_thickness,
struct nk_color);
4877NK_API
void nk_fill_arc(
struct nk_command_buffer*,
float cx,
float cy,
float radius,
float a_min,
float a_max,
struct nk_color);
4878NK_API
void nk_fill_triangle(
struct nk_command_buffer*,
float x0,
float y0,
float x1,
float y1,
float x2,
float y2,
struct nk_color);
4895 unsigned int clicked;
4901#ifdef NK_BUTTON_TRIGGER_ON_RELEASE
4908 unsigned char grabbed;
4909 unsigned char ungrab;
4914 unsigned int clicked;
4917 struct nk_key keys[NK_KEY_MAX];
4918 char text[NK_INPUT_MAX];
4927NK_API nk_bool nk_input_has_mouse_click(
const struct nk_input*,
enum nk_buttons);
4928NK_API nk_bool nk_input_has_mouse_click_in_rect(
const struct nk_input*,
enum nk_buttons,
struct nk_rect);
4929NK_API nk_bool nk_input_has_mouse_click_in_button_rect(
const struct nk_input*,
enum nk_buttons,
struct nk_rect);
4930NK_API nk_bool nk_input_has_mouse_click_down_in_rect(
const struct nk_input*,
enum nk_buttons,
struct nk_rect, nk_bool down);
4931NK_API nk_bool nk_input_is_mouse_click_in_rect(
const struct nk_input*,
enum nk_buttons,
struct nk_rect);
4932NK_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);
4933NK_API nk_bool nk_input_any_mouse_click_in_rect(
const struct nk_input*,
struct nk_rect);
4934NK_API nk_bool nk_input_is_mouse_prev_hovering_rect(
const struct nk_input*,
struct nk_rect);
4935NK_API nk_bool nk_input_is_mouse_hovering_rect(
const struct nk_input*,
struct nk_rect);
4936NK_API nk_bool nk_input_mouse_clicked(
const struct nk_input*,
enum nk_buttons,
struct nk_rect);
4937NK_API nk_bool nk_input_is_mouse_down(
const struct nk_input*,
enum nk_buttons);
4938NK_API nk_bool nk_input_is_mouse_pressed(
const struct nk_input*,
enum nk_buttons);
4939NK_API nk_bool nk_input_is_mouse_released(
const struct nk_input*,
enum nk_buttons);
4940NK_API nk_bool nk_input_is_key_pressed(
const struct nk_input*,
enum nk_keys);
4941NK_API nk_bool nk_input_is_key_released(
const struct nk_input*,
enum nk_keys);
4942NK_API nk_bool nk_input_is_key_down(
const struct nk_input*,
enum nk_keys);
4949#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
4966#ifdef NK_UINT_DRAW_INDEX
4967typedef nk_uint nk_draw_index;
4969typedef nk_ushort nk_draw_index;
4971enum nk_draw_list_stroke {
4972 NK_STROKE_OPEN = nk_false,
4973 NK_STROKE_CLOSED = nk_true
4976enum nk_draw_vertex_layout_attribute {
4980 NK_VERTEX_ATTRIBUTE_COUNT
4983enum nk_draw_vertex_layout_format {
4993NK_FORMAT_COLOR_BEGIN,
4994 NK_FORMAT_R8G8B8 = NK_FORMAT_COLOR_BEGIN,
4995 NK_FORMAT_R16G15B16,
4996 NK_FORMAT_R32G32B32,
5000 NK_FORMAT_R16G15B16A16,
5001 NK_FORMAT_R32G32B32A32,
5002 NK_FORMAT_R32G32B32A32_FLOAT,
5003 NK_FORMAT_R32G32B32A32_DOUBLE,
5007NK_FORMAT_COLOR_END = NK_FORMAT_RGBA32,
5011#define NK_VERTEX_LAYOUT_END NK_VERTEX_ATTRIBUTE_COUNT,NK_FORMAT_COUNT,0
5012struct nk_draw_vertex_layout_element {
5013 enum nk_draw_vertex_layout_attribute attribute;
5014 enum nk_draw_vertex_layout_format format;
5018struct nk_draw_command {
5019 unsigned int elem_count;
5022#ifdef NK_INCLUDE_COMMAND_USERDATA
5027struct nk_draw_list {
5029 struct nk_vec2 circle_vtx[12];
5036 unsigned int element_count;
5037 unsigned int vertex_count;
5038 unsigned int cmd_count;
5041 unsigned int path_count;
5042 unsigned int path_offset;
5044 enum nk_anti_aliasing line_AA;
5045 enum nk_anti_aliasing shape_AA;
5047#ifdef NK_INCLUDE_COMMAND_USERDATA
5053NK_API
void nk_draw_list_init(
struct nk_draw_list*);
5054NK_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);
5057#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))
5058NK_API
const struct nk_draw_command* nk__draw_list_begin(
const struct nk_draw_list*,
const struct nk_buffer*);
5059NK_API
const struct nk_draw_command* nk__draw_list_next(
const struct nk_draw_command*,
const struct nk_buffer*,
const struct nk_draw_list*);
5060NK_API
const struct nk_draw_command* nk__draw_list_end(
const struct nk_draw_list*,
const struct nk_buffer*);
5063NK_API
void nk_draw_list_path_clear(
struct nk_draw_list*);
5064NK_API
void nk_draw_list_path_line_to(
struct nk_draw_list*,
struct nk_vec2 pos);
5065NK_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);
5066NK_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);
5067NK_API
void nk_draw_list_path_rect_to(
struct nk_draw_list*,
struct nk_vec2 a,
struct nk_vec2 b,
float rounding);
5068NK_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);
5069NK_API
void nk_draw_list_path_fill(
struct nk_draw_list*,
struct nk_color);
5070NK_API
void nk_draw_list_path_stroke(
struct nk_draw_list*,
struct nk_color,
enum nk_draw_list_stroke closed,
float thickness);
5073NK_API
void nk_draw_list_stroke_line(
struct nk_draw_list*,
struct nk_vec2 a,
struct nk_vec2 b,
struct nk_color,
float thickness);
5074NK_API
void nk_draw_list_stroke_rect(
struct nk_draw_list*,
struct nk_rect rect,
struct nk_color,
float rounding,
float thickness);
5075NK_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);
5076NK_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);
5077NK_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);
5078NK_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);
5081NK_API
void nk_draw_list_fill_rect(
struct nk_draw_list*,
struct nk_rect rect,
struct nk_color,
float rounding);
5084NK_API
void nk_draw_list_fill_circle(
struct nk_draw_list*,
struct nk_vec2 center,
float radius,
struct nk_color col,
unsigned int segs);
5085NK_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);
5088NK_API
void nk_draw_list_add_image(
struct nk_draw_list*,
struct nk_image texture,
struct nk_rect rect,
struct nk_color);
5089NK_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);
5090#ifdef NK_INCLUDE_COMMAND_USERDATA
5091NK_API
void nk_draw_list_push_userdata(
struct nk_draw_list*,
nk_handle userdata);
5101enum nk_style_item_type {
5102 NK_STYLE_ITEM_COLOR,
5103 NK_STYLE_ITEM_IMAGE,
5104 NK_STYLE_ITEM_NINE_SLICE
5114 enum nk_style_item_type type;
5122 float disabled_factor;
5131 float color_factor_background;
5138 nk_flags text_alignment;
5139 float color_factor_text;
5147 float disabled_factor;
5171 nk_flags text_alignment;
5179 float disabled_factor;
5204 struct nk_color text_normal_active;
5206 struct nk_color text_pressed_active;
5208 nk_flags text_alignment;
5216 float disabled_factor;
5250 float disabled_factor;
5256 enum nk_symbol_type inc_symbol;
5257 enum nk_symbol_type dec_symbol;
5290 float disabled_factor;
5309 struct nk_color cursor_border_color;
5314 float cursor_border;
5315 float cursor_rounding;
5318 float disabled_factor;
5337 struct nk_color cursor_border_color;
5342 float border_cursor;
5343 float rounding_cursor;
5346 float disabled_factor;
5352 enum nk_symbol_type inc_symbol;
5353 enum nk_symbol_type dec_symbol;
5372 struct nk_color cursor_text_normal;
5383 struct nk_color selected_text_normal;
5384 struct nk_color selected_text_hover;
5390 struct nk_vec2 scrollbar_size;
5394 float disabled_factor;
5410 enum nk_symbol_type sym_left;
5411 enum nk_symbol_type sym_right;
5418 float disabled_factor;
5442 float disabled_factor;
5443 nk_bool show_markers;
5465 enum nk_symbol_type sym_normal;
5466 enum nk_symbol_type sym_hover;
5467 enum nk_symbol_type sym_active;
5472 struct nk_vec2 content_padding;
5473 struct nk_vec2 button_padding;
5476 float disabled_factor;
5490 enum nk_symbol_type sym_minimize;
5491 enum nk_symbol_type sym_maximize;
5500 float disabled_factor;
5503enum nk_style_header_align {
5516 enum nk_symbol_type close_symbol;
5517 enum nk_symbol_type minimize_symbol;
5518 enum nk_symbol_type maximize_symbol;
5526 enum nk_style_header_align align;
5538 struct nk_color popup_border_color;
5539 struct nk_color combo_border_color;
5540 struct nk_color contextual_border_color;
5542 struct nk_color group_border_color;
5543 struct nk_color tooltip_border_color;
5548 float contextual_border;
5551 float tooltip_border;
5553 float min_row_height_padding;
5557 struct nk_vec2 scrollbar_size;
5564 struct nk_vec2 contextual_padding;
5566 struct nk_vec2 tooltip_padding;
5571 const struct nk_cursor *cursors[NK_CURSOR_COUNT];
5604#ifndef NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS
5605#define NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS 16
5607#ifndef NK_CHART_MAX_SLOT
5608#define NK_CHART_MAX_SLOT 4
5613 NK_PANEL_WINDOW = NK_FLAG(0),
5614 NK_PANEL_GROUP = NK_FLAG(1),
5615 NK_PANEL_POPUP = NK_FLAG(2),
5616 NK_PANEL_CONTEXTUAL = NK_FLAG(4),
5617 NK_PANEL_COMBO = NK_FLAG(5),
5618 NK_PANEL_MENU = NK_FLAG(6),
5619 NK_PANEL_TOOLTIP = NK_FLAG(7)
5622 NK_PANEL_SET_NONBLOCK = NK_PANEL_CONTEXTUAL|NK_PANEL_COMBO|NK_PANEL_MENU|NK_PANEL_TOOLTIP,
5623 NK_PANEL_SET_POPUP = NK_PANEL_SET_NONBLOCK|NK_PANEL_POPUP,
5624 NK_PANEL_SET_SUB = NK_PANEL_SET_POPUP|NK_PANEL_GROUP
5628 enum nk_chart_type type;
5631 float min, max, range;
5635 nk_bool show_markers;
5644enum nk_panel_row_layout_type {
5645 NK_LAYOUT_DYNAMIC_FIXED = 0,
5646 NK_LAYOUT_DYNAMIC_ROW,
5647 NK_LAYOUT_DYNAMIC_FREE,
5649 NK_LAYOUT_STATIC_FIXED,
5650 NK_LAYOUT_STATIC_ROW,
5651 NK_LAYOUT_STATIC_FREE,
5657 enum nk_panel_row_layout_type type;
5669 float templates[NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS];
5686 enum nk_panel_type type;
5691 float at_x, at_y, max_x;
5692 float footer_height;
5693 float header_height;
5695 unsigned int has_scrolling;
5707#ifndef NK_WINDOW_MAX_NAME
5708#define NK_WINDOW_MAX_NAME 64
5713 NK_WINDOW_PRIVATE = NK_FLAG(11),
5725 enum nk_panel_type type;
5729 unsigned combo_count;
5730 unsigned con_count, con_old;
5731 unsigned active_con;
5745 unsigned char single_line;
5750 char buffer[NK_MAX_NUMBER_BUFFER];
5764 char name_string[NK_WINDOW_MAX_NAME];
5771 float scrollbar_hiding_timer;
5777 unsigned int scrolled;
5778 nk_bool widgets_disabled;
5781 unsigned int table_count;
5818#ifndef NK_BUTTON_BEHAVIOR_STACK_SIZE
5819#define NK_BUTTON_BEHAVIOR_STACK_SIZE 8
5822#ifndef NK_FONT_STACK_SIZE
5823#define NK_FONT_STACK_SIZE 8
5826#ifndef NK_STYLE_ITEM_STACK_SIZE
5827#define NK_STYLE_ITEM_STACK_SIZE 16
5830#ifndef NK_FLOAT_STACK_SIZE
5831#define NK_FLOAT_STACK_SIZE 32
5834#ifndef NK_VECTOR_STACK_SIZE
5835#define NK_VECTOR_STACK_SIZE 16
5838#ifndef NK_FLAGS_STACK_SIZE
5839#define NK_FLAGS_STACK_SIZE 32
5842#ifndef NK_COLOR_STACK_SIZE
5843#define NK_COLOR_STACK_SIZE 32
5846#define NK_CONFIGURATION_STACK_TYPE(prefix, name, type)\
5847 struct nk_config_stack_##name##_element {\
5848 prefix##_##type *address;\
5849 prefix##_##type old_value;\
5851#define NK_CONFIG_STACK(type,size)\
5852 struct nk_config_stack_##type {\
5854 struct nk_config_stack_##type##_element elements[size];\
5857#define nk_float float
5858NK_CONFIGURATION_STACK_TYPE(
struct nk, style_item, style_item);
5859NK_CONFIGURATION_STACK_TYPE(nk ,
float,
float);
5860NK_CONFIGURATION_STACK_TYPE(
struct nk,
vec2,
vec2);
5861NK_CONFIGURATION_STACK_TYPE(nk ,flags, flags);
5862NK_CONFIGURATION_STACK_TYPE(
struct nk, color, color);
5863NK_CONFIGURATION_STACK_TYPE(
const struct nk, user_font, user_font*);
5864NK_CONFIGURATION_STACK_TYPE(
enum nk, button_behavior, button_behavior);
5866NK_CONFIG_STACK(style_item, NK_STYLE_ITEM_STACK_SIZE);
5867NK_CONFIG_STACK(
float, NK_FLOAT_STACK_SIZE);
5868NK_CONFIG_STACK(
vec2, NK_VECTOR_STACK_SIZE);
5869NK_CONFIG_STACK(flags, NK_FLAGS_STACK_SIZE);
5870NK_CONFIG_STACK(color, NK_COLOR_STACK_SIZE);
5871NK_CONFIG_STACK(user_font, NK_FONT_STACK_SIZE);
5872NK_CONFIG_STACK(button_behavior, NK_BUTTON_BEHAVIOR_STACK_SIZE);
5875 struct nk_config_stack_style_item style_items;
5876 struct nk_config_stack_float floats;
5877 struct nk_config_stack_vec2 vectors;
5878 struct nk_config_stack_flags flags;
5879 struct nk_config_stack_color colors;
5880 struct nk_config_stack_user_font fonts;
5881 struct nk_config_stack_button_behavior button_behaviors;
5887#define NK_VALUE_PAGE_CAPACITY \
5888 (((NK_MAX(sizeof(struct nk_window),sizeof(struct nk_panel)) / sizeof(nk_uint))) / 2)
5893 nk_hash keys[NK_VALUE_PAGE_CAPACITY];
5894 nk_uint values[NK_VALUE_PAGE_CAPACITY];
5918 enum nk_allocation_type type;
5919 unsigned int page_count;
5933 nk_flags last_widget_state;
5934 enum nk_button_behavior button_behavior;
5936 float delta_time_seconds;
5941#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
5942 struct nk_draw_list draw_list;
5944#ifdef NK_INCLUDE_COMMAND_USERDATA
5971#define NK_PI 3.141592654f
5972#define NK_PI_HALF 1.570796326f
5973#define NK_UTF_INVALID 0xFFFD
5974#define NK_MAX_FLOAT_PRECISION 2
5976#define NK_UNUSED(x) ((void)(x))
5977#define NK_SATURATE(x) (NK_MAX(0, NK_MIN(1.0f, x)))
5978#define NK_LEN(a) (sizeof(a)/sizeof(a)[0])
5979#define NK_ABS(a) (((a) < 0) ? -(a) : (a))
5980#define NK_BETWEEN(x, a, b) ((a) <= (x) && (x) < (b))
5981#define NK_INBOX(px, py, x, y, w, h)\
5982 (NK_BETWEEN(px,x,x+w) && NK_BETWEEN(py,y,y+h))
5983#define NK_INTERSECT(x0, y0, w0, h0, x1, y1, w1, h1) \
5984 ((x1 < (x0 + w0)) && (x0 < (x1 + w1)) && \
5985 (y1 < (y0 + h0)) && (y0 < (y1 + h1)))
5986#define NK_CONTAINS(x, y, w, h, bx, by, bw, bh)\
5987 (NK_INBOX(x,y, bx, by, bw, bh) && NK_INBOX(x+w,y+h, bx, by, bw, bh))
5989#define nk_vec2_sub(a, b) nk_vec2((a).x - (b).x, (a).y - (b).y)
5990#define nk_vec2_add(a, b) nk_vec2((a).x + (b).x, (a).y + (b).y)
5991#define nk_vec2_len_sqr(a) ((a).x*(a).x+(a).y*(a).y)
5992#define nk_vec2_muls(a, t) nk_vec2((a).x * (t), (a).y * (t))
5994#define nk_ptr_add(t, p, i) ((t*)((void*)((nk_byte*)(p) + (i))))
5995#define nk_ptr_add_const(t, p, i) ((const t*)((const void*)((const nk_byte*)(p) + (i))))
5996#define nk_zero_struct(s) nk_zero(&s, sizeof(s))
6002#if defined(__PTRDIFF_TYPE__)
6003# define NK_UINT_TO_PTR(x) ((void*)(__PTRDIFF_TYPE__)(x))
6004# define NK_PTR_TO_UINT(x) ((nk_size)(__PTRDIFF_TYPE__)(x))
6005#elif !defined(__GNUC__)
6006# define NK_UINT_TO_PTR(x) ((void*)&((char*)0)[x])
6007# define NK_PTR_TO_UINT(x) ((nk_size)(((char*)x)-(char*)0))
6008#elif defined(NK_USE_FIXED_TYPES)
6009# define NK_UINT_TO_PTR(x) ((void*)(uintptr_t)(x))
6010# define NK_PTR_TO_UINT(x) ((uintptr_t)(x))
6012# define NK_UINT_TO_PTR(x) ((void*)(x))
6013# define NK_PTR_TO_UINT(x) ((nk_size)(x))
6016#define NK_ALIGN_PTR(x, mask)\
6017 (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte*)(x) + (mask-1)) & ~(mask-1))))
6018#define NK_ALIGN_PTR_BACK(x, mask)\
6019 (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte*)(x)) & ~(mask-1))))
6021#if ((defined(__GNUC__) && __GNUC__ >= 4) || defined(__clang__)) && !defined(EMSCRIPTEN)
6022#define NK_OFFSETOF(st,m) (__builtin_offsetof(st,m))
6024#define NK_OFFSETOF(st,m) ((nk_ptr)&(((st*)0)->m))
6032template<
typename T>
struct nk_alignof;
6033template<
typename T,
int size_diff>
struct nk_helper{
enum {value = size_diff};};
6034template<
typename T>
struct nk_helper<T,0>{
enum {value = nk_alignof<T>::value};};
6035template<
typename T>
struct nk_alignof{
struct Big {T x;
char c;};
enum {
6036 diff =
sizeof(Big) -
sizeof(T), value = nk_helper<Big, diff>::value};};
6037#define NK_ALIGNOF(t) (nk_alignof<t>::value)
6039#define NK_ALIGNOF(t) NK_OFFSETOF(struct {char c; t _h;}, _h)
6042#define NK_CONTAINER_OF(ptr,type,member)\
6043 (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member)))
6049#ifdef NK_IMPLEMENTATION
6051#ifndef NK_INTERNAL_H
6052#define NK_INTERNAL_H
6054#ifndef NK_POOL_DEFAULT_CAPACITY
6055#define NK_POOL_DEFAULT_CAPACITY 16
6058#ifndef NK_DEFAULT_COMMAND_BUFFER_SIZE
6059#define NK_DEFAULT_COMMAND_BUFFER_SIZE (4*1024)
6062#ifndef NK_BUFFER_DEFAULT_INITIAL_SIZE
6063#define NK_BUFFER_DEFAULT_INITIAL_SIZE (4*1024)
6067#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
6070#ifdef NK_INCLUDE_STANDARD_IO
6073#ifdef NK_INCLUDE_STANDARD_VARARGS
6078#define NK_ASSERT(expr) assert(expr)
6081#define NK_DEFAULT (-1)
6088 #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) ||\
6089 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
6090 (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) ||\
6091 (defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)) ||\
6092 defined(_ISOC99_SOURCE) || defined(_BSD_SOURCE)
6093 #define NK_VSNPRINTF(s,n,f,a) vsnprintf(s,n,f,a)
6095 #define NK_VSNPRINTF(s,n,f,a) vsprintf(s,f,a)
6099#define NK_SCHAR_MIN (-127)
6100#define NK_SCHAR_MAX 127
6101#define NK_UCHAR_MIN 0
6102#define NK_UCHAR_MAX 256
6103#define NK_SSHORT_MIN (-32767)
6104#define NK_SSHORT_MAX 32767
6105#define NK_USHORT_MIN 0
6106#define NK_USHORT_MAX 65535
6107#define NK_SINT_MIN (-2147483647)
6108#define NK_SINT_MAX 2147483647
6109#define NK_UINT_MIN 0
6110#define NK_UINT_MAX 4294967295u
6115NK_STATIC_ASSERT(
sizeof(nk_size) >=
sizeof(
void*));
6116NK_STATIC_ASSERT(
sizeof(nk_ptr) ==
sizeof(
void*));
6117NK_STATIC_ASSERT(
sizeof(nk_flags) >= 4);
6118NK_STATIC_ASSERT(
sizeof(nk_rune) >= 4);
6119NK_STATIC_ASSERT(
sizeof(nk_ushort) == 2);
6120NK_STATIC_ASSERT(
sizeof(nk_short) == 2);
6121NK_STATIC_ASSERT(
sizeof(nk_uint) == 4);
6122NK_STATIC_ASSERT(
sizeof(nk_int) == 4);
6123NK_STATIC_ASSERT(
sizeof(nk_byte) == 1);
6124#ifdef NK_INCLUDE_STANDARD_BOOL
6125NK_STATIC_ASSERT(
sizeof(nk_bool) ==
sizeof(
bool));
6127NK_STATIC_ASSERT(
sizeof(nk_bool) == 4);
6130NK_GLOBAL
const struct nk_rect nk_null_rect = {-8192.0f, -8192.0f, 16384, 16384};
6131#define NK_FLOAT_PRECISION 0.00000000000001
6133NK_GLOBAL
const struct nk_color nk_red = {255,0,0,255};
6134NK_GLOBAL
const struct nk_color nk_green = {0,255,0,255};
6135NK_GLOBAL
const struct nk_color nk_blue = {0,0,255,255};
6136NK_GLOBAL
const struct nk_color nk_white = {255,255,255,255};
6137NK_GLOBAL
const struct nk_color nk_black = {0,0,0,255};
6138NK_GLOBAL
const struct nk_color nk_yellow = {255,255,0,255};
6141#define nk_widget_state_reset(s)\
6142 if ((*(s)) & NK_WIDGET_STATE_MODIFIED)\
6143 (*(s)) = NK_WIDGET_STATE_INACTIVE|NK_WIDGET_STATE_MODIFIED;\
6144 else (*(s)) = NK_WIDGET_STATE_INACTIVE;
6148NK_LIB
float nk_inv_sqrt(
float n);
6151NK_LIB
float nk_sin(
float x);
6154NK_LIB
float nk_cos(
float x);
6157NK_LIB
float nk_atan(
float x);
6160NK_LIB
float nk_atan2(
float y,
float x);
6162NK_LIB nk_uint nk_round_up_pow2(nk_uint v);
6163NK_LIB
struct nk_rect nk_shrink_rect(struct
nk_rect r, float amount);
6165NK_LIB
void nk_unify(
struct nk_rect *clip,
const struct nk_rect *a,
float x0,
float y0,
float x1,
float y1);
6166NK_LIB
double nk_pow(
double x,
int n);
6167NK_LIB
int nk_ifloord(
double x);
6168NK_LIB
int nk_ifloorf(
float x);
6169NK_LIB
int nk_iceilf(
float x);
6170NK_LIB
int nk_log10(
double n);
6171NK_LIB
float nk_roundf(
float x);
6174enum {NK_DO_NOT_STOP_ON_NEW_LINE, NK_STOP_ON_NEW_LINE};
6175NK_LIB nk_bool nk_is_lower(
int c);
6176NK_LIB nk_bool nk_is_upper(
int c);
6177NK_LIB
int nk_to_upper(
int c);
6178NK_LIB
int nk_to_lower(
int c);
6181NK_LIB
void* nk_memcopy(
void *dst,
const void *src, nk_size n);
6184NK_LIB
void nk_memset(
void *ptr,
int c0, nk_size size);
6186NK_LIB
void nk_zero(
void *ptr, nk_size size);
6187NK_LIB
char *nk_itoa(
char *s,
long n);
6188NK_LIB
int nk_string_float_limit(
char *
string,
int prec);
6190NK_LIB
char *nk_dtoa(
char *s,
double n);
6192NK_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);
6193NK_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);
6194#ifdef NK_INCLUDE_STANDARD_VARARGS
6195NK_LIB
int nk_strfmt(
char *buf,
int buf_size,
const char *fmt, va_list args);
6197#ifdef NK_INCLUDE_STANDARD_IO
6198NK_LIB
char *nk_file_load(
const char* path, nk_size* siz,
const struct nk_allocator *alloc);
6202#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
6203NK_LIB
void* nk_malloc(
nk_handle unused,
void *old,nk_size size);
6204NK_LIB
void nk_mfree(
nk_handle unused,
void *ptr);
6206NK_LIB
void* nk_buffer_align(
void *unaligned, nk_size align, nk_size *alignment,
enum nk_buffer_allocation_type type);
6207NK_LIB
void* nk_buffer_alloc(
struct nk_buffer *b,
enum nk_buffer_allocation_type type, nk_size size, nk_size align);
6208NK_LIB
void* nk_buffer_realloc(
struct nk_buffer *b, nk_size capacity, nk_size *size);
6213NK_LIB
void* nk_command_buffer_push(
struct nk_command_buffer* b,
enum nk_command_type t, nk_size size);
6226NK_LIB
void nk_textedit_clear_state(
struct nk_text_edit *state,
enum nk_text_edit_type type, nk_plugin_filter filter);
6227NK_LIB
void nk_textedit_click(
struct nk_text_edit *state,
float x,
float y,
const struct nk_user_font *font,
float row_height);
6228NK_LIB
void nk_textedit_drag(
struct nk_text_edit *state,
float x,
float y,
const struct nk_user_font *font,
float row_height);
6229NK_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);
6232enum nk_window_insert_location {
6236NK_LIB
void *nk_create_window(
struct nk_context *ctx);
6239NK_LIB
struct nk_window *nk_find_window(
const struct nk_context *ctx, nk_hash hash,
const char *name);
6240NK_LIB
void nk_insert_window(
struct nk_context *ctx,
struct nk_window *win,
enum nk_window_insert_location loc);
6243NK_LIB
void nk_pool_init(
struct nk_pool *pool,
const struct nk_allocator *alloc,
unsigned int capacity);
6244NK_LIB
void nk_pool_free(
struct nk_pool *pool);
6245NK_LIB
void nk_pool_init_fixed(
struct nk_pool *pool,
void *memory, nk_size size);
6258NK_LIB nk_uint *nk_add_value(
struct nk_context *ctx,
struct nk_window *win, nk_hash name, nk_uint value);
6259NK_LIB nk_uint *nk_find_value(
const struct nk_window *win, nk_hash name);
6262NK_LIB
void *nk_create_panel(
struct nk_context *ctx);
6264NK_LIB nk_bool nk_panel_has_header(nk_flags flags,
const char *title);
6265NK_LIB
struct nk_vec2 nk_panel_get_padding(const struct
nk_style *style,
enum nk_panel_type type);
6266NK_LIB
float nk_panel_get_border(
const struct nk_style *style, nk_flags flags,
enum nk_panel_type type);
6267NK_LIB
struct nk_color nk_panel_get_border_color(const struct
nk_style *style,
enum nk_panel_type type);
6268NK_LIB nk_bool nk_panel_is_sub(
enum nk_panel_type type);
6269NK_LIB nk_bool nk_panel_is_nonblock(
enum nk_panel_type type);
6270NK_LIB nk_bool nk_panel_begin(
struct nk_context *ctx,
const char *title,
enum nk_panel_type panel_type);
6271NK_LIB
void nk_panel_end(
struct nk_context *ctx);
6274NK_LIB
float nk_layout_row_calculate_usable_space(
const struct nk_style *style,
enum nk_panel_type type,
float total_space,
int columns);
6275NK_LIB
void nk_panel_layout(
const struct nk_context *ctx,
struct nk_window *win,
float height,
int cols);
6276NK_LIB
void nk_row_layout(
struct nk_context *ctx,
enum nk_layout_format fmt,
float height,
int cols,
int width);
6279NK_LIB
void nk_panel_alloc_space(
struct nk_rect *bounds,
const struct nk_context *ctx);
6280NK_LIB
void nk_layout_peek(
struct nk_rect *bounds,
const struct nk_context *ctx);
6283NK_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);
6295NK_LIB nk_bool nk_button_behavior(nk_flags *state,
struct nk_rect r,
const struct nk_input *i,
enum nk_button_behavior behavior);
6305NK_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);
6307NK_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);
6310enum nk_toggle_type {
6314NK_LIB nk_bool nk_toggle_behavior(
const struct nk_input *in,
struct nk_rect select, nk_flags *state, nk_bool active);
6315NK_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);
6316NK_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);
6317NK_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);
6320NK_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);
6325NK_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);
6330NK_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);
6332NK_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);
6333NK_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);
6336NK_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);
6338NK_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);
6341NK_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);
6345NK_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);
6350enum nk_property_status {
6351 NK_PROPERTY_DEFAULT,
6355enum nk_property_filter {
6359enum nk_property_kind {
6369struct nk_property_variant {
6370 enum nk_property_kind kind;
6371 union nk_property value;
6372 union nk_property min_value;
6373 union nk_property max_value;
6374 union nk_property step;
6376NK_LIB
struct nk_property_variant nk_property_variant_int(int value, int min_value, int max_value, int step);
6377NK_LIB
struct nk_property_variant nk_property_variant_float(float value, float min_value, float max_value, float step);
6378NK_LIB
struct nk_property_variant nk_property_variant_double(double value, double min_value, double max_value, double step);
6380NK_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);
6381NK_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);
6383NK_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);
6384NK_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);
6386#ifdef NK_INCLUDE_FONT_BAKING
6393#ifndef NK_NO_STB_RECT_PACK_IMPLEMENTATION
6394#define STB_RECT_PACK_IMPLEMENTATION
6402#ifndef NK_NO_STB_TRUETYPE_IMPLEMENTATION
6403#define STB_TRUETYPE_IMPLEMENTATION
6409nk_stbtt_malloc(nk_size size,
void *user_data) {
6411 return alloc->alloc(alloc->userdata, 0, size);
6415nk_stbtt_free(
void *ptr,
void *user_data) {
6417 alloc->free(alloc->userdata, ptr);
6420#define STBTT_malloc(x,u) nk_stbtt_malloc(x,u)
6421#define STBTT_free(x,u) nk_stbtt_free(x,u)
6466#define NK_INV_SQRT nk_inv_sqrt
6471 const float threehalfs = 1.5f;
6472 union {nk_uint i;
float f;} conv = {0};
6475 conv.i = 0x5f375A84 - (conv.i >> 1);
6476 conv.f = conv.f * (threehalfs - (x2 * conv.f * conv.f));
6481#define NK_SIN nk_sin
6485 NK_STORAGE
const float a0 = +1.91059300966915117e-31f;
6486 NK_STORAGE
const float a1 = +1.00086760103908896f;
6487 NK_STORAGE
const float a2 = -1.21276126894734565e-2f;
6488 NK_STORAGE
const float a3 = -1.38078780785773762e-1f;
6489 NK_STORAGE
const float a4 = -2.67353392911981221e-2f;
6490 NK_STORAGE
const float a5 = +2.08026600266304389e-2f;
6491 NK_STORAGE
const float a6 = -3.03996055049204407e-3f;
6492 NK_STORAGE
const float a7 = +1.38235642404333740e-4f;
6493 return a0 + x*(a1 + x*(a2 + x*(a3 + x*(a4 + x*(a5 + x*(a6 + x*a7))))));
6497#define NK_COS nk_cos
6503 NK_STORAGE
const float a0 = 9.9995999154986614e-1f;
6504 NK_STORAGE
const float a1 = 1.2548995793001028e-3f;
6505 NK_STORAGE
const float a2 = -5.0648546280678015e-1f;
6506 NK_STORAGE
const float a3 = 1.2942246466519995e-2f;
6507 NK_STORAGE
const float a4 = 2.8668384702547972e-2f;
6508 NK_STORAGE
const float a5 = 7.3726485210586547e-3f;
6509 NK_STORAGE
const float a6 = -3.8510875386947414e-3f;
6510 NK_STORAGE
const float a7 = 4.7196604604366623e-4f;
6511 NK_STORAGE
const float a8 = -1.8776444013090451e-5f;
6512 return a0 + x*(a1 + x*(a2 + x*(a3 + x*(a4 + x*(a5 + x*(a6 + x*(a7 + x*a8)))))));
6516#define NK_ATAN nk_atan
6521 float u = -1.0989005e-05f;
6522 NK_ASSERT(x >= 0.0f &&
"TODO support negative floats");
6523 u = u * x + 0.00034117949f;
6524 u = u * x + -0.0044932296f;
6525 u = u * x + 0.032596264f;
6526 u = u * x + -0.14088021f;
6527 u = u * x + 0.36040401f;
6528 u = u * x + -0.47017866f;
6529 u = u * x + 0.00050198776f;
6530 u = u * x + 1.0077682f;
6531 u = u * x + -0.0004765437f;
6536#define NK_ATAN2 nk_atan2
6538nk_atan2(
float y,
float x)
6540 float ax = NK_ABS(x),
6544 nk_uint signs = (y < 0) | ((x < 0) << 1);
6547 if(y == 0.0 && x == 0.0)
return 0.0f;
6549 ? NK_PI_HALF - NK_ATAN(ax / ay)
6555 case 2:
return -a + NK_PI;
6556 case 3:
return a - NK_PI;
6562nk_round_up_pow2(nk_uint v)
6574nk_pow(
double x,
int n)
6579 n = (plus) ? n : -n;
6586 return plus ? r : 1.0 / r;
6591 x = (double)((
int)x - ((x < 0.0) ? 1 : 0));
6597 x = (float)((
int)x - ((x < 0.0f) ? 1 : 0));
6605 return (x > i) ? i+1: i;
6608 float r = x - (float)t;
6609 return (r > 0.0f) ? t+1: t;
6619 neg = (n < 0) ? 1 : 0;
6620 ret = (neg) ? (
int)-n : (int)n;
6621 while ((ret / 10) > 0) {
6625 if (neg) exp = -exp;
6631 return (x >= 0.0f) ? (float)nk_ifloorf(x + 0.5f) : (float)nk_iceilf(x - 0.5f);
6634nk_get_null_rect(void)
6636 return nk_null_rect;
6639nk_rect(float x, float y, float w, float h)
6647nk_recti(int x, int y, int w, int h)
6659 return nk_rect(pos.x, pos.y, size.x, size.y);
6662nk_rectv(const float *r)
6664 return nk_rect(r[0], r[1], r[2], r[3]);
6667nk_rectiv(const int *r)
6669 return nk_recti(r[0], r[1], r[2], r[3]);
6675 ret.x = r.x; ret.y = r.y;
6682 ret.x = r.w; ret.y = r.h;
6686nk_shrink_rect(struct
nk_rect r, float amount)
6689 r.w = NK_MAX(r.w, 2 * amount);
6690 r.h = NK_MAX(r.h, 2 * amount);
6691 res.x = r.x + amount;
6692 res.y = r.y + amount;
6693 res.w = r.w - 2 * amount;
6694 res.h = r.h - 2 * amount;
6700 r.w = NK_MAX(r.w, 2 * pad.x);
6701 r.h = NK_MAX(r.h, 2 * pad.y);
6702 r.x += pad.x; r.y += pad.y;
6711 ret.x = x; ret.y = y;
6723nk_vec2v(const float *v)
6728nk_vec2iv(const int *v)
6733nk_unify(
struct nk_rect *clip,
const struct nk_rect *a,
float x0,
float y0,
6738 clip->x = NK_MAX(a->x, x0);
6739 clip->y = NK_MAX(a->y, y0);
6740 clip->w = NK_MIN(a->x + a->w, x1) - clip->x;
6741 clip->h = NK_MIN(a->y + a->h, y1) - clip->y;
6742 clip->w = NK_MAX(0, clip->w);
6743 clip->h = NK_MAX(0, clip->h);
6747nk_triangle_from_direction(
struct nk_vec2 *result,
struct nk_rect r,
6748 float pad_x,
float pad_y,
enum nk_heading direction)
6750 float w_half, h_half;
6753 r.w = NK_MAX(2 * pad_x, r.w);
6754 r.h = NK_MAX(2 * pad_y, r.h);
6755 r.w = r.w - 2 * pad_x;
6756 r.h = r.h - 2 * pad_y;
6761 w_half = r.w / 2.0f;
6762 h_half = r.h / 2.0f;
6764 if (direction == NK_UP) {
6765 result[0] =
nk_vec2(r.x + w_half, r.y);
6766 result[1] =
nk_vec2(r.x + r.w, r.y + r.h);
6767 result[2] =
nk_vec2(r.x, r.y + r.h);
6768 }
else if (direction == NK_RIGHT) {
6769 result[0] =
nk_vec2(r.x, r.y);
6770 result[1] =
nk_vec2(r.x + r.w, r.y + h_half);
6771 result[2] =
nk_vec2(r.x, r.y + r.h);
6772 }
else if (direction == NK_DOWN) {
6773 result[0] =
nk_vec2(r.x, r.y);
6774 result[1] =
nk_vec2(r.x + r.w, r.y);
6775 result[2] =
nk_vec2(r.x + w_half, r.y + r.h);
6777 result[0] =
nk_vec2(r.x, r.y + h_half);
6778 result[1] =
nk_vec2(r.x + r.w, r.y);
6779 result[2] =
nk_vec2(r.x + r.w, r.y + r.h);
6792NK_INTERN
int nk_str_match_here(
const char *regexp,
const char *text);
6793NK_INTERN
int nk_str_match_star(
int c,
const char *regexp,
const char *text);
6794NK_LIB nk_bool nk_is_lower(
int c) {
return (c >=
'a' && c <=
'z') || (c >= 0xE0 && c <= 0xFF);}
6795NK_LIB nk_bool nk_is_upper(
int c){
return (c >=
'A' && c <=
'Z') || (c >= 0xC0 && c <= 0xDF);}
6796NK_LIB
int nk_to_upper(
int c) {
return (c >=
'a' && c <=
'z') ? (c - (
'a' -
'A')) : c;}
6797NK_LIB
int nk_to_lower(
int c) {
return (c >=
'A' && c <=
'Z') ? (c - (
'a' +
'A')) : c;}
6800#define NK_MEMCPY nk_memcopy
6802nk_memcopy(
void *dst0,
const void *src0, nk_size length)
6805 char *dst = (
char*)dst0;
6806 const char *src = (
const char*)src0;
6807 if (length == 0 || dst == src)
6811 #define nk_wsize sizeof(nk_word)
6812 #define nk_wmask (nk_wsize-1)
6813 #define NK_TLOOP(s) if (t) NK_TLOOP1(s)
6814 #define NK_TLOOP1(s) do { s; } while (--t)
6818 if ((t | (nk_ptr)dst) & nk_wmask) {
6819 if ((t ^ (nk_ptr)dst) & nk_wmask || length < nk_wsize)
6822 t = nk_wsize - (t & nk_wmask);
6824 NK_TLOOP1(*dst++ = *src++);
6826 t = length / nk_wsize;
6827 NK_TLOOP(*(nk_word*)(
void*)dst = *(
const nk_word*)(
const void*)src;
6828 src += nk_wsize; dst += nk_wsize);
6829 t = length & nk_wmask;
6830 NK_TLOOP(*dst++ = *src++);
6835 if ((t | (nk_ptr)dst) & nk_wmask) {
6836 if ((t ^ (nk_ptr)dst) & nk_wmask || length <= nk_wsize)
6841 NK_TLOOP1(*--dst = *--src);
6843 t = length / nk_wsize;
6844 NK_TLOOP(src -= nk_wsize; dst -= nk_wsize;
6845 *(nk_word*)(
void*)dst = *(
const nk_word*)(
const void*)src);
6846 t = length & nk_wmask;
6847 NK_TLOOP(*--dst = *--src);
6859#define NK_MEMSET nk_memset
6861nk_memset(
void *ptr,
int c0, nk_size size)
6863 #define nk_word unsigned
6864 #define nk_wsize sizeof(nk_word)
6865 #define nk_wmask (nk_wsize - 1)
6866 nk_byte *dst = (nk_byte*)ptr;
6870 if ((c = (nk_byte)c0) != 0) {
6872 if (
sizeof(
unsigned int) > 2)
6877 dst = (nk_byte*)ptr;
6878 if (size < 3 * nk_wsize) {
6879 while (size--) *dst++ = (nk_byte)c0;
6884 if ((t = NK_PTR_TO_UINT(dst) & nk_wmask) != 0) {
6888 *dst++ = (nk_byte)c0;
6893 t = size / nk_wsize;
6895 *(nk_word*)((
void*)dst) = c;
6900 t = (size & nk_wmask);
6903 *dst++ = (nk_byte)c0;
6913nk_zero(
void *ptr, nk_size size)
6916 NK_MEMSET(ptr, 0, size);
6919nk_strlen(
const char *str)
6923 while (str && *str++ !=
'\0') siz++;
6927nk_strtoi(
const char *str,
char **endptr)
6930 const char *p = str;
6937 while (*p ==
' ') p++;
6942 while (*p && *p >=
'0' && *p <=
'9') {
6943 value = value * 10 + (int) (*p -
'0');
6947 *endptr = (
char *)p;
6951nk_strtod(
const char *str,
char **endptr)
6955 char *p = (
char *)str;
6963 while (*p ==
' ') p++;
6969 while (*p && *p !=
'.' && *p !=
'e') {
6970 value = value * 10.0 + (double) (*p -
'0');
6976 for(m = 0.1; *p && *p !=
'e'; p++ ) {
6977 value = value + (double) (*p -
'0') * m;
6987 }
else if (*p ==
'+') {
6990 }
else div = nk_false;
6992 for (pow = 0; *p; p++)
6993 pow = pow * 10 + (
int) (*p -
'0');
6995 for (m = 1.0, i = 0; i < pow; i++)
7002 number = value * neg;
7008nk_strtof(
const char *str,
char **endptr)
7011 double double_value;
7012 double_value = NK_STRTOD(str, endptr);
7013 float_value = (float)double_value;
7017nk_stricmp(
const char *s1,
const char *s2)
7025 if (c1 <=
'Z' && c1 >=
'A') {
7029 if (c2 <=
'Z' && c2 >=
'A') {
7033 return ((d >= 0) << 1) - 1;
7039nk_stricmpn(
const char *s1,
const char *s2,
int n)
7050 if (c1 <=
'Z' && c1 >=
'A') {
7054 if (c2 <=
'Z' && c2 >=
'A') {
7058 return ((d >= 0) << 1) - 1;
7064nk_str_match_here(
const char *regexp,
const char *text)
7066 if (regexp[0] ==
'\0')
7068 if (regexp[1] ==
'*')
7069 return nk_str_match_star(regexp[0], regexp+2, text);
7070 if (regexp[0] ==
'$' && regexp[1] ==
'\0')
7071 return *text ==
'\0';
7072 if (*text!=
'\0' && (regexp[0]==
'.' || regexp[0]==*text))
7073 return nk_str_match_here(regexp+1, text+1);
7077nk_str_match_star(
int c,
const char *regexp,
const char *text)
7080 if (nk_str_match_here(regexp, text))
7082 }
while (*text !=
'\0' && (*text++ == c || c ==
'.'));
7086nk_strfilter(
const char *text,
const char *regexp)
7094 if (regexp[0] ==
'^')
7095 return nk_str_match_here(regexp+1, text);
7097 if (nk_str_match_here(regexp, text))
7099 }
while (*text++ !=
'\0');
7103nk_strmatch_fuzzy_text(
const char *str,
int str_len,
7104 const char *pattern,
int *out_score)
7111 #define NK_ADJACENCY_BONUS 5
7113 #define NK_SEPARATOR_BONUS 10
7115 #define NK_CAMEL_BONUS 10
7117 #define NK_LEADING_LETTER_PENALTY (-3)
7119 #define NK_MAX_LEADING_LETTER_PENALTY (-9)
7121 #define NK_UNMATCHED_LETTER_PENALTY (-1)
7125 char const * pattern_iter = pattern;
7127 int prev_matched = nk_false;
7128 int prev_lower = nk_false;
7130 int prev_separator = nk_true;
7133 char const * best_letter = 0;
7134 int best_letter_score = 0;
7139 if (!str || !str_len || !pattern)
return 0;
7140 while (str_iter < str_len)
7142 const char pattern_letter = *pattern_iter;
7143 const char str_letter = str[str_iter];
7145 int next_match = *pattern_iter !=
'\0' &&
7146 nk_to_lower(pattern_letter) == nk_to_lower(str_letter);
7147 int rematch = best_letter && nk_to_upper(*best_letter) == nk_to_upper(str_letter);
7149 int advanced = next_match && best_letter;
7150 int pattern_repeat = best_letter && *pattern_iter !=
'\0';
7151 pattern_repeat = pattern_repeat &&
7152 nk_to_lower(*best_letter) == nk_to_lower(pattern_letter);
7154 if (advanced || pattern_repeat) {
7155 score += best_letter_score;
7157 best_letter_score = 0;
7160 if (next_match || rematch)
7164 if (pattern_iter == pattern) {
7165 int count = (int)(&str[str_iter] - str);
7166 int penalty = NK_LEADING_LETTER_PENALTY * count;
7167 if (penalty < NK_MAX_LEADING_LETTER_PENALTY)
7168 penalty = NK_MAX_LEADING_LETTER_PENALTY;
7175 new_score += NK_ADJACENCY_BONUS;
7179 new_score += NK_SEPARATOR_BONUS;
7182 if (prev_lower && nk_is_upper(str_letter))
7183 new_score += NK_CAMEL_BONUS;
7190 if (new_score >= best_letter_score) {
7192 if (best_letter != 0)
7193 score += NK_UNMATCHED_LETTER_PENALTY;
7195 best_letter = &str[str_iter];
7196 best_letter_score = new_score;
7198 prev_matched = nk_true;
7200 score += NK_UNMATCHED_LETTER_PENALTY;
7201 prev_matched = nk_false;
7205 prev_lower = nk_is_lower(str_letter) != 0;
7206 prev_separator = str_letter ==
'_' || str_letter ==
' ';
7213 score += best_letter_score;
7216 if (*pattern_iter !=
'\0')
7224nk_strmatch_fuzzy_string(
char const *str,
char const *pattern,
int *out_score)
7226 return nk_strmatch_fuzzy_text(str, nk_strlen(str), pattern, out_score);
7229nk_string_float_limit(
char *
string,
int prec)
7239 if (dot == (prec+1)) {
7246 return (
int)(c - string);
7249nk_strrev_ascii(
char *s)
7251 int len = nk_strlen(s);
7255 for (; i < end; ++i) {
7257 s[i] = s[len - 1 - i];
7262nk_itoa(
char *s,
long n)
7275 s[i++] = (char)(
'0' + (n % 10));
7286#define NK_DTOA nk_dtoa
7288nk_dtoa(
char *s,
double n)
7291 int digit = 0, m = 0, m1 = 0;
7299 s[0] =
'0'; s[1] =
'\0';
7308 useExp = (m >= 14 || (neg && m >= 9) || m <= -9);
7309 if (neg) *(c++) =
'-';
7315 n = n / (double)nk_pow(10.0, m);
7324 while (n > NK_FLOAT_PRECISION || m >= 0) {
7325 double weight = nk_pow(10.0, m);
7327 double t = (double)n / weight;
7328 digit = nk_ifloord(t);
7329 n -= ((double)digit * weight);
7330 *(c++) = (
char)(
'0' + (char)digit);
7332 if (m == 0 && n > 0)
7349 *(c++) = (
char)(
'0' + (char)(m1 % 10));
7354 for (i = 0, j = m-1; i<j; i++, j--) {
7366#ifdef NK_INCLUDE_STANDARD_VARARGS
7367#ifndef NK_INCLUDE_STANDARD_IO
7369nk_vsnprintf(
char *buf,
int buf_size,
const char *fmt, va_list args)
7374 NK_ARG_TYPE_DEFAULT,
7378 NK_ARG_FLAG_LEFT = 0x01,
7379 NK_ARG_FLAG_PLUS = 0x02,
7380 NK_ARG_FLAG_SPACE = 0x04,
7381 NK_ARG_FLAG_NUM = 0x10,
7382 NK_ARG_FLAG_ZERO = 0x20
7385 char number_buffer[NK_MAX_NUMBER_BUFFER];
7386 enum nk_arg_type arg_type = NK_ARG_TYPE_DEFAULT;
7387 int precision = NK_DEFAULT;
7388 int width = NK_DEFAULT;
7393 const char *iter = fmt;
7396 NK_ASSERT(buf_size);
7397 if (!buf || !buf_size || !fmt)
return 0;
7398 for (iter = fmt; *iter && len < buf_size; iter++) {
7400 while (*iter && (*iter !=
'%') && (len < buf_size))
7401 buf[len++] = *iter++;
7402 if (!(*iter) || len >= buf_size)
break;
7407 if (*iter ==
'-') flag |= NK_ARG_FLAG_LEFT;
7408 else if (*iter ==
'+') flag |= NK_ARG_FLAG_PLUS;
7409 else if (*iter ==
' ') flag |= NK_ARG_FLAG_SPACE;
7410 else if (*iter ==
'#') flag |= NK_ARG_FLAG_NUM;
7411 else if (*iter ==
'0') flag |= NK_ARG_FLAG_ZERO;
7418 if (*iter >=
'1' && *iter <=
'9') {
7420 width = nk_strtoi(iter, &end);
7424 }
else if (*iter ==
'*') {
7425 width = va_arg(args,
int);
7430 precision = NK_DEFAULT;
7434 precision = va_arg(args,
int);
7438 precision = nk_strtoi(iter, &end);
7447 if (*(iter+1) ==
'h') {
7448 arg_type = NK_ARG_TYPE_CHAR;
7450 }
else arg_type = NK_ARG_TYPE_SHORT;
7452 }
else if (*iter ==
'l') {
7453 arg_type = NK_ARG_TYPE_LONG;
7455 }
else arg_type = NK_ARG_TYPE_DEFAULT;
7459 NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
7460 NK_ASSERT(precision == NK_DEFAULT);
7461 NK_ASSERT(width == NK_DEFAULT);
7464 }
else if (*iter ==
's') {
7466 const char *str = va_arg(args,
const char*);
7467 NK_ASSERT(str != buf &&
"buffer and argument are not allowed to overlap!");
7468 NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
7469 NK_ASSERT(precision == NK_DEFAULT);
7470 NK_ASSERT(width == NK_DEFAULT);
7471 if (str == buf)
return -1;
7472 while (str && *str && len < buf_size)
7473 buf[len++] = *str++;
7474 }
else if (*iter ==
'n') {
7476 signed int *n = va_arg(args,
int*);
7477 NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
7478 NK_ASSERT(precision == NK_DEFAULT);
7479 NK_ASSERT(width == NK_DEFAULT);
7481 }
else if (*iter ==
'c' || *iter ==
'i' || *iter ==
'd') {
7484 const char *num_iter;
7485 int num_len, num_print, padding;
7486 int cur_precision = NK_MAX(precision, 1);
7487 int cur_width = NK_MAX(width, 0);
7490 if (arg_type == NK_ARG_TYPE_CHAR)
7491 value = (
signed char)va_arg(args,
int);
7492 else if (arg_type == NK_ARG_TYPE_SHORT)
7493 value = (
signed short)va_arg(args,
int);
7494 else if (arg_type == NK_ARG_TYPE_LONG)
7495 value = va_arg(args,
signed long);
7496 else if (*iter ==
'c')
7497 value = (
unsigned char)va_arg(args,
int);
7498 else value = va_arg(args,
signed int);
7501 nk_itoa(number_buffer, value);
7502 num_len = nk_strlen(number_buffer);
7503 padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0);
7504 if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE))
7505 padding = NK_MAX(padding-1, 0);
7508 if (!(flag & NK_ARG_FLAG_LEFT)) {
7509 while (padding-- > 0 && (len < buf_size)) {
7510 if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT))
7512 else buf[len++] =
' ';
7517 if ((flag & NK_ARG_FLAG_PLUS) && value >= 0 && len < buf_size)
7519 else if ((flag & NK_ARG_FLAG_SPACE) && value >= 0 && len < buf_size)
7523 num_print = NK_MAX(cur_precision, num_len);
7524 while (precision && (num_print > num_len) && (len < buf_size)) {
7530 num_iter = number_buffer;
7531 while (precision && *num_iter && len < buf_size)
7532 buf[len++] = *num_iter++;
7535 if (flag & NK_ARG_FLAG_LEFT) {
7536 while ((padding-- > 0) && (len < buf_size))
7539 }
else if (*iter ==
'o' || *iter ==
'x' || *iter ==
'X' || *iter ==
'u') {
7541 unsigned long value = 0;
7542 int num_len = 0, num_print, padding = 0;
7543 int cur_precision = NK_MAX(precision, 1);
7544 int cur_width = NK_MAX(width, 0);
7545 unsigned int base = (*iter ==
'o') ? 8: (*iter ==
'u')? 10: 16;
7548 const char *upper_output_format =
"0123456789ABCDEF";
7549 const char *lower_output_format =
"0123456789abcdef";
7550 const char *output_format = (*iter ==
'x') ?
7551 lower_output_format: upper_output_format;
7554 if (arg_type == NK_ARG_TYPE_CHAR)
7555 value = (
unsigned char)va_arg(args,
int);
7556 else if (arg_type == NK_ARG_TYPE_SHORT)
7557 value = (
unsigned short)va_arg(args,
int);
7558 else if (arg_type == NK_ARG_TYPE_LONG)
7559 value = va_arg(args,
unsigned long);
7560 else value = va_arg(args,
unsigned int);
7564 int digit = output_format[value % base];
7565 if (num_len < NK_MAX_NUMBER_BUFFER)
7566 number_buffer[num_len++] = (char)digit;
7568 }
while (value > 0);
7570 num_print = NK_MAX(cur_precision, num_len);
7571 padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0);
7572 if (flag & NK_ARG_FLAG_NUM)
7573 padding = NK_MAX(padding-1, 0);
7576 if (!(flag & NK_ARG_FLAG_LEFT)) {
7577 while ((padding-- > 0) && (len < buf_size)) {
7578 if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT))
7580 else buf[len++] =
' ';
7585 if (num_print && (flag & NK_ARG_FLAG_NUM)) {
7586 if ((*iter ==
'o') && (len < buf_size)) {
7588 }
else if ((*iter ==
'x') && ((len+1) < buf_size)) {
7591 }
else if ((*iter ==
'X') && ((len+1) < buf_size)) {
7596 while (precision && (num_print > num_len) && (len < buf_size)) {
7602 while (num_len > 0) {
7603 if (precision && (len < buf_size))
7604 buf[len++] = number_buffer[num_len-1];
7609 if (flag & NK_ARG_FLAG_LEFT) {
7610 while ((padding-- > 0) && (len < buf_size))
7613 }
else if (*iter ==
'f') {
7615 const char *num_iter;
7616 int cur_precision = (precision < 0) ? 6: precision;
7617 int prefix, cur_width = NK_MAX(width, 0);
7618 double value = va_arg(args,
double);
7619 int num_len = 0, frac_len = 0, dot = 0;
7622 NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
7623 NK_DTOA(number_buffer, value);
7624 num_len = nk_strlen(number_buffer);
7627 num_iter = number_buffer;
7628 while (*num_iter && *num_iter !=
'.')
7631 prefix = (*num_iter ==
'.')?(
int)(num_iter - number_buffer)+1:0;
7632 padding = NK_MAX(cur_width - (prefix + NK_MIN(cur_precision, num_len - prefix)) , 0);
7633 if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE))
7634 padding = NK_MAX(padding-1, 0);
7637 if (!(flag & NK_ARG_FLAG_LEFT)) {
7638 while (padding-- > 0 && (len < buf_size)) {
7639 if (flag & NK_ARG_FLAG_ZERO)
7641 else buf[len++] =
' ';
7646 num_iter = number_buffer;
7647 if ((flag & NK_ARG_FLAG_PLUS) && (value >= 0) && (len < buf_size))
7649 else if ((flag & NK_ARG_FLAG_SPACE) && (value >= 0) && (len < buf_size))
7652 if (dot) frac_len++;
7654 buf[len++] = *num_iter;
7655 if (*num_iter ==
'.') dot = 1;
7656 if (frac_len >= cur_precision)
break;
7661 while (frac_len < cur_precision) {
7662 if (!dot && len < buf_size) {
7672 if (flag & NK_ARG_FLAG_LEFT) {
7673 while ((padding-- > 0) && (len < buf_size))
7678 NK_ASSERT(0 &&
"specifier is not supported!");
7682 buf[(len >= buf_size)?(buf_size-1):len] = 0;
7683 result = (len >= buf_size)?-1:len;
7688nk_strfmt(
char *buf,
int buf_size,
const char *fmt, va_list args)
7692 NK_ASSERT(buf_size);
7693 if (!buf || !buf_size || !fmt)
return 0;
7694#ifdef NK_INCLUDE_STANDARD_IO
7695 result = NK_VSNPRINTF(buf, (nk_size)buf_size, fmt, args);
7696 result = (result >= buf_size) ? -1: result;
7697 buf[buf_size-1] = 0;
7699 result = nk_vsnprintf(buf, buf_size, fmt, args);
7705nk_murmur_hash(
const void * key,
int len, nk_hash seed)
7708 #define NK_ROTL(x,r) ((x) << (r) | ((x) >> (32 - r)))
7712 const nk_byte *data = (
const nk_byte*)key;
7713 const nk_byte *keyptr = data;
7715 const int bsize =
sizeof(k1);
7716 const int nblocks = len/4;
7718 const nk_uint c1 = 0xcc9e2d51;
7719 const nk_uint c2 = 0x1b873593;
7720 const nk_byte *tail;
7725 for (i = 0; i < nblocks; ++i, keyptr += bsize) {
7726 k1ptr = (nk_byte*)&k1;
7727 k1ptr[0] = keyptr[0];
7728 k1ptr[1] = keyptr[1];
7729 k1ptr[2] = keyptr[2];
7730 k1ptr[3] = keyptr[3];
7733 k1 = NK_ROTL(k1,15);
7737 h1 = NK_ROTL(h1,13);
7738 h1 = h1*5+0xe6546b64;
7742 tail = (
const nk_byte*)(data + nblocks*4);
7745 case 3: k1 ^= (nk_uint)(tail[2] << 16);
7746 case 2: k1 ^= (nk_uint)(tail[1] << 8u);
7747 case 1: k1 ^= tail[0];
7749 k1 = NK_ROTL(k1,15);
7768#ifdef NK_INCLUDE_STANDARD_IO
7770nk_file_load(
const char* path, nk_size* siz,
const struct nk_allocator *alloc)
7779 if (!path || !siz || !alloc)
7782 fd = fopen(path,
"rb");
7784 fseek(fd, 0, SEEK_END);
7790 *siz = (nk_size)ret;
7791 fseek(fd, 0, SEEK_SET);
7792 buf = (
char*)alloc->alloc(alloc->userdata,0, *siz);
7798 *siz = (nk_size)fread(buf, 1,*siz, fd);
7804nk_text_clamp(
const struct nk_user_font *font,
const char *text,
7805 int text_len,
float space,
int *glyphs,
float *text_width,
7806 nk_rune *sep_list,
int sep_count)
7810 float last_width = 0;
7811 nk_rune unicode = 0;
7819 float sep_width = 0;
7820 sep_count = NK_MAX(sep_count,0);
7822 glyph_len = nk_utf_decode(text, &unicode, text_len);
7823 while (glyph_len && (width < space) && (len < text_len)) {
7825 s = font->
width(font->userdata, font->
height, text, len);
7826 for (i = 0; i < sep_count; ++i) {
7827 if (unicode != sep_list[i])
continue;
7828 sep_width = last_width = width;
7833 if (i == sep_count){
7834 last_width = sep_width = width;
7838 glyph_len = nk_utf_decode(&text[len], &unicode, text_len - len);
7841 if (len >= text_len) {
7843 *text_width = last_width;
7847 *text_width = sep_width;
7848 return (!sep_len) ? len: sep_len;
7852nk_text_calculate_text_bounds(const struct
nk_user_font *font,
7853 const char *begin,
int byte_len,
float row_height,
const char **remaining,
7854 struct nk_vec2 *out_offset,
int *glyphs,
int op)
7856 float line_height = row_height;
7858 float line_width = 0.0f;
7862 nk_rune unicode = 0;
7864 if (!begin || byte_len <= 0 || !font)
7867 glyph_len = nk_utf_decode(begin, &unicode, byte_len);
7868 if (!glyph_len)
return text_size;
7869 glyph_width = font->width(font->userdata, font->height, begin, glyph_len);
7872 while ((text_len < byte_len) && glyph_len) {
7873 if (unicode ==
'\n') {
7874 text_size.x = NK_MAX(text_size.x, line_width);
7875 text_size.y += line_height;
7878 if (op == NK_STOP_ON_NEW_LINE)
7882 glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
7886 if (unicode ==
'\r') {
7889 glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
7893 *glyphs = *glyphs + 1;
7894 text_len += glyph_len;
7895 line_width += (float)glyph_width;
7896 glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
7897 glyph_width = font->width(font->userdata, font->height, begin+text_len, glyph_len);
7901 if (text_size.x < line_width)
7902 text_size.x = line_width;
7904 *out_offset =
nk_vec2(line_width, text_size.y + line_height);
7905 if (line_width > 0 || text_size.y == 0.0f)
7906 text_size.y += line_height;
7908 *remaining = begin+text_len;
7922nk_parse_hex(
const char *p,
int length)
7926 while (len < length) {
7928 if (p[len] >=
'a' && p[len] <=
'f')
7929 i += ((p[len] -
'a') + 10);
7930 else if (p[len] >=
'A' && p[len] <=
'F')
7931 i += ((p[len] -
'A') + 10);
7932 else i += (p[len] -
'0');
7938nk_rgb_factor(struct
nk_color col, float factor)
7942 col.r = (nk_byte)(col.r * factor);
7943 col.g = (nk_byte)(col.g * factor);
7944 col.b = (nk_byte)(col.b * factor);
7948nk_rgba(int r, int g, int b, int a)
7951 ret.r = (nk_byte)NK_CLAMP(0, r, 255);
7952 ret.g = (nk_byte)NK_CLAMP(0, g, 255);
7953 ret.b = (nk_byte)NK_CLAMP(0, b, 255);
7954 ret.a = (nk_byte)NK_CLAMP(0, a, 255);
7958nk_rgb_hex(const char *rgb)
7961 const char *c = rgb;
7963 col.r = (nk_byte)nk_parse_hex(c, 2);
7964 col.g = (nk_byte)nk_parse_hex(c+2, 2);
7965 col.b = (nk_byte)nk_parse_hex(c+4, 2);
7970nk_rgba_hex(const char *rgb)
7973 const char *c = rgb;
7975 col.r = (nk_byte)nk_parse_hex(c, 2);
7976 col.g = (nk_byte)nk_parse_hex(c+2, 2);
7977 col.b = (nk_byte)nk_parse_hex(c+4, 2);
7978 col.a = (nk_byte)nk_parse_hex(c+6, 2);
7982nk_color_hex_rgba(
char *output,
struct nk_color col)
7984 #define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i): 'A' - 10 + (i))
7985 output[0] = (char)NK_TO_HEX((col.r & 0xF0) >> 4);
7986 output[1] = (char)NK_TO_HEX((col.r & 0x0F));
7987 output[2] = (char)NK_TO_HEX((col.g & 0xF0) >> 4);
7988 output[3] = (char)NK_TO_HEX((col.g & 0x0F));
7989 output[4] = (char)NK_TO_HEX((col.b & 0xF0) >> 4);
7990 output[5] = (char)NK_TO_HEX((col.b & 0x0F));
7991 output[6] = (char)NK_TO_HEX((col.a & 0xF0) >> 4);
7992 output[7] = (char)NK_TO_HEX((col.a & 0x0F));
7997nk_color_hex_rgb(
char *output,
struct nk_color col)
7999 #define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i): 'A' - 10 + (i))
8000 output[0] = (char)NK_TO_HEX((col.r & 0xF0) >> 4);
8001 output[1] = (char)NK_TO_HEX((col.r & 0x0F));
8002 output[2] = (char)NK_TO_HEX((col.g & 0xF0) >> 4);
8003 output[3] = (char)NK_TO_HEX((col.g & 0x0F));
8004 output[4] = (char)NK_TO_HEX((col.b & 0xF0) >> 4);
8005 output[5] = (char)NK_TO_HEX((col.b & 0x0F));
8010nk_rgba_iv(const int *c)
8012 return nk_rgba(c[0], c[1], c[2], c[3]);
8015nk_rgba_bv(const nk_byte *c)
8017 return nk_rgba(c[0], c[1], c[2], c[3]);
8020nk_rgb(int r, int g, int b)
8023 ret.r = (nk_byte)NK_CLAMP(0, r, 255);
8024 ret.g = (nk_byte)NK_CLAMP(0, g, 255);
8025 ret.b = (nk_byte)NK_CLAMP(0, b, 255);
8026 ret.a = (nk_byte)255;
8030nk_rgb_iv(const int *c)
8032 return nk_rgb(c[0], c[1], c[2]);
8035nk_rgb_bv(const nk_byte* c)
8037 return nk_rgb(c[0], c[1], c[2]);
8040nk_rgba_u32(nk_uint in)
8043 ret.r = (in & 0xFF);
8044 ret.g = ((in >> 8) & 0xFF);
8045 ret.b = ((in >> 16) & 0xFF);
8046 ret.a = (nk_byte)((in >> 24) & 0xFF);
8050nk_rgba_f(float r, float g, float b, float a)
8053 ret.r = (nk_byte)(NK_SATURATE(r) * 255.0f);
8054 ret.g = (nk_byte)(NK_SATURATE(g) * 255.0f);
8055 ret.b = (nk_byte)(NK_SATURATE(b) * 255.0f);
8056 ret.a = (nk_byte)(NK_SATURATE(a) * 255.0f);
8060nk_rgba_fv(const float *c)
8062 return nk_rgba_f(c[0], c[1], c[2], c[3]);
8067 return nk_rgba_f(c.r, c.g, c.b, c.a);
8070nk_rgb_f(float r, float g, float b)
8073 ret.r = (nk_byte)(NK_SATURATE(r) * 255.0f);
8074 ret.g = (nk_byte)(NK_SATURATE(g) * 255.0f);
8075 ret.b = (nk_byte)(NK_SATURATE(b) * 255.0f);
8080nk_rgb_fv(const float *c)
8082 return nk_rgb_f(c[0], c[1], c[2]);
8087 return nk_rgb_f(c.r, c.g, c.b);
8090nk_hsv(int h, int s, int v)
8092 return nk_hsva(h, s, v, 255);
8095nk_hsv_iv(const int *c)
8097 return nk_hsv(c[0], c[1], c[2]);
8100nk_hsv_bv(const nk_byte *c)
8102 return nk_hsv(c[0], c[1], c[2]);
8105nk_hsv_f(float h, float s, float v)
8107 return nk_hsva_f(h, s, v, 1.0f);
8110nk_hsv_fv(const float *c)
8112 return nk_hsv_f(c[0], c[1], c[2]);
8115nk_hsva(int h, int s, int v, int a)
8117 float hf = ((float)NK_CLAMP(0, h, 255)) / 255.0f;
8118 float sf = ((float)NK_CLAMP(0, s, 255)) / 255.0f;
8119 float vf = ((float)NK_CLAMP(0, v, 255)) / 255.0f;
8120 float af = ((float)NK_CLAMP(0, a, 255)) / 255.0f;
8121 return nk_hsva_f(hf, sf, vf, af);
8124nk_hsva_iv(const int *c)
8126 return nk_hsva(c[0], c[1], c[2], c[3]);
8129nk_hsva_bv(const nk_byte *c)
8131 return nk_hsva(c[0], c[1], c[2], c[3]);
8134nk_hsva_colorf(float h, float s, float v, float a)
8140 out.r = v; out.g = v; out.b = v; out.a = a;
8143 h = h / (60.0f/360.0f);
8147 q = v * (1.0f - (s * f));
8148 t = v * (1.0f - s * (1.0f - f));
8151 case 0:
default: out.r = v; out.g = t; out.b = p;
break;
8152 case 1: out.r = q; out.g = v; out.b = p;
break;
8153 case 2: out.r = p; out.g = v; out.b = t;
break;
8154 case 3: out.r = p; out.g = q; out.b = v;
break;
8155 case 4: out.r = t; out.g = p; out.b = v;
break;
8156 case 5: out.r = v; out.g = p; out.b = q;
break;}
8161nk_hsva_colorfv(const float *c)
8163 return nk_hsva_colorf(c[0], c[1], c[2], c[3]);
8166nk_hsva_f(float h, float s, float v, float a)
8168 struct nk_colorf c = nk_hsva_colorf(h, s, v, a);
8169 return nk_rgba_f(c.r, c.g, c.b, c.a);
8172nk_hsva_fv(const float *c)
8174 return nk_hsva_f(c[0], c[1], c[2], c[3]);
8179 nk_uint out = (nk_uint)in.r;
8180 out |= ((nk_uint)in.g << 8);
8181 out |= ((nk_uint)in.b << 16);
8182 out |= ((nk_uint)in.a << 24);
8186nk_color_f(
float *r,
float *g,
float *b,
float *a,
struct nk_color in)
8188 NK_STORAGE
const float s = 1.0f/255.0f;
8189 *r = (float)in.r * s;
8190 *g = (float)in.g * s;
8191 *b = (float)in.b * s;
8192 *a = (float)in.a * s;
8195nk_color_fv(
float *c,
struct nk_color in)
8197 nk_color_f(&c[0], &c[1], &c[2], &c[3], in);
8203 nk_color_f(&o.r, &o.g, &o.b, &o.a, in);
8207nk_color_d(
double *r,
double *g,
double *b,
double *a,
struct nk_color in)
8209 NK_STORAGE
const double s = 1.0/255.0;
8210 *r = (double)in.r * s;
8211 *g = (double)in.g * s;
8212 *b = (double)in.b * s;
8213 *a = (double)in.a * s;
8216nk_color_dv(
double *c,
struct nk_color in)
8218 nk_color_d(&c[0], &c[1], &c[2], &c[3], in);
8221nk_color_hsv_f(
float *out_h,
float *out_s,
float *out_v,
struct nk_color in)
8224 nk_color_hsva_f(out_h, out_s, out_v, &a, in);
8227nk_color_hsv_fv(
float *out,
struct nk_color in)
8230 nk_color_hsva_f(&out[0], &out[1], &out[2], &a, in);
8233nk_colorf_hsva_f(
float *out_h,
float *out_s,
8234 float *out_v,
float *out_a,
struct nk_colorf in)
8239 const float t = in.g; in.g = in.b; in.b = t;
8243 const float t = in.r; in.r = in.g; in.g = t;
8246 chroma = in.r - ((in.g < in.b) ? in.g: in.b);
8247 *out_h = NK_ABS(K + (in.g - in.b)/(6.0f * chroma + 1e-20f));
8248 *out_s = chroma / (in.r + 1e-20f);
8254nk_colorf_hsva_fv(
float *hsva,
struct nk_colorf in)
8256 nk_colorf_hsva_f(&hsva[0], &hsva[1], &hsva[2], &hsva[3], in);
8259nk_color_hsva_f(
float *out_h,
float *out_s,
8260 float *out_v,
float *out_a,
struct nk_color in)
8263 nk_color_f(&col.r,&col.g,&col.b,&col.a, in);
8264 nk_colorf_hsva_f(out_h, out_s, out_v, out_a, col);
8267nk_color_hsva_fv(
float *out,
struct nk_color in)
8269 nk_color_hsva_f(&out[0], &out[1], &out[2], &out[3], in);
8272nk_color_hsva_i(
int *out_h,
int *out_s,
int *out_v,
8276 nk_color_hsva_f(&h, &s, &v, &a, in);
8277 *out_h = (nk_byte)(h * 255.0f);
8278 *out_s = (nk_byte)(s * 255.0f);
8279 *out_v = (nk_byte)(v * 255.0f);
8280 *out_a = (nk_byte)(a * 255.0f);
8283nk_color_hsva_iv(
int *out,
struct nk_color in)
8285 nk_color_hsva_i(&out[0], &out[1], &out[2], &out[3], in);
8288nk_color_hsva_bv(nk_byte *out,
struct nk_color in)
8291 nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
8292 out[0] = (nk_byte)tmp[0];
8293 out[1] = (nk_byte)tmp[1];
8294 out[2] = (nk_byte)tmp[2];
8295 out[3] = (nk_byte)tmp[3];
8298nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a,
struct nk_color in)
8301 nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
8302 *h = (nk_byte)tmp[0];
8303 *s = (nk_byte)tmp[1];
8304 *v = (nk_byte)tmp[2];
8305 *a = (nk_byte)tmp[3];
8308nk_color_hsv_i(
int *out_h,
int *out_s,
int *out_v,
struct nk_color in)
8311 nk_color_hsva_i(out_h, out_s, out_v, &a, in);
8314nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v,
struct nk_color in)
8317 nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
8318 *out_h = (nk_byte)tmp[0];
8319 *out_s = (nk_byte)tmp[1];
8320 *out_v = (nk_byte)tmp[2];
8323nk_color_hsv_iv(
int *out,
struct nk_color in)
8325 nk_color_hsv_i(&out[0], &out[1], &out[2], in);
8328nk_color_hsv_bv(nk_byte *out,
struct nk_color in)
8331 nk_color_hsv_i(&tmp[0], &tmp[1], &tmp[2], in);
8332 out[0] = (nk_byte)tmp[0];
8333 out[1] = (nk_byte)tmp[1];
8334 out[2] = (nk_byte)tmp[2];
8345NK_GLOBAL
const nk_byte nk_utfbyte[
NK_UTF_SIZE+1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
8346NK_GLOBAL
const nk_byte nk_utfmask[
NK_UTF_SIZE+1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
8347NK_GLOBAL
const nk_uint nk_utfmin[
NK_UTF_SIZE+1] = {0, 0, 0x80, 0x800, 0x10000};
8348NK_GLOBAL
const nk_uint nk_utfmax[
NK_UTF_SIZE+1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
8351nk_utf_validate(nk_rune *u,
int i)
8355 if (!NK_BETWEEN(*u, nk_utfmin[i], nk_utfmax[i]) ||
8356 NK_BETWEEN(*u, 0xD800, 0xDFFF))
8358 for (i = 1; *u > nk_utfmax[i]; ++i);
8362nk_utf_decode_byte(
char c,
int *i)
8366 for(*i = 0; *i < (int)NK_LEN(nk_utfmask); ++(*i)) {
8367 if (((nk_byte)c & nk_utfmask[*i]) == nk_utfbyte[*i])
8368 return (nk_byte)(c & ~nk_utfmask[*i]);
8373nk_utf_decode(
const char *c, nk_rune *u,
int clen)
8375 int i, j, len, type=0;
8381 if (!c || !u)
return 0;
8382 if (!clen)
return 0;
8385 udecoded = nk_utf_decode_byte(c[0], &len);
8389 for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
8390 udecoded = (udecoded << 6) | nk_utf_decode_byte(c[i], &type);
8397 nk_utf_validate(u, len);
8401nk_utf_encode_byte(nk_rune u,
int i)
8403 return (
char)((nk_utfbyte[i]) | ((nk_byte)u & ~nk_utfmask[i]));
8406nk_utf_encode(nk_rune u,
char *c,
int clen)
8409 len = nk_utf_validate(&u, 0);
8413 for (i = len - 1; i != 0; --i) {
8414 c[i] = nk_utf_encode_byte(u, 0);
8417 c[0] = nk_utf_encode_byte(u, len);
8421nk_utf_len(
const char *str,
int len)
8431 if (!str || !len)
return 0;
8435 glyph_len = nk_utf_decode(text, &unicode, text_len);
8436 while (glyph_len && src_len < len) {
8438 src_len = src_len + glyph_len;
8439 glyph_len = nk_utf_decode(text + src_len, &unicode, text_len - src_len);
8444nk_utf_at(
const char *buffer,
int length,
int index,
8445 nk_rune *unicode,
int *len)
8457 if (!buffer || !unicode || !len)
return 0;
8466 glyph_len = nk_utf_decode(text, unicode, text_len);
8474 src_len = src_len + glyph_len;
8475 glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
8477 if (i != index)
return 0;
8478 return buffer + src_len;
8490#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
8492nk_malloc(
nk_handle unused,
void *old,nk_size size)
8496 return malloc(size);
8505nk_buffer_init_default(
struct nk_buffer *buffer)
8508 alloc.userdata.ptr = 0;
8509 alloc.alloc = nk_malloc;
8510 alloc.free = nk_mfree;
8511 nk_buffer_init(buffer, &alloc, NK_BUFFER_DEFAULT_INITIAL_SIZE);
8517 nk_size initial_size)
8521 NK_ASSERT(initial_size);
8522 if (!b || !a || !initial_size)
return;
8524 nk_zero(b,
sizeof(*b));
8525 b->
type = NK_BUFFER_DYNAMIC;
8526 b->
memory.ptr = a->alloc(a->userdata,0, initial_size);
8527 b->
memory.size = initial_size;
8528 b->
size = initial_size;
8533nk_buffer_init_fixed(
struct nk_buffer *b,
void *m, nk_size size)
8538 if (!b || !m || !size)
return;
8540 nk_zero(b,
sizeof(*b));
8541 b->
type = NK_BUFFER_FIXED;
8547nk_buffer_align(
void *unaligned,
8548 nk_size align, nk_size *alignment,
8549 enum nk_buffer_allocation_type type)
8555 case NK_BUFFER_FRONT:
8557 memory = NK_ALIGN_PTR(unaligned, align);
8558 *alignment = (nk_size)((nk_byte*)memory - (nk_byte*)unaligned);
8564 case NK_BUFFER_BACK:
8566 memory = NK_ALIGN_PTR_BACK(unaligned, align);
8567 *alignment = (nk_size)((nk_byte*)unaligned - (nk_byte*)memory);
8577nk_buffer_realloc(
struct nk_buffer *b, nk_size capacity, nk_size *size)
8580 nk_size buffer_size;
8584 if (!b || !size || !b->
pool.alloc || !b->
pool.free)
8587 buffer_size = b->
memory.size;
8590 if (!temp)
return 0;
8593 if (temp != b->
memory.ptr) {
8594 NK_MEMCPY(temp, b->
memory.ptr, buffer_size);
8598 if (b->
size == buffer_size) {
8606 back_size = buffer_size - b->
size;
8607 dst = nk_ptr_add(
void, temp, capacity - back_size);
8608 src = nk_ptr_add(
void, temp, b->
size);
8609 NK_MEMCPY(dst, src, back_size);
8610 b->
size = capacity - back_size;
8615nk_buffer_alloc(
struct nk_buffer *b,
enum nk_buffer_allocation_type type,
8616 nk_size size, nk_size align)
8625 if (!b || !size)
return 0;
8629 if (type == NK_BUFFER_FRONT)
8631 else unaligned = nk_ptr_add(
void, b->
memory.ptr, b->
size - size);
8632 memory = nk_buffer_align(unaligned, align, &alignment, type);
8635 if (type == NK_BUFFER_FRONT)
8641 if (b->
type != NK_BUFFER_DYNAMIC)
8643 NK_ASSERT(b->
pool.alloc && b->
pool.free);
8644 if (b->
type != NK_BUFFER_DYNAMIC || !b->
pool.alloc || !b->
pool.free)
8649 capacity = NK_MAX(capacity, nk_round_up_pow2((nk_uint)(b->
allocated + size)));
8650 b->
memory.ptr = nk_buffer_realloc(b, capacity, &b->
memory.size);
8651 if (!b->
memory.ptr)
return 0;
8654 if (type == NK_BUFFER_FRONT)
8656 else unaligned = nk_ptr_add(
void, b->
memory.ptr, b->
size - size);
8657 memory = nk_buffer_align(unaligned, align, &alignment, type);
8659 if (type == NK_BUFFER_FRONT)
8661 else b->
size -= (size + alignment);
8667nk_buffer_push(
struct nk_buffer *b,
enum nk_buffer_allocation_type type,
8668 const void *memory, nk_size size, nk_size align)
8670 void *mem = nk_buffer_alloc(b, type, size, align);
8672 NK_MEMCPY(mem, memory, size);
8675nk_buffer_mark(
struct nk_buffer *buffer,
enum nk_buffer_allocation_type type)
8678 if (!buffer)
return;
8679 buffer->marker[type].active = nk_true;
8680 if (type == NK_BUFFER_BACK)
8681 buffer->marker[type].offset = buffer->
size;
8682 else buffer->marker[type].offset = buffer->
allocated;
8685nk_buffer_reset(
struct nk_buffer *buffer,
enum nk_buffer_allocation_type type)
8688 if (!buffer)
return;
8689 if (type == NK_BUFFER_BACK) {
8691 buffer->
needed -= (buffer->
memory.size - buffer->marker[type].offset);
8692 if (buffer->marker[type].active)
8693 buffer->
size = buffer->marker[type].offset;
8695 buffer->marker[type].active = nk_false;
8699 if (buffer->marker[type].active)
8700 buffer->
allocated = buffer->marker[type].offset;
8702 buffer->marker[type].active = nk_false;
8719 if (!b || !b->
memory.ptr)
return;
8720 if (b->
type == NK_BUFFER_FIXED)
return;
8721 if (!b->
pool.free)
return;
8722 NK_ASSERT(b->
pool.free);
8730 if (!s || !b)
return;
8732 s->size = b->
memory.size;
8734 s->memory = b->
memory.ptr;
8735 s->calls = b->
calls;
8738nk_buffer_memory(
struct nk_buffer *buffer)
8741 if (!buffer)
return 0;
8742 return buffer->
memory.ptr;
8745nk_buffer_memory_const(
const struct nk_buffer *buffer)
8748 if (!buffer)
return 0;
8749 return buffer->
memory.ptr;
8752nk_buffer_total(
const struct nk_buffer *buffer)
8755 if (!buffer)
return 0;
8756 return buffer->
memory.size;
8767#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
8769nk_str_init_default(
struct nk_str *str)
8772 alloc.userdata.ptr = 0;
8773 alloc.alloc = nk_malloc;
8774 alloc.free = nk_mfree;
8775 nk_buffer_init(&str->buffer, &alloc, 32);
8783 nk_buffer_init(&str->buffer, alloc, size);
8787nk_str_init_fixed(
struct nk_str *str,
void *memory, nk_size size)
8789 nk_buffer_init_fixed(&str->buffer, memory, size);
8793nk_str_append_text_char(
struct nk_str *s,
const char *str,
int len)
8798 if (!s || !str || !len)
return 0;
8799 mem = (
char*)nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len *
sizeof(char), 0);
8801 NK_MEMCPY(mem, str, (nk_size)len *
sizeof(
char));
8802 s->len += nk_utf_len(str, len);
8806nk_str_append_str_char(
struct nk_str *s,
const char *str)
8808 return nk_str_append_text_char(s, str, nk_strlen(str));
8811nk_str_append_text_utf8(
struct nk_str *str,
const char *text,
int len)
8816 if (!str || !text || !len)
return 0;
8817 for (i = 0; i < len; ++i)
8818 byte_len += nk_utf_decode(text+byte_len, &unicode, 4);
8819 nk_str_append_text_char(str, text, byte_len);
8823nk_str_append_str_utf8(
struct nk_str *str,
const char *text)
8829 if (!str || !text)
return 0;
8831 glyph_len = byte_len = nk_utf_decode(text+byte_len, &unicode, 4);
8832 while (unicode !=
'\0' && glyph_len) {
8833 glyph_len = nk_utf_decode(text+byte_len, &unicode, 4);
8834 byte_len += glyph_len;
8837 nk_str_append_text_char(str, text, byte_len);
8841nk_str_append_text_runes(
struct nk_str *str,
const nk_rune *text,
int len)
8848 if (!str || !text || !len)
return 0;
8849 for (i = 0; i < len; ++i) {
8850 byte_len = nk_utf_encode(text[i], glyph,
NK_UTF_SIZE);
8851 if (!byte_len)
break;
8852 nk_str_append_text_char(str, glyph, byte_len);
8857nk_str_append_str_runes(
struct nk_str *str,
const nk_rune *runes)
8863 if (!str || !runes)
return 0;
8864 while (runes[i] !=
'\0') {
8865 byte_len = nk_utf_encode(runes[i], glyph,
NK_UTF_SIZE);
8866 nk_str_append_text_char(str, glyph, byte_len);
8872nk_str_insert_at_char(
struct nk_str *s,
int pos,
const char *str,
int len)
8882 NK_ASSERT(len >= 0);
8883 if (!s || !str || !len || (nk_size)pos > s->buffer.
allocated)
return 0;
8885 (s->buffer.
type == NK_BUFFER_FIXED))
return 0;
8887 copylen = (int)s->buffer.
allocated - pos;
8889 nk_str_append_text_char(s, str, len);
8892 mem = nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len *
sizeof(
char), 0);
8896 NK_ASSERT(((
int)pos + (
int)len + ((
int)copylen - 1)) >= 0);
8897 NK_ASSERT(((
int)pos + ((
int)copylen - 1)) >= 0);
8898 dst = nk_ptr_add(
char, s->buffer.
memory.ptr, pos + len + (copylen - 1));
8899 src = nk_ptr_add(
char, s->buffer.
memory.ptr, pos + (copylen-1));
8900 for (i = 0; i < copylen; ++i) *dst-- = *src--;
8901 mem = nk_ptr_add(
void, s->buffer.
memory.ptr, pos);
8902 NK_MEMCPY(mem, str, (nk_size)len *
sizeof(
char));
8903 s->len = nk_utf_len((
char *)s->buffer.
memory.ptr, (
int)s->buffer.
allocated);
8907nk_str_insert_at_rune(
struct nk_str *str,
int pos,
const char *cstr,
int len)
8917 if (!str || !cstr || !len)
return 0;
8918 begin = nk_str_at_rune(str, pos, &unicode, &glyph_len);
8920 return nk_str_append_text_char(str, cstr, len);
8921 buffer = nk_str_get_const(str);
8922 if (!begin)
return 0;
8923 return nk_str_insert_at_char(str, (
int)(begin - buffer), cstr, len);
8926nk_str_insert_text_char(
struct nk_str *str,
int pos,
const char *text,
int len)
8928 return nk_str_insert_text_utf8(str, pos, text, len);
8931nk_str_insert_str_char(
struct nk_str *str,
int pos,
const char *text)
8933 return nk_str_insert_text_utf8(str, pos, text, nk_strlen(text));
8936nk_str_insert_text_utf8(
struct nk_str *str,
int pos,
const char *text,
int len)
8944 if (!str || !text || !len)
return 0;
8945 for (i = 0; i < len; ++i)
8946 byte_len += nk_utf_decode(text+byte_len, &unicode, 4);
8947 nk_str_insert_at_rune(str, pos, text, byte_len);
8951nk_str_insert_str_utf8(
struct nk_str *str,
int pos,
const char *text)
8957 if (!str || !text)
return 0;
8959 glyph_len = byte_len = nk_utf_decode(text+byte_len, &unicode, 4);
8960 while (unicode !=
'\0' && glyph_len) {
8961 glyph_len = nk_utf_decode(text+byte_len, &unicode, 4);
8962 byte_len += glyph_len;
8965 nk_str_insert_at_rune(str, pos, text, byte_len);
8969nk_str_insert_text_runes(
struct nk_str *str,
int pos,
const nk_rune *runes,
int len)
8976 if (!str || !runes || !len)
return 0;
8977 for (i = 0; i < len; ++i) {
8978 byte_len = nk_utf_encode(runes[i], glyph,
NK_UTF_SIZE);
8979 if (!byte_len)
break;
8980 nk_str_insert_at_rune(str, pos+i, glyph, byte_len);
8985nk_str_insert_str_runes(
struct nk_str *str,
int pos,
const nk_rune *runes)
8991 if (!str || !runes)
return 0;
8992 while (runes[i] !=
'\0') {
8993 byte_len = nk_utf_encode(runes[i], glyph,
NK_UTF_SIZE);
8994 nk_str_insert_at_rune(str, pos+i, glyph, byte_len);
9000nk_str_remove_chars(
struct nk_str *s,
int len)
9003 NK_ASSERT(len >= 0);
9004 if (!s || len < 0 || (nk_size)len > s->buffer.
allocated)
return;
9005 NK_ASSERT(((
int)s->buffer.
allocated - (
int)len) >= 0);
9007 s->len = nk_utf_len((
char *)s->buffer.
memory.ptr, (
int)s->buffer.
allocated);
9010nk_str_remove_runes(
struct nk_str *str,
int len)
9018 NK_ASSERT(len >= 0);
9019 if (!str || len < 0)
return;
9020 if (len >= str->len) {
9025 index = str->len - len;
9026 begin = nk_str_at_rune(str, index, &unicode, &len);
9028 nk_str_remove_chars(str, (
int)(end-begin)+1);
9031nk_str_delete_chars(
struct nk_str *s,
int pos,
int len)
9034 if (!s || !len || (nk_size)pos > s->buffer.
allocated ||
9035 (nk_size)(pos + len) > s->buffer.
allocated)
return;
9037 if ((nk_size)(pos + len) < s->buffer.
allocated) {
9039 char *dst = nk_ptr_add(
char, s->buffer.
memory.ptr, pos);
9040 char *src = nk_ptr_add(
char, s->buffer.
memory.ptr, pos + len);
9041 NK_MEMCPY(dst, src, s->buffer.
allocated - (nk_size)(pos + len));
9042 NK_ASSERT(((
int)s->buffer.
allocated - (
int)len) >= 0);
9044 }
else nk_str_remove_chars(s, len);
9045 s->len = nk_utf_len((
char *)s->buffer.
memory.ptr, (
int)s->buffer.
allocated);
9048nk_str_delete_runes(
struct nk_str *s,
int pos,
int len)
9057 NK_ASSERT(s->len >= pos + len);
9058 if (s->len < pos + len)
9059 len = NK_CLAMP(0, (s->len - pos), s->len);
9062 temp = (
char *)s->buffer.
memory.ptr;
9063 begin = nk_str_at_rune(s, pos, &unicode, &unused);
9065 s->buffer.
memory.ptr = begin;
9066 end = nk_str_at_rune(s, len, &unicode, &unused);
9067 s->buffer.
memory.ptr = temp;
9069 nk_str_delete_chars(s, (
int)(begin - temp), (
int)(end - begin));
9072nk_str_at_char(
struct nk_str *s,
int pos)
9075 if (!s || pos > (
int)s->buffer.
allocated)
return 0;
9076 return nk_ptr_add(
char, s->buffer.
memory.ptr, pos);
9079nk_str_at_rune(
struct nk_str *str,
int pos, nk_rune *unicode,
int *len)
9091 if (!str || !unicode || !len)
return 0;
9098 text = (
char*)str->buffer.
memory.ptr;
9100 glyph_len = nk_utf_decode(text, unicode, text_len);
9108 src_len = src_len + glyph_len;
9109 glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
9111 if (i != pos)
return 0;
9112 return text + src_len;
9115nk_str_at_char_const(
const struct nk_str *s,
int pos)
9118 if (!s || pos > (
int)s->buffer.
allocated)
return 0;
9119 return nk_ptr_add(
char, s->buffer.
memory.ptr, pos);
9122nk_str_at_const(
const struct nk_str *str,
int pos, nk_rune *unicode,
int *len)
9134 if (!str || !unicode || !len)
return 0;
9141 text = (
char*)str->buffer.
memory.ptr;
9143 glyph_len = nk_utf_decode(text, unicode, text_len);
9151 src_len = src_len + glyph_len;
9152 glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
9154 if (i != pos)
return 0;
9155 return text + src_len;
9158nk_str_rune_at(
const struct nk_str *str,
int pos)
9161 nk_rune unicode = 0;
9162 nk_str_at_const(str, pos, &unicode, &len);
9166nk_str_get(
struct nk_str *s)
9169 if (!s || !s->len || !s->buffer.
allocated)
return 0;
9170 return (
char*)s->buffer.
memory.ptr;
9173nk_str_get_const(
const struct nk_str *s)
9176 if (!s || !s->len || !s->buffer.
allocated)
return 0;
9177 return (
const char*)s->buffer.
memory.ptr;
9180nk_str_len(
const struct nk_str *s)
9183 if (!s || !s->len || !s->buffer.
allocated)
return 0;
9187nk_str_len_char(
const struct nk_str *s)
9190 if (!s || !s->len || !s->buffer.
allocated)
return 0;
9194nk_str_clear(
struct nk_str *str)
9197 nk_buffer_clear(&str->buffer);
9201nk_str_free(
struct nk_str *str)
9204 nk_buffer_free(&str->buffer);
9218 struct nk_buffer *b,
enum nk_command_clipping clip)
9222 if (!cb || !b)
return;
9224 cb->use_clipping = (int)clip;
9237 b->clip = nk_null_rect;
9238#ifdef NK_INCLUDE_COMMAND_USERDATA
9239 b->userdata.ptr = 0;
9244 enum nk_command_type t, nk_size size)
9246 NK_STORAGE
const nk_size align = NK_ALIGNOF(
struct nk_command);
9255 cmd = (
struct nk_command*)nk_buffer_alloc(b->base,NK_BUFFER_FRONT,size,align);
9259 b->last = (nk_size)((nk_byte*)cmd - (nk_byte*)b->base->
memory.ptr);
9260 unaligned = (nk_byte*)cmd + size;
9261 memory = NK_ALIGN_PTR(unaligned, align);
9262 alignment = (nk_size)((nk_byte*)memory - (nk_byte*)unaligned);
9263#ifdef NK_ZERO_COMMAND_MEMORY
9264 NK_MEMSET(cmd, 0, size + alignment);
9268 cmd->next = b->base->
allocated + alignment;
9269#ifdef NK_INCLUDE_COMMAND_USERDATA
9270 cmd->userdata = b->userdata;
9287 nk_command_buffer_push(b, NK_COMMAND_SCISSOR,
sizeof(*cmd));
9290 cmd->x = (short)r.x;
9291 cmd->y = (short)r.y;
9292 cmd->w = (
unsigned short)NK_MAX(0, r.w);
9293 cmd->h = (
unsigned short)NK_MAX(0, r.h);
9297 float x1,
float y1,
float line_thickness,
struct nk_color c)
9301 if (!b || line_thickness <= 0)
return;
9303 nk_command_buffer_push(b, NK_COMMAND_LINE,
sizeof(*cmd));
9305 cmd->line_thickness = (
unsigned short)line_thickness;
9306 cmd->begin.x = (short)x0;
9307 cmd->begin.y = (short)y0;
9308 cmd->end.x = (short)x1;
9309 cmd->end.y = (short)y1;
9314 float ctrl0x,
float ctrl0y,
float ctrl1x,
float ctrl1y,
9315 float bx,
float by,
float line_thickness,
struct nk_color col)
9319 if (!b || col.a == 0 || line_thickness <= 0)
return;
9322 nk_command_buffer_push(b, NK_COMMAND_CURVE,
sizeof(*cmd));
9324 cmd->line_thickness = (
unsigned short)line_thickness;
9325 cmd->begin.x = (short)ax;
9326 cmd->begin.y = (short)ay;
9327 cmd->ctrl[0].x = (short)ctrl0x;
9328 cmd->ctrl[0].y = (short)ctrl0y;
9329 cmd->ctrl[1].x = (short)ctrl1x;
9330 cmd->ctrl[1].y = (short)ctrl1y;
9331 cmd->end.x = (short)bx;
9332 cmd->end.y = (short)by;
9337 float rounding,
float line_thickness,
struct nk_color c)
9341 if (!b || c.a == 0 || rect.w == 0 || rect.h == 0 || line_thickness <= 0)
return;
9342 if (b->use_clipping) {
9343 const struct nk_rect *clip = &b->clip;
9344 if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
9345 clip->x, clip->y, clip->w, clip->h))
return;
9348 nk_command_buffer_push(b, NK_COMMAND_RECT,
sizeof(*cmd));
9350 cmd->rounding = (
unsigned short)rounding;
9351 cmd->line_thickness = (
unsigned short)line_thickness;
9352 cmd->x = (short)rect.x;
9353 cmd->y = (short)rect.y;
9354 cmd->w = (
unsigned short)NK_MAX(0, rect.w);
9355 cmd->h = (
unsigned short)NK_MAX(0, rect.h);
9364 if (!b || c.a == 0 || rect.w == 0 || rect.h == 0)
return;
9365 if (b->use_clipping) {
9366 const struct nk_rect *clip = &b->clip;
9367 if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
9368 clip->x, clip->y, clip->w, clip->h))
return;
9372 nk_command_buffer_push(b, NK_COMMAND_RECT_FILLED,
sizeof(*cmd));
9374 cmd->rounding = (
unsigned short)rounding;
9375 cmd->x = (short)rect.x;
9376 cmd->y = (short)rect.y;
9377 cmd->w = (
unsigned short)NK_MAX(0, rect.w);
9378 cmd->h = (
unsigned short)NK_MAX(0, rect.h);
9388 if (!b || rect.w == 0 || rect.h == 0)
return;
9389 if (b->use_clipping) {
9390 const struct nk_rect *clip = &b->clip;
9391 if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
9392 clip->x, clip->y, clip->w, clip->h))
return;
9396 nk_command_buffer_push(b, NK_COMMAND_RECT_MULTI_COLOR,
sizeof(*cmd));
9398 cmd->x = (short)rect.x;
9399 cmd->y = (short)rect.y;
9400 cmd->w = (
unsigned short)NK_MAX(0, rect.w);
9401 cmd->h = (
unsigned short)NK_MAX(0, rect.h);
9405 cmd->bottom = bottom;
9409 float line_thickness,
struct nk_color c)
9412 if (!b || r.w == 0 || r.h == 0 || line_thickness <= 0)
return;
9413 if (b->use_clipping) {
9414 const struct nk_rect *clip = &b->clip;
9415 if (!NK_INTERSECT(r.x, r.y, r.w, r.h, clip->x, clip->y, clip->w, clip->h))
9420 nk_command_buffer_push(b, NK_COMMAND_CIRCLE,
sizeof(*cmd));
9422 cmd->line_thickness = (
unsigned short)line_thickness;
9423 cmd->x = (short)r.x;
9424 cmd->y = (short)r.y;
9425 cmd->w = (
unsigned short)NK_MAX(r.w, 0);
9426 cmd->h = (
unsigned short)NK_MAX(r.h, 0);
9434 if (!b || c.a == 0 || r.w == 0 || r.h == 0)
return;
9435 if (b->use_clipping) {
9436 const struct nk_rect *clip = &b->clip;
9437 if (!NK_INTERSECT(r.x, r.y, r.w, r.h, clip->x, clip->y, clip->w, clip->h))
9442 nk_command_buffer_push(b, NK_COMMAND_CIRCLE_FILLED,
sizeof(*cmd));
9444 cmd->x = (short)r.x;
9445 cmd->y = (short)r.y;
9446 cmd->w = (
unsigned short)NK_MAX(r.w, 0);
9447 cmd->h = (
unsigned short)NK_MAX(r.h, 0);
9452 float a_min,
float a_max,
float line_thickness,
struct nk_color c)
9455 if (!b || c.a == 0 || line_thickness <= 0)
return;
9457 nk_command_buffer_push(b, NK_COMMAND_ARC,
sizeof(*cmd));
9459 cmd->line_thickness = (
unsigned short)line_thickness;
9460 cmd->cx = (short)cx;
9461 cmd->cy = (short)cy;
9462 cmd->r = (
unsigned short)radius;
9469 float a_min,
float a_max,
struct nk_color c)
9473 if (!b || c.a == 0)
return;
9475 nk_command_buffer_push(b, NK_COMMAND_ARC_FILLED,
sizeof(*cmd));
9477 cmd->cx = (short)cx;
9478 cmd->cy = (short)cy;
9479 cmd->r = (
unsigned short)radius;
9486 float y1,
float x2,
float y2,
float line_thickness,
struct nk_color c)
9490 if (!b || c.a == 0 || line_thickness <= 0)
return;
9491 if (b->use_clipping) {
9492 const struct nk_rect *clip = &b->clip;
9493 if (!NK_INBOX(x0, y0, clip->x, clip->y, clip->w, clip->h) &&
9494 !NK_INBOX(x1, y1, clip->x, clip->y, clip->w, clip->h) &&
9495 !NK_INBOX(x2, y2, clip->x, clip->y, clip->w, clip->h))
9500 nk_command_buffer_push(b, NK_COMMAND_TRIANGLE,
sizeof(*cmd));
9502 cmd->line_thickness = (
unsigned short)line_thickness;
9503 cmd->a.x = (short)x0;
9504 cmd->a.y = (short)y0;
9505 cmd->b.x = (short)x1;
9506 cmd->b.y = (short)y1;
9507 cmd->c.x = (short)x2;
9508 cmd->c.y = (short)y2;
9513 float y1,
float x2,
float y2,
struct nk_color c)
9517 if (!b || c.a == 0)
return;
9519 if (b->use_clipping) {
9520 const struct nk_rect *clip = &b->clip;
9521 if (!NK_INBOX(x0, y0, clip->x, clip->y, clip->w, clip->h) &&
9522 !NK_INBOX(x1, y1, clip->x, clip->y, clip->w, clip->h) &&
9523 !NK_INBOX(x2, y2, clip->x, clip->y, clip->w, clip->h))
9528 nk_command_buffer_push(b, NK_COMMAND_TRIANGLE_FILLED,
sizeof(*cmd));
9530 cmd->a.x = (short)x0;
9531 cmd->a.y = (short)y0;
9532 cmd->b.x = (short)x1;
9533 cmd->b.y = (short)y1;
9534 cmd->c.x = (short)x2;
9535 cmd->c.y = (short)y2;
9539nk_stroke_polygon(
struct nk_command_buffer *b,
const float *points,
int point_count,
9540 float line_thickness,
struct nk_color col)
9547 if (!b || col.a == 0 || line_thickness <= 0)
return;
9548 size =
sizeof(*cmd) +
sizeof(short) * 2 * (nk_size)point_count;
9549 cmd = (
struct nk_command_polygon*) nk_command_buffer_push(b, NK_COMMAND_POLYGON, size);
9552 cmd->line_thickness = (
unsigned short)line_thickness;
9553 cmd->point_count = (
unsigned short)point_count;
9554 for (i = 0; i < point_count; ++i) {
9555 cmd->points[i].x = (short)points[i*2];
9556 cmd->points[i].y = (short)points[i*2+1];
9560nk_fill_polygon(
struct nk_command_buffer *b,
const float *points,
int point_count,
9568 if (!b || col.a == 0)
return;
9569 size =
sizeof(*cmd) +
sizeof(short) * 2 * (nk_size)point_count;
9571 nk_command_buffer_push(b, NK_COMMAND_POLYGON_FILLED, size);
9574 cmd->point_count = (
unsigned short)point_count;
9575 for (i = 0; i < point_count; ++i) {
9576 cmd->points[i].x = (short)points[i*2+0];
9577 cmd->points[i].y = (short)points[i*2+1];
9581nk_stroke_polyline(
struct nk_command_buffer *b,
const float *points,
int point_count,
9582 float line_thickness,
struct nk_color col)
9589 if (!b || col.a == 0 || line_thickness <= 0)
return;
9590 size =
sizeof(*cmd) +
sizeof(short) * 2 * (nk_size)point_count;
9594 cmd->point_count = (
unsigned short)point_count;
9595 cmd->line_thickness = (
unsigned short)line_thickness;
9596 for (i = 0; i < point_count; ++i) {
9597 cmd->points[i].x = (short)points[i*2];
9598 cmd->points[i].y = (short)points[i*2+1];
9608 if (b->use_clipping) {
9609 const struct nk_rect *c = &b->clip;
9610 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))
9615 nk_command_buffer_push(b, NK_COMMAND_IMAGE,
sizeof(*cmd));
9617 cmd->x = (short)r.x;
9618 cmd->y = (short)r.y;
9619 cmd->w = (
unsigned short)NK_MAX(0, r.w);
9620 cmd->h = (
unsigned short)NK_MAX(0, r.h);
9630 nk_ushort rgnX, rgnY, rgnW, rgnH;
9631 rgnX = slcimg->region[0];
9632 rgnY = slcimg->region[1];
9633 rgnW = slcimg->region[2];
9634 rgnH = slcimg->region[3];
9637 img.handle = slcimg->handle;
9640 img.region[0] = rgnX;
9641 img.region[1] = rgnY;
9642 img.region[2] = slc->l;
9643 img.region[3] = slc->t;
9646 nk_rect(r.x, r.y, (
float)slc->l, (
float)slc->t),
9649#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);
9652 IMG_RGN(rgnX + slc->l, rgnY, rgnW - slc->l - slc->r, slc->t);
9654 nk_rect(r.x + (
float)slc->l, r.y, (
float)(r.w - slc->l - slc->r), (
float)slc->t),
9658 IMG_RGN(rgnX + rgnW - slc->r, rgnY, slc->r, slc->t);
9660 nk_rect(r.x + r.w - (
float)slc->r, r.y, (
float)slc->r, (
float)slc->t),
9664 IMG_RGN(rgnX, rgnY + slc->t, slc->l, rgnH - slc->t - slc->b);
9666 nk_rect(r.x, r.y + (
float)slc->t, (
float)slc->l, (
float)(r.h - slc->t - slc->b)),
9670 IMG_RGN(rgnX + slc->l, rgnY + slc->t, rgnW - slc->l - slc->r, rgnH - slc->t - slc->b);
9672 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)),
9676 IMG_RGN(rgnX + rgnW - slc->r, rgnY + slc->t, slc->r, rgnH - slc->t - slc->b);
9678 nk_rect(r.x + r.w - (
float)slc->r, r.y + (
float)slc->t, (
float)slc->r, (
float)(r.h - slc->t - slc->b)),
9682 IMG_RGN(rgnX, rgnY + rgnH - slc->b, slc->l, slc->b);
9684 nk_rect(r.x, r.y + r.h - (
float)slc->b, (
float)slc->l, (
float)slc->b),
9688 IMG_RGN(rgnX + slc->l, rgnY + rgnH - slc->b, rgnW - slc->l - slc->r, slc->b);
9690 nk_rect(r.x + (
float)slc->l, r.y + r.h - (
float)slc->b, (
float)(r.w - slc->l - slc->r), (
float)slc->b),
9694 IMG_RGN(rgnX + rgnW - slc->r, rgnY + rgnH - slc->b, slc->r, slc->b);
9696 nk_rect(r.x + r.w - (
float)slc->r, r.y + r.h - (
float)slc->b, (
float)slc->r, (
float)slc->b),
9703 nk_command_custom_callback cb,
nk_handle usr)
9708 if (b->use_clipping) {
9709 const struct nk_rect *c = &b->clip;
9710 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))
9715 nk_command_buffer_push(b, NK_COMMAND_CUSTOM,
sizeof(*cmd));
9717 cmd->x = (short)r.x;
9718 cmd->y = (short)r.y;
9719 cmd->w = (
unsigned short)NK_MAX(0, r.w);
9720 cmd->h = (
unsigned short)NK_MAX(0, r.h);
9721 cmd->callback_data = usr;
9726 const char *
string,
int length,
const struct nk_user_font *font,
9729 float text_width = 0;
9734 if (!b || !
string || !length || (bg.a == 0 && fg.a == 0))
return;
9735 if (b->use_clipping) {
9736 const struct nk_rect *c = &b->clip;
9737 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))
9742 text_width = font->
width(font->userdata, font->
height,
string, length);
9743 if (text_width > r.w){
9745 float txt_width = (float)text_width;
9746 length = nk_text_clamp(font,
string, length, r.w, &glyphs, &txt_width, 0,0);
9749 if (!length)
return;
9751 nk_command_buffer_push(b, NK_COMMAND_TEXT,
sizeof(*cmd) + (nk_size)(length + 1));
9753 cmd->x = (short)r.x;
9754 cmd->y = (short)r.y;
9755 cmd->w = (
unsigned short)r.w;
9756 cmd->h = (
unsigned short)r.h;
9757 cmd->background = bg;
9758 cmd->foreground = fg;
9760 cmd->length = length;
9761 cmd->height = font->
height;
9762 NK_MEMCPY(cmd->string,
string, (nk_size)length);
9763 cmd->string[length] =
'\0';
9774#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
9776nk_draw_list_init(
struct nk_draw_list *list)
9781 nk_zero(list,
sizeof(*list));
9782 for (i = 0; i < NK_LEN(list->circle_vtx); ++i) {
9783 const float a = ((float)i / (
float)NK_LEN(list->circle_vtx)) * 2 * NK_PI;
9784 list->circle_vtx[i].x = (float)NK_COS(a);
9785 list->circle_vtx[i].y = (float)NK_SIN(a);
9789nk_draw_list_setup(
struct nk_draw_list *canvas,
const struct nk_convert_config *config,
9791 enum nk_anti_aliasing line_aa,
enum nk_anti_aliasing shape_aa)
9796 NK_ASSERT(vertices);
9797 NK_ASSERT(elements);
9798 if (!canvas || !config || !cmds || !vertices || !elements)
9801 canvas->buffer = cmds;
9802 canvas->config = *config;
9803 canvas->elements = elements;
9804 canvas->vertices = vertices;
9805 canvas->line_AA = line_aa;
9806 canvas->shape_AA = shape_aa;
9807 canvas->clip_rect = nk_null_rect;
9809 canvas->cmd_offset = 0;
9810 canvas->element_count = 0;
9811 canvas->vertex_count = 0;
9812 canvas->cmd_offset = 0;
9813 canvas->cmd_count = 0;
9814 canvas->path_count = 0;
9816NK_API
const struct nk_draw_command*
9817nk__draw_list_begin(
const struct nk_draw_list *canvas,
const struct nk_buffer *buffer)
9821 const struct nk_draw_command *cmd;
9824 if (!buffer || !buffer->
size || !canvas->cmd_count)
9827 memory = (nk_byte*)buffer->
memory.ptr;
9828 offset = buffer->
memory.size - canvas->cmd_offset;
9829 cmd = nk_ptr_add(
const struct nk_draw_command, memory, offset);
9832NK_API
const struct nk_draw_command*
9833nk__draw_list_end(
const struct nk_draw_list *canvas,
const struct nk_buffer *buffer)
9838 const struct nk_draw_command *end;
9842 if (!buffer || !canvas)
9845 memory = (nk_byte*)buffer->
memory.ptr;
9846 size = buffer->
memory.size;
9847 offset = size - canvas->cmd_offset;
9848 end = nk_ptr_add(
const struct nk_draw_command, memory, offset);
9849 end -= (canvas->cmd_count-1);
9852NK_API
const struct nk_draw_command*
9853nk__draw_list_next(
const struct nk_draw_command *cmd,
9854 const struct nk_buffer *buffer,
const struct nk_draw_list *canvas)
9856 const struct nk_draw_command *end;
9859 if (!cmd || !buffer || !canvas)
9862 end = nk__draw_list_end(canvas, buffer);
9863 if (cmd <= end)
return 0;
9867nk_draw_list_alloc_path(
struct nk_draw_list *list,
int count)
9870 NK_STORAGE
const nk_size point_align = NK_ALIGNOF(
struct nk_vec2);
9871 NK_STORAGE
const nk_size point_size =
sizeof(
struct nk_vec2);
9873 nk_buffer_alloc(list->buffer, NK_BUFFER_FRONT,
9874 point_size * (nk_size)count, point_align);
9876 if (!points)
return 0;
9877 if (!list->path_offset) {
9878 void *memory = nk_buffer_memory(list->buffer);
9879 list->path_offset = (
unsigned int)((nk_byte*)points - (nk_byte*)memory);
9881 list->path_count += (
unsigned int)count;
9885nk_draw_list_path_last(struct nk_draw_list *list)
9889 NK_ASSERT(list->path_count);
9890 memory = nk_buffer_memory(list->buffer);
9891 point = nk_ptr_add(
struct nk_vec2, memory, list->path_offset);
9892 point += (list->path_count-1);
9895NK_INTERN
struct nk_draw_command*
9896nk_draw_list_push_command(
struct nk_draw_list *list,
struct nk_rect clip,
9899 NK_STORAGE
const nk_size cmd_align = NK_ALIGNOF(
struct nk_draw_command);
9900 NK_STORAGE
const nk_size cmd_size =
sizeof(
struct nk_draw_command);
9901 struct nk_draw_command *cmd;
9904 cmd = (
struct nk_draw_command*)
9905 nk_buffer_alloc(list->buffer, NK_BUFFER_BACK, cmd_size, cmd_align);
9908 if (!list->cmd_count) {
9909 nk_byte *memory = (nk_byte*)nk_buffer_memory(list->buffer);
9910 nk_size total = nk_buffer_total(list->buffer);
9911 memory = nk_ptr_add(nk_byte, memory, total);
9912 list->cmd_offset = (nk_size)(memory - (nk_byte*)cmd);
9915 cmd->elem_count = 0;
9916 cmd->clip_rect = clip;
9917 cmd->texture = texture;
9918#ifdef NK_INCLUDE_COMMAND_USERDATA
9919 cmd->userdata = list->userdata;
9923 list->clip_rect = clip;
9926NK_INTERN
struct nk_draw_command*
9927nk_draw_list_command_last(
struct nk_draw_list *list)
9931 struct nk_draw_command *cmd;
9932 NK_ASSERT(list->cmd_count);
9934 memory = nk_buffer_memory(list->buffer);
9935 size = nk_buffer_total(list->buffer);
9936 cmd = nk_ptr_add(
struct nk_draw_command, memory, size - list->cmd_offset);
9937 return (cmd - (list->cmd_count-1));
9940nk_draw_list_add_clip(
struct nk_draw_list *list,
struct nk_rect rect)
9944 if (!list->cmd_count) {
9945 nk_draw_list_push_command(list, rect, list->config.tex_null.texture);
9947 struct nk_draw_command *prev = nk_draw_list_command_last(list);
9948 if (prev->elem_count == 0)
9949 prev->clip_rect = rect;
9950 nk_draw_list_push_command(list, rect, prev->texture);
9954nk_draw_list_push_image(
struct nk_draw_list *list,
nk_handle texture)
9958 if (!list->cmd_count) {
9959 nk_draw_list_push_command(list, nk_null_rect, texture);
9961 struct nk_draw_command *prev = nk_draw_list_command_last(list);
9962 if (prev->elem_count == 0) {
9963 prev->texture = texture;
9964 #ifdef NK_INCLUDE_COMMAND_USERDATA
9965 prev->userdata = list->userdata;
9967 }
else if (prev->texture.id != texture.id
9968 #ifdef NK_INCLUDE_COMMAND_USERDATA
9969 || prev->userdata.id != list->userdata.id
9972 nk_draw_list_push_command(list, prev->clip_rect, texture);
9976#ifdef NK_INCLUDE_COMMAND_USERDATA
9978nk_draw_list_push_userdata(
struct nk_draw_list *list,
nk_handle userdata)
9980 list->userdata = userdata;
9984nk_draw_list_alloc_vertices(
struct nk_draw_list *list, nk_size count)
9988 if (!list)
return 0;
9989 vtx = nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT,
9990 list->config.vertex_size*count, list->config.vertex_alignment);
9992 list->vertex_count += (
unsigned int)count;
10003 if(
sizeof(nk_draw_index)==2) NK_ASSERT((list->vertex_count < NK_USHORT_MAX &&
10004 "To many vertices for 16-bit vertex indices. Please read comment above on how to solve this problem"));
10007NK_INTERN nk_draw_index*
10008nk_draw_list_alloc_elements(
struct nk_draw_list *list, nk_size count)
10010 nk_draw_index *ids;
10011 struct nk_draw_command *cmd;
10012 NK_STORAGE
const nk_size elem_align = NK_ALIGNOF(nk_draw_index);
10013 NK_STORAGE
const nk_size elem_size =
sizeof(nk_draw_index);
10015 if (!list)
return 0;
10017 ids = (nk_draw_index*)
10018 nk_buffer_alloc(list->elements, NK_BUFFER_FRONT, elem_size*count, elem_align);
10019 if (!ids)
return 0;
10020 cmd = nk_draw_list_command_last(list);
10021 list->element_count += (
unsigned int)count;
10022 cmd->elem_count += (
unsigned int)count;
10026nk_draw_vertex_layout_element_is_end_of_layout(
10027 const struct nk_draw_vertex_layout_element *element)
10029 return (element->attribute == NK_VERTEX_ATTRIBUTE_COUNT ||
10030 element->format == NK_FORMAT_COUNT);
10033nk_draw_vertex_color(
void *attr,
const float *vals,
10034 enum nk_draw_vertex_layout_format format)
10038 NK_ASSERT(format >= NK_FORMAT_COLOR_BEGIN);
10039 NK_ASSERT(format <= NK_FORMAT_COLOR_END);
10040 if (format < NK_FORMAT_COLOR_BEGIN || format > NK_FORMAT_COLOR_END)
return;
10042 val[0] = NK_SATURATE(vals[0]);
10043 val[1] = NK_SATURATE(vals[1]);
10044 val[2] = NK_SATURATE(vals[2]);
10045 val[3] = NK_SATURATE(vals[3]);
10048 default: NK_ASSERT(0 &&
"Invalid vertex layout color format");
break;
10049 case NK_FORMAT_R8G8B8A8:
10050 case NK_FORMAT_R8G8B8: {
10051 struct nk_color col = nk_rgba_fv(val);
10052 NK_MEMCPY(attr, &col.r,
sizeof(col));
10054 case NK_FORMAT_B8G8R8A8: {
10055 struct nk_color col = nk_rgba_fv(val);
10056 struct nk_color bgra = nk_rgba(col.b, col.g, col.r, col.a);
10057 NK_MEMCPY(attr, &bgra,
sizeof(bgra));
10059 case NK_FORMAT_R16G15B16: {
10061 col[0] = (nk_ushort)(val[0]*(
float)NK_USHORT_MAX);
10062 col[1] = (nk_ushort)(val[1]*(
float)NK_USHORT_MAX);
10063 col[2] = (nk_ushort)(val[2]*(
float)NK_USHORT_MAX);
10064 NK_MEMCPY(attr, col,
sizeof(col));
10066 case NK_FORMAT_R16G15B16A16: {
10068 col[0] = (nk_ushort)(val[0]*(
float)NK_USHORT_MAX);
10069 col[1] = (nk_ushort)(val[1]*(
float)NK_USHORT_MAX);
10070 col[2] = (nk_ushort)(val[2]*(
float)NK_USHORT_MAX);
10071 col[3] = (nk_ushort)(val[3]*(
float)NK_USHORT_MAX);
10072 NK_MEMCPY(attr, col,
sizeof(col));
10074 case NK_FORMAT_R32G32B32: {
10076 col[0] = (nk_uint)(val[0]*(
float)NK_UINT_MAX);
10077 col[1] = (nk_uint)(val[1]*(
float)NK_UINT_MAX);
10078 col[2] = (nk_uint)(val[2]*(
float)NK_UINT_MAX);
10079 NK_MEMCPY(attr, col,
sizeof(col));
10081 case NK_FORMAT_R32G32B32A32: {
10083 col[0] = (nk_uint)(val[0]*(
float)NK_UINT_MAX);
10084 col[1] = (nk_uint)(val[1]*(
float)NK_UINT_MAX);
10085 col[2] = (nk_uint)(val[2]*(
float)NK_UINT_MAX);
10086 col[3] = (nk_uint)(val[3]*(
float)NK_UINT_MAX);
10087 NK_MEMCPY(attr, col,
sizeof(col));
10089 case NK_FORMAT_R32G32B32A32_FLOAT:
10090 NK_MEMCPY(attr, val,
sizeof(
float)*4);
10092 case NK_FORMAT_R32G32B32A32_DOUBLE: {
10094 col[0] = (double)val[0];
10095 col[1] = (double)val[1];
10096 col[2] = (double)val[2];
10097 col[3] = (double)val[3];
10098 NK_MEMCPY(attr, col,
sizeof(col));
10100 case NK_FORMAT_RGB32:
10101 case NK_FORMAT_RGBA32: {
10102 struct nk_color col = nk_rgba_fv(val);
10103 nk_uint color = nk_color_u32(col);
10104 NK_MEMCPY(attr, &color,
sizeof(color));
10108nk_draw_vertex_element(
void *dst,
const float *values,
int value_count,
10109 enum nk_draw_vertex_layout_format format)
10112 void *attribute = dst;
10114 NK_ASSERT(format < NK_FORMAT_COLOR_BEGIN);
10115 if (format >= NK_FORMAT_COLOR_BEGIN && format <= NK_FORMAT_COLOR_END)
return;
10116 for (value_index = 0; value_index < value_count; ++value_index) {
10118 default: NK_ASSERT(0 &&
"invalid vertex layout format");
break;
10119 case NK_FORMAT_SCHAR: {
10120 char value = (char)NK_CLAMP((
float)NK_SCHAR_MIN, values[value_index], (float)NK_SCHAR_MAX);
10121 NK_MEMCPY(attribute, &value,
sizeof(value));
10122 attribute = (
void*)((
char*)attribute +
sizeof(char));
10124 case NK_FORMAT_SSHORT: {
10125 nk_short value = (nk_short)NK_CLAMP((
float)NK_SSHORT_MIN, values[value_index], (float)NK_SSHORT_MAX);
10126 NK_MEMCPY(attribute, &value,
sizeof(value));
10127 attribute = (
void*)((
char*)attribute +
sizeof(value));
10129 case NK_FORMAT_SINT: {
10130 nk_int value = (nk_int)NK_CLAMP((
float)NK_SINT_MIN, values[value_index], (float)NK_SINT_MAX);
10131 NK_MEMCPY(attribute, &value,
sizeof(value));
10132 attribute = (
void*)((
char*)attribute +
sizeof(nk_int));
10134 case NK_FORMAT_UCHAR: {
10135 unsigned char value = (
unsigned char)NK_CLAMP((
float)NK_UCHAR_MIN, values[value_index], (float)NK_UCHAR_MAX);
10136 NK_MEMCPY(attribute, &value,
sizeof(value));
10137 attribute = (
void*)((
char*)attribute +
sizeof(
unsigned char));
10139 case NK_FORMAT_USHORT: {
10140 nk_ushort value = (nk_ushort)NK_CLAMP((
float)NK_USHORT_MIN, values[value_index], (float)NK_USHORT_MAX);
10141 NK_MEMCPY(attribute, &value,
sizeof(value));
10142 attribute = (
void*)((
char*)attribute +
sizeof(value));
10144 case NK_FORMAT_UINT: {
10145 nk_uint value = (nk_uint)NK_CLAMP((
float)NK_UINT_MIN, values[value_index], (float)NK_UINT_MAX);
10146 NK_MEMCPY(attribute, &value,
sizeof(value));
10147 attribute = (
void*)((
char*)attribute +
sizeof(nk_uint));
10149 case NK_FORMAT_FLOAT:
10150 NK_MEMCPY(attribute, &values[value_index],
sizeof(values[value_index]));
10151 attribute = (
void*)((
char*)attribute +
sizeof(float));
10153 case NK_FORMAT_DOUBLE: {
10154 double value = (double)values[value_index];
10155 NK_MEMCPY(attribute, &value,
sizeof(value));
10156 attribute = (
void*)((
char*)attribute +
sizeof(double));
10165 void *result = (
void*)((
char*)dst + config->
vertex_size);
10166 const struct nk_draw_vertex_layout_element *elem_iter = config->
vertex_layout;
10167 while (!nk_draw_vertex_layout_element_is_end_of_layout(elem_iter)) {
10168 void *address = (
void*)((
char*)dst + elem_iter->offset);
10169 switch (elem_iter->attribute) {
10170 case NK_VERTEX_ATTRIBUTE_COUNT:
10171 default: NK_ASSERT(0 &&
"wrong element attribute");
break;
10172 case NK_VERTEX_POSITION: nk_draw_vertex_element(address, &pos.x, 2, elem_iter->format);
break;
10173 case NK_VERTEX_TEXCOORD: nk_draw_vertex_element(address, &uv.x, 2, elem_iter->format);
break;
10174 case NK_VERTEX_COLOR: nk_draw_vertex_color(address, &color.r, elem_iter->format);
break;
10181nk_draw_list_stroke_poly_line(
struct nk_draw_list *list,
const struct nk_vec2 *points,
10182 const unsigned int points_count,
struct nk_color color,
enum nk_draw_list_stroke closed,
10183 float thickness,
enum nk_anti_aliasing aliasing)
10190 if (!list || points_count < 2)
return;
10192 color.a = (nk_byte)((
float)color.a * list->config.global_alpha);
10193 count = points_count;
10194 if (!closed) count = points_count-1;
10195 thick_line = thickness > 1.0f;
10197#ifdef NK_INCLUDE_COMMAND_USERDATA
10198 nk_draw_list_push_userdata(list, list->userdata);
10201 color.a = (nk_byte)((
float)color.a * list->config.global_alpha);
10202 nk_color_fv(&col.r, color);
10206 if (aliasing == NK_ANTI_ALIASING_ON) {
10208 const float AA_SIZE = 1.0f;
10209 NK_STORAGE
const nk_size pnt_align = NK_ALIGNOF(
struct nk_vec2);
10210 NK_STORAGE
const nk_size pnt_size =
sizeof(
struct nk_vec2);
10214 nk_size vertex_offset;
10215 nk_size index = list->vertex_count;
10217 const nk_size idx_count = (thick_line) ? (count * 18) : (count * 12);
10218 const nk_size vtx_count = (thick_line) ? (points_count * 4): (points_count *3);
10220 void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
10221 nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
10224 struct nk_vec2 *normals, *temp;
10225 if (!vtx || !ids)
return;
10228 vertex_offset = (nk_size)((nk_byte*)vtx - (nk_byte*)list->vertices->memory.ptr);
10229 nk_buffer_mark(list->vertices, NK_BUFFER_FRONT);
10230 size = pnt_size * ((thick_line) ? 5 : 3) * points_count;
10231 normals = (
struct nk_vec2*) nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, size, pnt_align);
10232 if (!normals)
return;
10233 temp = normals + points_count;
10236 vtx = (
void*)((nk_byte*)list->vertices->memory.ptr + vertex_offset);
10239 for (i1 = 0; i1 < count; ++i1) {
10240 const nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1);
10241 struct nk_vec2 diff = nk_vec2_sub(points[i2], points[i1]);
10245 len = nk_vec2_len_sqr(diff);
10247 len = NK_INV_SQRT(len);
10250 diff = nk_vec2_muls(diff, len);
10251 normals[i1].x = diff.y;
10252 normals[i1].y = -diff.x;
10256 normals[points_count-1] = normals[points_count-2];
10262 temp[0] = nk_vec2_add(points[0], nk_vec2_muls(normals[0], AA_SIZE));
10263 temp[1] = nk_vec2_sub(points[0], nk_vec2_muls(normals[0], AA_SIZE));
10264 d = nk_vec2_muls(normals[points_count-1], AA_SIZE);
10265 temp[(points_count-1) * 2 + 0] = nk_vec2_add(points[points_count-1], d);
10266 temp[(points_count-1) * 2 + 1] = nk_vec2_sub(points[points_count-1], d);
10271 for (i1 = 0; i1 < count; i1++) {
10274 nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1);
10275 nk_size idx2 = ((i1+1) == points_count) ? index: (idx1 + 3);
10278 dm = nk_vec2_muls(nk_vec2_add(normals[i1], normals[i2]), 0.5f);
10279 dmr2 = dm.x * dm.x + dm.y* dm.y;
10280 if (dmr2 > 0.000001f) {
10281 float scale = 1.0f/dmr2;
10282 scale = NK_MIN(100.0f, scale);
10283 dm = nk_vec2_muls(dm, scale);
10286 dm = nk_vec2_muls(dm, AA_SIZE);
10287 temp[i2*2+0] = nk_vec2_add(points[i2], dm);
10288 temp[i2*2+1] = nk_vec2_sub(points[i2], dm);
10290 ids[0] = (nk_draw_index)(idx2 + 0); ids[1] = (nk_draw_index)(idx1+0);
10291 ids[2] = (nk_draw_index)(idx1 + 2); ids[3] = (nk_draw_index)(idx1+2);
10292 ids[4] = (nk_draw_index)(idx2 + 2); ids[5] = (nk_draw_index)(idx2+0);
10293 ids[6] = (nk_draw_index)(idx2 + 1); ids[7] = (nk_draw_index)(idx1+1);
10294 ids[8] = (nk_draw_index)(idx1 + 0); ids[9] = (nk_draw_index)(idx1+0);
10295 ids[10]= (nk_draw_index)(idx2 + 0); ids[11]= (nk_draw_index)(idx2+1);
10301 for (i = 0; i < points_count; ++i) {
10302 const struct nk_vec2 uv = list->config.tex_null.uv;
10303 vtx = nk_draw_vertex(vtx, &list->config, points[i], uv, col);
10304 vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+0], uv, col_trans);
10305 vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+1], uv, col_trans);
10309 const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f;
10311 struct nk_vec2 d1 = nk_vec2_muls(normals[0], half_inner_thickness + AA_SIZE);
10312 struct nk_vec2 d2 = nk_vec2_muls(normals[0], half_inner_thickness);
10314 temp[0] = nk_vec2_add(points[0], d1);
10315 temp[1] = nk_vec2_add(points[0], d2);
10316 temp[2] = nk_vec2_sub(points[0], d2);
10317 temp[3] = nk_vec2_sub(points[0], d1);
10319 d1 = nk_vec2_muls(normals[points_count-1], half_inner_thickness + AA_SIZE);
10320 d2 = nk_vec2_muls(normals[points_count-1], half_inner_thickness);
10322 temp[(points_count-1)*4+0] = nk_vec2_add(points[points_count-1], d1);
10323 temp[(points_count-1)*4+1] = nk_vec2_add(points[points_count-1], d2);
10324 temp[(points_count-1)*4+2] = nk_vec2_sub(points[points_count-1], d2);
10325 temp[(points_count-1)*4+3] = nk_vec2_sub(points[points_count-1], d1);
10330 for (i1 = 0; i1 < count; ++i1) {
10331 struct nk_vec2 dm_out, dm_in;
10332 const nk_size i2 = ((i1+1) == points_count) ? 0: (i1 + 1);
10333 nk_size idx2 = ((i1+1) == points_count) ? index: (idx1 + 4);
10336 struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(normals[i1], normals[i2]), 0.5f);
10337 float dmr2 = dm.x * dm.x + dm.y* dm.y;
10338 if (dmr2 > 0.000001f) {
10339 float scale = 1.0f/dmr2;
10340 scale = NK_MIN(100.0f, scale);
10341 dm = nk_vec2_muls(dm, scale);
10344 dm_out = nk_vec2_muls(dm, ((half_inner_thickness) + AA_SIZE));
10345 dm_in = nk_vec2_muls(dm, half_inner_thickness);
10346 temp[i2*4+0] = nk_vec2_add(points[i2], dm_out);
10347 temp[i2*4+1] = nk_vec2_add(points[i2], dm_in);
10348 temp[i2*4+2] = nk_vec2_sub(points[i2], dm_in);
10349 temp[i2*4+3] = nk_vec2_sub(points[i2], dm_out);
10352 ids[0] = (nk_draw_index)(idx2 + 1); ids[1] = (nk_draw_index)(idx1+1);
10353 ids[2] = (nk_draw_index)(idx1 + 2); ids[3] = (nk_draw_index)(idx1+2);
10354 ids[4] = (nk_draw_index)(idx2 + 2); ids[5] = (nk_draw_index)(idx2+1);
10355 ids[6] = (nk_draw_index)(idx2 + 1); ids[7] = (nk_draw_index)(idx1+1);
10356 ids[8] = (nk_draw_index)(idx1 + 0); ids[9] = (nk_draw_index)(idx1+0);
10357 ids[10]= (nk_draw_index)(idx2 + 0); ids[11] = (nk_draw_index)(idx2+1);
10358 ids[12]= (nk_draw_index)(idx2 + 2); ids[13] = (nk_draw_index)(idx1+2);
10359 ids[14]= (nk_draw_index)(idx1 + 3); ids[15] = (nk_draw_index)(idx1+3);
10360 ids[16]= (nk_draw_index)(idx2 + 3); ids[17] = (nk_draw_index)(idx2+2);
10366 for (i = 0; i < points_count; ++i) {
10367 const struct nk_vec2 uv = list->config.tex_null.uv;
10368 vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+0], uv, col_trans);
10369 vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+1], uv, col);
10370 vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+2], uv, col);
10371 vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+3], uv, col_trans);
10375 nk_buffer_reset(list->vertices, NK_BUFFER_FRONT);
10379 nk_size idx = list->vertex_count;
10380 const nk_size idx_count = count * 6;
10381 const nk_size vtx_count = count * 4;
10382 void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
10383 nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
10384 if (!vtx || !ids)
return;
10386 for (i1 = 0; i1 < count; ++i1) {
10388 const struct nk_vec2 uv = list->config.tex_null.uv;
10389 const nk_size i2 = ((i1+1) == points_count) ? 0 : i1 + 1;
10390 const struct nk_vec2 p1 = points[i1];
10391 const struct nk_vec2 p2 = points[i2];
10392 struct nk_vec2 diff = nk_vec2_sub(p2, p1);
10396 len = nk_vec2_len_sqr(diff);
10398 len = NK_INV_SQRT(len);
10400 diff = nk_vec2_muls(diff, len);
10403 dx = diff.x * (thickness * 0.5f);
10404 dy = diff.y * (thickness * 0.5f);
10406 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(p1.x + dy, p1.y - dx), uv, col);
10407 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(p2.x + dy, p2.y - dx), uv, col);
10408 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(p2.x - dy, p2.y + dx), uv, col);
10409 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(p1.x - dy, p1.y + dx), uv, col);
10411 ids[0] = (nk_draw_index)(idx+0); ids[1] = (nk_draw_index)(idx+1);
10412 ids[2] = (nk_draw_index)(idx+2); ids[3] = (nk_draw_index)(idx+0);
10413 ids[4] = (nk_draw_index)(idx+2); ids[5] = (nk_draw_index)(idx+3);
10421nk_draw_list_fill_poly_convex(
struct nk_draw_list *list,
10422 const struct nk_vec2 *points,
const unsigned int points_count,
10423 struct nk_color color,
enum nk_anti_aliasing aliasing)
10428 NK_STORAGE
const nk_size pnt_align = NK_ALIGNOF(
struct nk_vec2);
10429 NK_STORAGE
const nk_size pnt_size =
sizeof(
struct nk_vec2);
10431 if (!list || points_count < 3)
return;
10433#ifdef NK_INCLUDE_COMMAND_USERDATA
10434 nk_draw_list_push_userdata(list, list->userdata);
10437 color.a = (nk_byte)((
float)color.a * list->config.global_alpha);
10438 nk_color_fv(&col.r, color);
10442 if (aliasing == NK_ANTI_ALIASING_ON) {
10447 const float AA_SIZE = 1.0f;
10448 nk_size vertex_offset = 0;
10449 nk_size index = list->vertex_count;
10451 const nk_size idx_count = (points_count-2)*3 + points_count*6;
10452 const nk_size vtx_count = (points_count*2);
10454 void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
10455 nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
10459 unsigned int vtx_inner_idx = (
unsigned int)(index + 0);
10460 unsigned int vtx_outer_idx = (
unsigned int)(index + 1);
10461 if (!vtx || !ids)
return;
10464 vertex_offset = (nk_size)((nk_byte*)vtx - (nk_byte*)list->vertices->memory.ptr);
10465 nk_buffer_mark(list->vertices, NK_BUFFER_FRONT);
10466 size = pnt_size * points_count;
10467 normals = (
struct nk_vec2*) nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, size, pnt_align);
10468 if (!normals)
return;
10469 vtx = (
void*)((nk_byte*)list->vertices->memory.ptr + vertex_offset);
10472 for (i = 2; i < points_count; i++) {
10473 ids[0] = (nk_draw_index)(vtx_inner_idx);
10474 ids[1] = (nk_draw_index)(vtx_inner_idx + ((i-1) << 1));
10475 ids[2] = (nk_draw_index)(vtx_inner_idx + (i << 1));
10480 for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) {
10481 struct nk_vec2 p0 = points[i0];
10482 struct nk_vec2 p1 = points[i1];
10483 struct nk_vec2 diff = nk_vec2_sub(p1, p0);
10486 float len = nk_vec2_len_sqr(diff);
10488 len = NK_INV_SQRT(len);
10490 diff = nk_vec2_muls(diff, len);
10492 normals[i0].x = diff.y;
10493 normals[i0].y = -diff.x;
10497 for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) {
10498 const struct nk_vec2 uv = list->config.tex_null.uv;
10499 struct nk_vec2 n0 = normals[i0];
10500 struct nk_vec2 n1 = normals[i1];
10501 struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(n0, n1), 0.5f);
10502 float dmr2 = dm.x*dm.x + dm.y*dm.y;
10503 if (dmr2 > 0.000001f) {
10504 float scale = 1.0f / dmr2;
10505 scale = NK_MIN(scale, 100.0f);
10506 dm = nk_vec2_muls(dm, scale);
10508 dm = nk_vec2_muls(dm, AA_SIZE * 0.5f);
10511 vtx = nk_draw_vertex(vtx, &list->config, nk_vec2_sub(points[i1], dm), uv, col);
10512 vtx = nk_draw_vertex(vtx, &list->config, nk_vec2_add(points[i1], dm), uv, col_trans);
10515 ids[0] = (nk_draw_index)(vtx_inner_idx+(i1<<1));
10516 ids[1] = (nk_draw_index)(vtx_inner_idx+(i0<<1));
10517 ids[2] = (nk_draw_index)(vtx_outer_idx+(i0<<1));
10518 ids[3] = (nk_draw_index)(vtx_outer_idx+(i0<<1));
10519 ids[4] = (nk_draw_index)(vtx_outer_idx+(i1<<1));
10520 ids[5] = (nk_draw_index)(vtx_inner_idx+(i1<<1));
10524 nk_buffer_reset(list->vertices, NK_BUFFER_FRONT);
10527 nk_size index = list->vertex_count;
10528 const nk_size idx_count = (points_count-2)*3;
10529 const nk_size vtx_count = points_count;
10530 void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
10531 nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
10533 if (!vtx || !ids)
return;
10534 for (i = 0; i < vtx_count; ++i)
10535 vtx = nk_draw_vertex(vtx, &list->config, points[i], list->config.tex_null.uv, col);
10536 for (i = 2; i < points_count; ++i) {
10537 ids[0] = (nk_draw_index)index;
10538 ids[1] = (nk_draw_index)(index+ i - 1);
10539 ids[2] = (nk_draw_index)(index+i);
10545nk_draw_list_path_clear(
struct nk_draw_list *list)
10549 nk_buffer_reset(list->buffer, NK_BUFFER_FRONT);
10550 list->path_count = 0;
10551 list->path_offset = 0;
10554nk_draw_list_path_line_to(
struct nk_draw_list *list,
struct nk_vec2 pos)
10557 struct nk_draw_command *cmd = 0;
10560 if (!list->cmd_count)
10561 nk_draw_list_add_clip(list, nk_null_rect);
10563 cmd = nk_draw_list_command_last(list);
10564 if (cmd && cmd->texture.ptr != list->config.tex_null.texture.ptr)
10565 nk_draw_list_push_image(list, list->config.tex_null.texture);
10567 points = nk_draw_list_alloc_path(list, 1);
10568 if (!points)
return;
10572nk_draw_list_path_arc_to_fast(
struct nk_draw_list *list,
struct nk_vec2 center,
10573 float radius,
int a_min,
int a_max)
10578 if (a_min <= a_max) {
10579 for (a = a_min; a <= a_max; a++) {
10580 const struct nk_vec2 c = list->circle_vtx[(nk_size)a % NK_LEN(list->circle_vtx)];
10581 const float x = center.x + c.x * radius;
10582 const float y = center.y + c.y * radius;
10583 nk_draw_list_path_line_to(list,
nk_vec2(x, y));
10588nk_draw_list_path_arc_to(
struct nk_draw_list *list,
struct nk_vec2 center,
10589 float radius,
float a_min,
float a_max,
unsigned int segments)
10591 unsigned int i = 0;
10594 if (radius == 0.0f)
return;
10614 {
const float d_angle = (a_max - a_min) / (
float)segments;
10615 const float sin_d = (float)NK_SIN(d_angle);
10616 const float cos_d = (float)NK_COS(d_angle);
10618 float cx = (float)NK_COS(a_min) * radius;
10619 float cy = (float)NK_SIN(a_min) * radius;
10620 for(i = 0; i <= segments; ++i) {
10621 float new_cx, new_cy;
10622 const float x = center.x + cx;
10623 const float y = center.y + cy;
10624 nk_draw_list_path_line_to(list,
nk_vec2(x, y));
10626 new_cx = cx * cos_d - cy * sin_d;
10627 new_cy = cy * cos_d + cx * sin_d;
10633nk_draw_list_path_rect_to(
struct nk_draw_list *list,
struct nk_vec2 a,
10634 struct nk_vec2 b,
float rounding)
10640 r = NK_MIN(r, ((b.x-a.x) < 0) ? -(b.x-a.x): (b.x-a.x));
10641 r = NK_MIN(r, ((b.y-a.y) < 0) ? -(b.y-a.y): (b.y-a.y));
10644 nk_draw_list_path_line_to(list, a);
10645 nk_draw_list_path_line_to(list,
nk_vec2(b.x,a.y));
10646 nk_draw_list_path_line_to(list, b);
10647 nk_draw_list_path_line_to(list,
nk_vec2(a.x,b.y));
10649 nk_draw_list_path_arc_to_fast(list,
nk_vec2(a.x + r, a.y + r), r, 6, 9);
10650 nk_draw_list_path_arc_to_fast(list,
nk_vec2(b.x - r, a.y + r), r, 9, 12);
10651 nk_draw_list_path_arc_to_fast(list,
nk_vec2(b.x - r, b.y - r), r, 0, 3);
10652 nk_draw_list_path_arc_to_fast(list,
nk_vec2(a.x + r, b.y - r), r, 3, 6);
10656nk_draw_list_path_curve_to(
struct nk_draw_list *list,
struct nk_vec2 p2,
10657 struct nk_vec2 p3,
struct nk_vec2 p4,
unsigned int num_segments)
10660 unsigned int i_step;
10664 NK_ASSERT(list->path_count);
10665 if (!list || !list->path_count)
return;
10666 num_segments = NK_MAX(num_segments, 1);
10668 p1 = nk_draw_list_path_last(list);
10669 t_step = 1.0f/(float)num_segments;
10670 for (i_step = 1; i_step <= num_segments; ++i_step) {
10671 float t = t_step * (float)i_step;
10672 float u = 1.0f - t;
10674 float w2 = 3*u*u*t;
10675 float w3 = 3*u*t*t;
10676 float w4 = t * t *t;
10677 float x = w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x;
10678 float y = w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y;
10679 nk_draw_list_path_line_to(list,
nk_vec2(x,y));
10683nk_draw_list_path_fill(
struct nk_draw_list *list,
struct nk_color color)
10688 points = (
struct nk_vec2*)nk_buffer_memory(list->buffer);
10689 nk_draw_list_fill_poly_convex(list, points, list->path_count, color, list->config.shape_AA);
10690 nk_draw_list_path_clear(list);
10693nk_draw_list_path_stroke(
struct nk_draw_list *list,
struct nk_color color,
10694 enum nk_draw_list_stroke closed,
float thickness)
10699 points = (
struct nk_vec2*)nk_buffer_memory(list->buffer);
10700 nk_draw_list_stroke_poly_line(list, points, list->path_count, color,
10701 closed, thickness, list->config.line_AA);
10702 nk_draw_list_path_clear(list);
10705nk_draw_list_stroke_line(
struct nk_draw_list *list,
struct nk_vec2 a,
10709 if (!list || !col.a)
return;
10710 if (list->line_AA == NK_ANTI_ALIASING_ON) {
10711 nk_draw_list_path_line_to(list, a);
10712 nk_draw_list_path_line_to(list, b);
10714 nk_draw_list_path_line_to(list, nk_vec2_sub(a,
nk_vec2(0.5f,0.5f)));
10715 nk_draw_list_path_line_to(list, nk_vec2_sub(b,
nk_vec2(0.5f,0.5f)));
10717 nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness);
10720nk_draw_list_fill_rect(
struct nk_draw_list *list,
struct nk_rect rect,
10721 struct nk_color col,
float rounding)
10724 if (!list || !col.a)
return;
10726 if (list->line_AA == NK_ANTI_ALIASING_ON) {
10727 nk_draw_list_path_rect_to(list,
nk_vec2(rect.x, rect.y),
10728 nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
10730 nk_draw_list_path_rect_to(list,
nk_vec2(rect.x-0.5f, rect.y-0.5f),
10731 nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
10732 } nk_draw_list_path_fill(list, col);
10735nk_draw_list_stroke_rect(
struct nk_draw_list *list,
struct nk_rect rect,
10736 struct nk_color col,
float rounding,
float thickness)
10739 if (!list || !col.a)
return;
10740 if (list->line_AA == NK_ANTI_ALIASING_ON) {
10741 nk_draw_list_path_rect_to(list,
nk_vec2(rect.x, rect.y),
10742 nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
10744 nk_draw_list_path_rect_to(list,
nk_vec2(rect.x-0.5f, rect.y-0.5f),
10745 nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
10746 } nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
10749nk_draw_list_fill_rect_multi_color(
struct nk_draw_list *list,
struct nk_rect rect,
10755 struct nk_colorf col_right, col_bottom;
10756 nk_draw_index *idx;
10757 nk_draw_index index;
10759 nk_color_fv(&col_left.r, left);
10760 nk_color_fv(&col_right.r, right);
10761 nk_color_fv(&col_top.r, top);
10762 nk_color_fv(&col_bottom.r, bottom);
10767 nk_draw_list_push_image(list, list->config.tex_null.texture);
10768 index = (nk_draw_index)list->vertex_count;
10769 vtx = nk_draw_list_alloc_vertices(list, 4);
10770 idx = nk_draw_list_alloc_elements(list, 6);
10771 if (!vtx || !idx)
return;
10773 idx[0] = (nk_draw_index)(index+0); idx[1] = (nk_draw_index)(index+1);
10774 idx[2] = (nk_draw_index)(index+2); idx[3] = (nk_draw_index)(index+0);
10775 idx[4] = (nk_draw_index)(index+2); idx[5] = (nk_draw_index)(index+3);
10777 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(rect.x, rect.y), list->config.tex_null.uv, col_left);
10778 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(rect.x + rect.w, rect.y), list->config.tex_null.uv, col_top);
10779 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(rect.x + rect.w, rect.y + rect.h), list->config.tex_null.uv, col_right);
10780 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(rect.x, rect.y + rect.h), list->config.tex_null.uv, col_bottom);
10783nk_draw_list_fill_triangle(
struct nk_draw_list *list,
struct nk_vec2 a,
10787 if (!list || !col.a)
return;
10788 nk_draw_list_path_line_to(list, a);
10789 nk_draw_list_path_line_to(list, b);
10790 nk_draw_list_path_line_to(list, c);
10791 nk_draw_list_path_fill(list, col);
10794nk_draw_list_stroke_triangle(
struct nk_draw_list *list,
struct nk_vec2 a,
10798 if (!list || !col.a)
return;
10799 nk_draw_list_path_line_to(list, a);
10800 nk_draw_list_path_line_to(list, b);
10801 nk_draw_list_path_line_to(list, c);
10802 nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
10805nk_draw_list_fill_circle(
struct nk_draw_list *list,
struct nk_vec2 center,
10806 float radius,
struct nk_color col,
unsigned int segs)
10810 if (!list || !col.a)
return;
10811 a_max = NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs;
10812 nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs);
10813 nk_draw_list_path_fill(list, col);
10816nk_draw_list_stroke_circle(
struct nk_draw_list *list,
struct nk_vec2 center,
10817 float radius,
struct nk_color col,
unsigned int segs,
float thickness)
10821 if (!list || !col.a)
return;
10822 a_max = NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs;
10823 nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs);
10824 nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
10827nk_draw_list_stroke_curve(
struct nk_draw_list *list,
struct nk_vec2 p0,
10829 struct nk_color col,
unsigned int segments,
float thickness)
10832 if (!list || !col.a)
return;
10833 nk_draw_list_path_line_to(list, p0);
10834 nk_draw_list_path_curve_to(list, cp0, cp1, p1, segments);
10835 nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness);
10838nk_draw_list_push_rect_uv(
struct nk_draw_list *list,
struct nk_vec2 a,
10849 nk_draw_index *idx;
10850 nk_draw_index index;
10854 nk_color_fv(&col.r, color);
10860 index = (nk_draw_index)list->vertex_count;
10861 vtx = nk_draw_list_alloc_vertices(list, 4);
10862 idx = nk_draw_list_alloc_elements(list, 6);
10863 if (!vtx || !idx)
return;
10865 idx[0] = (nk_draw_index)(index+0); idx[1] = (nk_draw_index)(index+1);
10866 idx[2] = (nk_draw_index)(index+2); idx[3] = (nk_draw_index)(index+0);
10867 idx[4] = (nk_draw_index)(index+2); idx[5] = (nk_draw_index)(index+3);
10869 vtx = nk_draw_vertex(vtx, &list->config, a, uva, col);
10870 vtx = nk_draw_vertex(vtx, &list->config, b, uvb, col);
10871 vtx = nk_draw_vertex(vtx, &list->config, c, uvc, col);
10872 vtx = nk_draw_vertex(vtx, &list->config, d, uvd, col);
10875nk_draw_list_add_image(
struct nk_draw_list *list,
struct nk_image texture,
10881 nk_draw_list_push_image(list, texture.handle);
10882 if (nk_image_is_subimage(&texture)) {
10885 uv[0].x = (float)texture.region[0]/(
float)texture.w;
10886 uv[0].y = (float)texture.region[1]/(
float)texture.h;
10887 uv[1].x = (float)(texture.region[0] + texture.region[2])/(float)texture.w;
10888 uv[1].y = (float)(texture.region[1] + texture.region[3])/(float)texture.h;
10889 nk_draw_list_push_rect_uv(list,
nk_vec2(rect.x, rect.y),
10890 nk_vec2(rect.x + rect.w, rect.y + rect.h), uv[0], uv[1], color);
10891 }
else nk_draw_list_push_rect_uv(list,
nk_vec2(rect.x, rect.y),
10892 nk_vec2(rect.x + rect.w, rect.y + rect.h),
10896nk_draw_list_add_text(
struct nk_draw_list *list,
const struct nk_user_font *font,
10897 struct nk_rect rect,
const char *text,
int len,
float font_height,
10902 nk_rune unicode = 0;
10905 int next_glyph_len = 0;
10906 struct nk_user_font_glyph g;
10909 if (!list || !len || !text)
return;
10910 if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
10911 list->clip_rect.x, list->clip_rect.y, list->clip_rect.w, list->clip_rect.h))
return;
10913 nk_draw_list_push_image(list, font->texture);
10915 glyph_len = nk_utf_decode(text, &unicode, len);
10916 if (!glyph_len)
return;
10919 fg.a = (nk_byte)((
float)fg.a * list->config.global_alpha);
10920 while (text_len < len && glyph_len) {
10921 float gx, gy, gh, gw;
10922 float char_width = 0;
10926 next_glyph_len = nk_utf_decode(text + text_len + glyph_len, &next, (
int)len - text_len);
10927 font->query(font->userdata, font_height, &g, unicode,
10931 gx = x + g.offset.x;
10932 gy = rect.y + g.offset.y;
10933 gw = g.width; gh = g.height;
10934 char_width = g.xadvance;
10935 nk_draw_list_push_rect_uv(list,
nk_vec2(gx,gy),
nk_vec2(gx + gw, gy+ gh),
10936 g.uv[0], g.uv[1], fg);
10939 text_len += glyph_len;
10941 glyph_len = next_glyph_len;
10950 nk_flags res = NK_CONVERT_SUCCESS;
10954 NK_ASSERT(vertices);
10955 NK_ASSERT(elements);
10959 if (!ctx || !cmds || !vertices || !elements || !config || !config->
vertex_layout)
10960 return NK_CONVERT_INVALID_PARAM;
10962 nk_draw_list_setup(&ctx->draw_list, config, cmds, vertices, elements,
10966#ifdef NK_INCLUDE_COMMAND_USERDATA
10967 ctx->draw_list.userdata = cmd->userdata;
10969 switch (cmd->type) {
10970 case NK_COMMAND_NOP:
break;
10971 case NK_COMMAND_SCISSOR: {
10973 nk_draw_list_add_clip(&ctx->draw_list,
nk_rect(s->x, s->y, s->w, s->h));
10975 case NK_COMMAND_LINE: {
10977 nk_draw_list_stroke_line(&ctx->draw_list,
nk_vec2(l->begin.x, l->begin.y),
10978 nk_vec2(l->end.x, l->end.y), l->color, l->line_thickness);
10980 case NK_COMMAND_CURVE: {
10982 nk_draw_list_stroke_curve(&ctx->draw_list,
nk_vec2(q->begin.x, q->begin.y),
10984 q->ctrl[1].y),
nk_vec2(q->end.x, q->end.y), q->color,
10987 case NK_COMMAND_RECT: {
10989 nk_draw_list_stroke_rect(&ctx->draw_list,
nk_rect(r->x, r->y, r->w, r->h),
10990 r->color, (
float)r->rounding, r->line_thickness);
10992 case NK_COMMAND_RECT_FILLED: {
10994 nk_draw_list_fill_rect(&ctx->draw_list,
nk_rect(r->x, r->y, r->w, r->h),
10995 r->color, (
float)r->rounding);
10997 case NK_COMMAND_RECT_MULTI_COLOR: {
10999 nk_draw_list_fill_rect_multi_color(&ctx->draw_list,
nk_rect(r->x, r->y, r->w, r->h),
11000 r->left, r->top, r->right, r->bottom);
11002 case NK_COMMAND_CIRCLE: {
11004 nk_draw_list_stroke_circle(&ctx->draw_list,
nk_vec2((
float)c->x + (
float)c->w/2,
11005 (
float)c->y + (
float)c->h/2), (
float)c->w/2, c->color,
11008 case NK_COMMAND_CIRCLE_FILLED: {
11010 nk_draw_list_fill_circle(&ctx->draw_list,
nk_vec2((
float)c->x + (
float)c->w/2,
11011 (
float)c->y + (
float)c->h/2), (
float)c->w/2, c->color,
11014 case NK_COMMAND_ARC: {
11016 nk_draw_list_path_line_to(&ctx->draw_list,
nk_vec2(c->cx, c->cy));
11017 nk_draw_list_path_arc_to(&ctx->draw_list,
nk_vec2(c->cx, c->cy), c->r,
11019 nk_draw_list_path_stroke(&ctx->draw_list, c->color, NK_STROKE_CLOSED, c->line_thickness);
11021 case NK_COMMAND_ARC_FILLED: {
11023 nk_draw_list_path_line_to(&ctx->draw_list,
nk_vec2(c->cx, c->cy));
11024 nk_draw_list_path_arc_to(&ctx->draw_list,
nk_vec2(c->cx, c->cy), c->r,
11026 nk_draw_list_path_fill(&ctx->draw_list, c->color);
11028 case NK_COMMAND_TRIANGLE: {
11030 nk_draw_list_stroke_triangle(&ctx->draw_list,
nk_vec2(t->a.x, t->a.y),
11032 t->line_thickness);
11034 case NK_COMMAND_TRIANGLE_FILLED: {
11036 nk_draw_list_fill_triangle(&ctx->draw_list,
nk_vec2(t->a.x, t->a.y),
11039 case NK_COMMAND_POLYGON: {
11042 for (i = 0; i < p->point_count; ++i) {
11043 struct nk_vec2 pnt =
nk_vec2((
float)p->points[i].x, (
float)p->points[i].y);
11044 nk_draw_list_path_line_to(&ctx->draw_list, pnt);
11046 nk_draw_list_path_stroke(&ctx->draw_list, p->color, NK_STROKE_CLOSED, p->line_thickness);
11048 case NK_COMMAND_POLYGON_FILLED: {
11051 for (i = 0; i < p->point_count; ++i) {
11052 struct nk_vec2 pnt =
nk_vec2((
float)p->points[i].x, (
float)p->points[i].y);
11053 nk_draw_list_path_line_to(&ctx->draw_list, pnt);
11055 nk_draw_list_path_fill(&ctx->draw_list, p->color);
11057 case NK_COMMAND_POLYLINE: {
11060 for (i = 0; i < p->point_count; ++i) {
11061 struct nk_vec2 pnt =
nk_vec2((
float)p->points[i].x, (
float)p->points[i].y);
11062 nk_draw_list_path_line_to(&ctx->draw_list, pnt);
11064 nk_draw_list_path_stroke(&ctx->draw_list, p->color, NK_STROKE_OPEN, p->line_thickness);
11066 case NK_COMMAND_TEXT: {
11068 nk_draw_list_add_text(&ctx->draw_list, t->font,
nk_rect(t->x, t->y, t->w, t->h),
11069 t->string, t->length, t->height, t->foreground);
11071 case NK_COMMAND_IMAGE: {
11073 nk_draw_list_add_image(&ctx->draw_list, i->img,
nk_rect(i->x, i->y, i->w, i->h), i->col);
11075 case NK_COMMAND_CUSTOM: {
11077 c->callback(&ctx->draw_list, c->x, c->y, c->w, c->h, c->callback_data);
11083 res |= (vertices->
needed > vertices->
allocated) ? NK_CONVERT_VERTEX_BUFFER_FULL: 0;
11084 res |= (elements->
needed > elements->
allocated) ? NK_CONVERT_ELEMENT_BUFFER_FULL: 0;
11087NK_API
const struct nk_draw_command*
11091 return nk__draw_list_begin(&ctx->draw_list, buffer);
11093NK_API
const struct nk_draw_command*
11096 return nk__draw_list_end(&ctx->draw_list, buffer);
11098NK_API
const struct nk_draw_command*
11099nk__draw_next(
const struct nk_draw_command *cmd,
11102 return nk__draw_list_next(cmd, buffer, &ctx->draw_list);
11172#ifndef STB_INCLUDE_STB_RECT_PACK_H
11173#define STB_INCLUDE_STB_RECT_PACK_H
11175#define STB_RECT_PACK_VERSION 1
11178#define STBRP_DEF static
11180#define STBRP_DEF extern
11187typedef struct stbrp_context stbrp_context;
11188typedef struct stbrp_node stbrp_node;
11189typedef struct stbrp_rect stbrp_rect;
11191typedef int stbrp_coord;
11193#define STBRP__MAXVAL 0x7fffffff
11196STBRP_DEF
int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects,
int num_rects);
11236STBRP_DEF
void stbrp_init_target (stbrp_context *context,
int width,
int height, stbrp_node *nodes,
int num_nodes);
11257STBRP_DEF
void stbrp_setup_allow_out_of_mem (stbrp_context *context,
int allow_out_of_mem);
11263STBRP_DEF
void stbrp_setup_heuristic (stbrp_context *context,
int heuristic);
11270 STBRP_HEURISTIC_Skyline_default=0,
11271 STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
11272 STBRP_HEURISTIC_Skyline_BF_sortHeight
11287struct stbrp_context
11295 stbrp_node *active_head;
11296 stbrp_node *free_head;
11297 stbrp_node extra[2];
11311#ifdef STB_RECT_PACK_IMPLEMENTATION
11314#define STBRP_SORT qsort
11317#ifndef STBRP_ASSERT
11319#define STBRP_ASSERT assert
11323#define STBRP__NOTUSED(v) (void)(v)
11324#define STBRP__CDECL __cdecl
11326#define STBRP__NOTUSED(v) (void)sizeof(v)
11327#define STBRP__CDECL
11332 STBRP__INIT_skyline = 1
11335STBRP_DEF
void stbrp_setup_heuristic(stbrp_context *context,
int heuristic)
11337 switch (context->init_mode) {
11338 case STBRP__INIT_skyline:
11339 STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
11340 context->heuristic = heuristic;
11347STBRP_DEF
void stbrp_setup_allow_out_of_mem(stbrp_context *context,
int allow_out_of_mem)
11349 if (allow_out_of_mem)
11354 context->align = 1;
11363 context->align = (context->width + context->num_nodes-1) / context->num_nodes;
11367STBRP_DEF
void stbrp_init_target(stbrp_context *context,
int width,
int height, stbrp_node *nodes,
int num_nodes)
11371 for (i=0; i < num_nodes-1; ++i)
11372 nodes[i].next = &nodes[i+1];
11373 nodes[i].next = NULL;
11374 context->init_mode = STBRP__INIT_skyline;
11375 context->heuristic = STBRP_HEURISTIC_Skyline_default;
11376 context->free_head = &nodes[0];
11377 context->active_head = &context->extra[0];
11378 context->width = width;
11379 context->height = height;
11380 context->num_nodes = num_nodes;
11381 stbrp_setup_allow_out_of_mem(context, 0);
11384 context->extra[0].x = 0;
11385 context->extra[0].y = 0;
11386 context->extra[0].next = &context->extra[1];
11387 context->extra[1].x = (stbrp_coord) width;
11388 context->extra[1].y = (1<<30);
11389 context->extra[1].next = NULL;
11393static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first,
int x0,
int width,
int *pwaste)
11395 stbrp_node *node = first;
11396 int x1 = x0 + width;
11397 int min_y, visited_width, waste_area;
11401 STBRP_ASSERT(first->x <= x0);
11405 while (node->next->x <= x0)
11408 STBRP_ASSERT(node->next->x > x0);
11411 STBRP_ASSERT(node->x <= x0);
11416 while (node->x < x1) {
11417 if (node->y > min_y) {
11421 waste_area += visited_width * (node->y - min_y);
11425 visited_width += node->next->x - x0;
11427 visited_width += node->next->x - node->x;
11430 int under_width = node->next->x - node->x;
11431 if (under_width + visited_width > width)
11432 under_width = width - visited_width;
11433 waste_area += under_width * (min_y - node->y);
11434 visited_width += under_width;
11439 *pwaste = waste_area;
11446 stbrp_node **prev_link;
11447} stbrp__findresult;
11449static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c,
int width,
int height)
11451 int best_waste = (1<<30), best_x, best_y = (1 << 30);
11452 stbrp__findresult fr;
11453 stbrp_node **prev, *node, *tail, **best = NULL;
11456 width = (width + c->align - 1);
11457 width -= width % c->align;
11458 STBRP_ASSERT(width % c->align == 0);
11461 if (width > c->width || height > c->height) {
11462 fr.prev_link = NULL;
11467 node = c->active_head;
11468 prev = &c->active_head;
11469 while (node->x + width <= c->width) {
11471 y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
11472 if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) {
11480 if (y + height <= c->height) {
11482 if (y < best_y || (y == best_y && waste < best_waste)) {
11484 best_waste = waste;
11489 prev = &node->next;
11493 best_x = (best == NULL) ? 0 : (*best)->x;
11512 if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
11513 tail = c->active_head;
11514 node = c->active_head;
11515 prev = &c->active_head;
11517 while (tail->x < width)
11520 int xpos = tail->x - width;
11522 STBRP_ASSERT(xpos >= 0);
11524 while (node->next->x <= xpos) {
11525 prev = &node->next;
11528 STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
11529 y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
11530 if (y + height <= c->height) {
11532 if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
11534 STBRP_ASSERT(y <= best_y);
11536 best_waste = waste;
11545 fr.prev_link = best;
11551static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context,
int width,
int height)
11554 stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
11555 stbrp_node *node, *cur;
11561 if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
11562 res.prev_link = NULL;
11567 node = context->free_head;
11568 node->x = (stbrp_coord) res.x;
11569 node->y = (stbrp_coord) (res.y + height);
11571 context->free_head = node->next;
11577 cur = *res.prev_link;
11578 if (cur->x < res.x) {
11580 stbrp_node *next = cur->next;
11584 *res.prev_link = node;
11589 while (cur->next && cur->next->x <= res.x + width) {
11590 stbrp_node *next = cur->next;
11592 cur->next = context->free_head;
11593 context->free_head = cur;
11600 if (cur->x < res.x + width)
11601 cur->x = (stbrp_coord) (res.x + width);
11604 cur = context->active_head;
11605 while (cur->x < context->width) {
11606 STBRP_ASSERT(cur->x < cur->next->x);
11609 STBRP_ASSERT(cur->next == NULL);
11613 cur = context->active_head;
11618 cur = context->free_head;
11623 STBRP_ASSERT(count == context->num_nodes+2);
11630static int STBRP__CDECL rect_height_compare(
const void *a,
const void *b)
11632 const stbrp_rect *p = (
const stbrp_rect *) a;
11633 const stbrp_rect *q = (
const stbrp_rect *) b;
11638 return (p->w > q->w) ? -1 : (p->w < q->w);
11641static int STBRP__CDECL rect_original_order(
const void *a,
const void *b)
11643 const stbrp_rect *p = (
const stbrp_rect *) a;
11644 const stbrp_rect *q = (
const stbrp_rect *) b;
11645 return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
11648STBRP_DEF
int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects,
int num_rects)
11650 int i, all_rects_packed = 1;
11653 for (i=0; i < num_rects; ++i) {
11654 rects[i].was_packed = i;
11658 STBRP_SORT(rects, num_rects,
sizeof(rects[0]), rect_height_compare);
11660 for (i=0; i < num_rects; ++i) {
11661 if (rects[i].w == 0 || rects[i].h == 0) {
11662 rects[i].x = rects[i].y = 0;
11664 stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
11665 if (fr.prev_link) {
11666 rects[i].x = (stbrp_coord) fr.x;
11667 rects[i].y = (stbrp_coord) fr.y;
11669 rects[i].x = rects[i].y = STBRP__MAXVAL;
11675 STBRP_SORT(rects, num_rects,
sizeof(rects[0]), rect_original_order);
11678 for (i=0; i < num_rects; ++i) {
11679 rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
11680 if (!rects[i].was_packed)
11681 all_rects_packed = 0;
11685 return all_rects_packed;
12008#define STB_TRUETYPE_IMPLEMENTATION
12009#include "stb_truetype.h"
12011unsigned char ttf_buffer[1<<20];
12012unsigned char temp_bitmap[512*512];
12014stbtt_bakedchar cdata[96];
12017void my_stbtt_initfont(
void)
12019 fread(ttf_buffer, 1, 1<<20, fopen(
"c:/windows/fonts/times.ttf",
"rb"));
12020 stbtt_BakeFontBitmap(ttf_buffer,0, 32.0, temp_bitmap,512,512, 32,96, cdata);
12022 glGenTextures(1, &ftex);
12023 glBindTexture(GL_TEXTURE_2D, ftex);
12024 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512,512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap);
12026 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
12029void my_stbtt_print(
float x,
float y,
char *text)
12032 glEnable(GL_BLEND);
12033 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
12034 glEnable(GL_TEXTURE_2D);
12035 glBindTexture(GL_TEXTURE_2D, ftex);
12038 if (*text >= 32 && *text < 128) {
12039 stbtt_aligned_quad q;
12040 stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);
12041 glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y0);
12042 glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y0);
12043 glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y1);
12044 glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y1);
12059#define STB_TRUETYPE_IMPLEMENTATION
12060#include "stb_truetype.h"
12062char ttf_buffer[1<<25];
12064int main(
int argc,
char **argv)
12066 stbtt_fontinfo font;
12067 unsigned char *bitmap;
12068 int w,h,i,j,c = (argc > 1 ? atoi(argv[1]) :
'a'), s = (argc > 2 ? atoi(argv[2]) : 20);
12070 fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] :
"c:/windows/fonts/arialbd.ttf",
"rb"));
12072 stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0));
12073 bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), c, &w, &h, 0,0);
12075 for (j=0; j < h; ++j) {
12076 for (i=0; i < w; ++i)
12077 putchar(
" .:ioVM@"[bitmap[j*w+i]>>5]);
12102char buffer[24<<20];
12103unsigned char screen[20][79];
12105int main(
int arg,
char **argv)
12107 stbtt_fontinfo font;
12108 int i,j,ascent,baseline,ch=0;
12109 float scale, xpos=2;
12110 char *text =
"Heljo World!";
12112 fread(buffer, 1, 1000000, fopen(
"c:/windows/fonts/arialbd.ttf",
"rb"));
12113 stbtt_InitFont(&font, buffer, 0);
12115 scale = stbtt_ScaleForPixelHeight(&font, 15);
12116 stbtt_GetFontVMetrics(&font, &ascent,0,0);
12117 baseline = (int) (ascent*scale);
12120 int advance,lsb,x0,y0,x1,y1;
12121 float x_shift = xpos - (float) floor(xpos);
12122 stbtt_GetCodepointHMetrics(&font, text[ch], &advance, &lsb);
12123 stbtt_GetCodepointBitmapBoxSubpixel(&font, text[ch], scale,scale,x_shift,0, &x0,&y0,&x1,&y1);
12124 stbtt_MakeCodepointBitmapSubpixel(&font, &screen[baseline + y0][(
int) xpos + x0], x1-x0,y1-y0, 79, scale,scale,x_shift,0, text[ch]);
12129 xpos += (advance * scale);
12131 xpos += scale*stbtt_GetCodepointKernAdvance(&font, text[ch],text[ch+1]);
12135 for (j=0; j < 20; ++j) {
12136 for (i=0; i < 78; ++i)
12137 putchar(
" .:ioVM@"[screen[j][i]>>5]);
12155#ifdef STB_TRUETYPE_IMPLEMENTATION
12157 #ifndef stbtt_uint8
12158 typedef unsigned char stbtt_uint8;
12159 typedef signed char stbtt_int8;
12160 typedef unsigned short stbtt_uint16;
12161 typedef signed short stbtt_int16;
12162 typedef unsigned int stbtt_uint32;
12163 typedef signed int stbtt_int32;
12166 typedef char stbtt__check_size32[
sizeof(stbtt_int32)==4 ? 1 : -1];
12167 typedef char stbtt__check_size16[
sizeof(stbtt_int16)==2 ? 1 : -1];
12170 #ifndef STBTT_ifloor
12172 #define STBTT_ifloor(x) ((int) floor(x))
12173 #define STBTT_iceil(x) ((int) ceil(x))
12178 #define STBTT_sqrt(x) sqrt(x)
12179 #define STBTT_pow(x,y) pow(x,y)
12184 #define STBTT_fmod(x,y) fmod(x,y)
12189 #define STBTT_cos(x) cos(x)
12190 #define STBTT_acos(x) acos(x)
12195 #define STBTT_fabs(x) fabs(x)
12199 #ifndef STBTT_malloc
12200 #include <stdlib.h>
12201 #define STBTT_malloc(x,u) ((void)(u),malloc(x))
12202 #define STBTT_free(x,u) ((void)(u),free(x))
12205 #ifndef STBTT_assert
12206 #include <assert.h>
12207 #define STBTT_assert(x) assert(x)
12210 #ifndef STBTT_strlen
12211 #include <string.h>
12212 #define STBTT_strlen(x) strlen(x)
12215 #ifndef STBTT_memcpy
12216 #include <string.h>
12217 #define STBTT_memcpy memcpy
12218 #define STBTT_memset memset
12229#ifndef __STB_INCLUDE_STB_TRUETYPE_H__
12230#define __STB_INCLUDE_STB_TRUETYPE_H__
12233#define STBTT_DEF static
12235#define STBTT_DEF extern
12245 unsigned char *data;
12259 unsigned short x0,y0,x1,y1;
12260 float xoff,yoff,xadvance;
12263STBTT_DEF
int stbtt_BakeFontBitmap(
const unsigned char *data,
int offset,
12264 float pixel_height,
12265 unsigned char *pixels,
int pw,
int ph,
12266 int first_char,
int num_chars,
12267 stbtt_bakedchar *chardata);
12277} stbtt_aligned_quad;
12279STBTT_DEF
void stbtt_GetBakedQuad(
const stbtt_bakedchar *chardata,
int pw,
int ph,
12281 float *xpos,
float *ypos,
12282 stbtt_aligned_quad *q,
12283 int opengl_fillrule);
12294STBTT_DEF
void stbtt_GetScaledFontVMetrics(
const unsigned char *fontdata,
int index,
float size,
float *ascent,
float *descent,
float *lineGap);
12307 unsigned short x0,y0,x1,y1;
12308 float xoff,yoff,xadvance;
12312typedef struct stbtt_pack_context stbtt_pack_context;
12313typedef struct stbtt_fontinfo stbtt_fontinfo;
12314#ifndef STB_RECT_PACK_VERSION
12315typedef struct stbrp_rect stbrp_rect;
12318STBTT_DEF
int stbtt_PackBegin(stbtt_pack_context *spc,
unsigned char *pixels,
int width,
int height,
int stride_in_bytes,
int padding,
void *alloc_context);
12329STBTT_DEF
void stbtt_PackEnd (stbtt_pack_context *spc);
12332#define STBTT_POINT_SIZE(x) (-(x))
12334STBTT_DEF
int stbtt_PackFontRange(stbtt_pack_context *spc,
const unsigned char *fontdata,
int font_index,
float font_size,
12335 int first_unicode_char_in_range,
int num_chars_in_range, stbtt_packedchar *chardata_for_range);
12352 int first_unicode_codepoint_in_range;
12353 int *array_of_unicode_codepoints;
12355 stbtt_packedchar *chardata_for_range;
12356 unsigned char h_oversample, v_oversample;
12359STBTT_DEF
int stbtt_PackFontRanges(stbtt_pack_context *spc,
const unsigned char *fontdata,
int font_index, stbtt_pack_range *ranges,
int num_ranges);
12365STBTT_DEF
void stbtt_PackSetOversampling(stbtt_pack_context *spc,
unsigned int h_oversample,
unsigned int v_oversample);
12381STBTT_DEF
void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc,
int skip);
12387STBTT_DEF
void stbtt_GetPackedQuad(
const stbtt_packedchar *chardata,
int pw,
int ph,
12389 float *xpos,
float *ypos,
12390 stbtt_aligned_quad *q,
12391 int align_to_integer);
12393STBTT_DEF
int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc,
const stbtt_fontinfo *info, stbtt_pack_range *ranges,
int num_ranges, stbrp_rect *rects);
12394STBTT_DEF
void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects,
int num_rects);
12395STBTT_DEF
int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc,
const stbtt_fontinfo *info, stbtt_pack_range *ranges,
int num_ranges, stbrp_rect *rects);
12408struct stbtt_pack_context {
12409 void *user_allocator_context;
12413 int stride_in_bytes;
12416 unsigned int h_oversample, v_oversample;
12417 unsigned char *pixels;
12427STBTT_DEF
int stbtt_GetNumberOfFonts(
const unsigned char *data);
12434STBTT_DEF
int stbtt_GetFontOffsetForIndex(
const unsigned char *data,
int index);
12443struct stbtt_fontinfo
12446 unsigned char * data;
12451 int loca,head,glyf,hhea,hmtx,kern,gpos,svg;
12453 int indexToLocFormat;
12456 stbtt__buf charstrings;
12459 stbtt__buf fontdicts;
12460 stbtt__buf fdselect;
12463STBTT_DEF
int stbtt_InitFont(stbtt_fontinfo *info,
const unsigned char *data,
int offset);
12475STBTT_DEF
int stbtt_FindGlyphIndex(
const stbtt_fontinfo *info,
int unicode_codepoint);
12488STBTT_DEF
float stbtt_ScaleForPixelHeight(
const stbtt_fontinfo *info,
float pixels);
12496STBTT_DEF
float stbtt_ScaleForMappingEmToPixels(
const stbtt_fontinfo *info,
float pixels);
12501STBTT_DEF
void stbtt_GetFontVMetrics(
const stbtt_fontinfo *info,
int *ascent,
int *descent,
int *lineGap);
12509STBTT_DEF
int stbtt_GetFontVMetricsOS2(
const stbtt_fontinfo *info,
int *typoAscent,
int *typoDescent,
int *typoLineGap);
12515STBTT_DEF
void stbtt_GetFontBoundingBox(
const stbtt_fontinfo *info,
int *x0,
int *y0,
int *x1,
int *y1);
12518STBTT_DEF
void stbtt_GetCodepointHMetrics(
const stbtt_fontinfo *info,
int codepoint,
int *advanceWidth,
int *leftSideBearing);
12523STBTT_DEF
int stbtt_GetCodepointKernAdvance(
const stbtt_fontinfo *info,
int ch1,
int ch2);
12526STBTT_DEF
int stbtt_GetCodepointBox(
const stbtt_fontinfo *info,
int codepoint,
int *x0,
int *y0,
int *x1,
int *y1);
12529STBTT_DEF
void stbtt_GetGlyphHMetrics(
const stbtt_fontinfo *info,
int glyph_index,
int *advanceWidth,
int *leftSideBearing);
12530STBTT_DEF
int stbtt_GetGlyphKernAdvance(
const stbtt_fontinfo *info,
int glyph1,
int glyph2);
12531STBTT_DEF
int stbtt_GetGlyphBox(
const stbtt_fontinfo *info,
int glyph_index,
int *x0,
int *y0,
int *x1,
int *y1);
12534typedef struct stbtt_kerningentry
12539} stbtt_kerningentry;
12541STBTT_DEF
int stbtt_GetKerningTableLength(
const stbtt_fontinfo *info);
12542STBTT_DEF
int stbtt_GetKerningTable(
const stbtt_fontinfo *info, stbtt_kerningentry* table,
int table_length);
12562#ifndef stbtt_vertex
12564 #define stbtt_vertex_type short
12567 stbtt_vertex_type x,y,cx,cy,cx1,cy1;
12568 unsigned char type,padding;
12572STBTT_DEF
int stbtt_IsGlyphEmpty(
const stbtt_fontinfo *info,
int glyph_index);
12575STBTT_DEF
int stbtt_GetCodepointShape(
const stbtt_fontinfo *info,
int unicode_codepoint, stbtt_vertex **vertices);
12576STBTT_DEF
int stbtt_GetGlyphShape(
const stbtt_fontinfo *info,
int glyph_index, stbtt_vertex **vertices);
12587STBTT_DEF
void stbtt_FreeShape(
const stbtt_fontinfo *info, stbtt_vertex *vertices);
12590STBTT_DEF
unsigned char *stbtt_FindSVGDoc(
const stbtt_fontinfo *info,
int gl);
12591STBTT_DEF
int stbtt_GetCodepointSVG(
const stbtt_fontinfo *info,
int unicode_codepoint,
const char **svg);
12592STBTT_DEF
int stbtt_GetGlyphSVG(
const stbtt_fontinfo *info,
int gl,
const char **svg);
12601STBTT_DEF
void stbtt_FreeBitmap(
unsigned char *bitmap,
void *userdata);
12604STBTT_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);
12613STBTT_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);
12617STBTT_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);
12623STBTT_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);
12627STBTT_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);
12631STBTT_DEF
void stbtt_GetCodepointBitmapBox(
const stbtt_fontinfo *font,
int codepoint,
float scale_x,
float scale_y,
int *ix0,
int *iy0,
int *ix1,
int *iy1);
12638STBTT_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);
12644STBTT_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);
12645STBTT_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);
12646STBTT_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);
12647STBTT_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);
12648STBTT_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);
12649STBTT_DEF
void stbtt_GetGlyphBitmapBox(
const stbtt_fontinfo *font,
int glyph,
float scale_x,
float scale_y,
int *ix0,
int *iy0,
int *ix1,
int *iy1);
12650STBTT_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);
12657 unsigned char *pixels;
12661STBTT_DEF
void stbtt_Rasterize(stbtt__bitmap *result,
12662 float flatness_in_pixels,
12663 stbtt_vertex *vertices,
12665 float scale_x,
float scale_y,
12666 float shift_x,
float shift_y,
12667 int x_off,
int y_off,
12675STBTT_DEF
void stbtt_FreeSDF(
unsigned char *bitmap,
void *userdata);
12678STBTT_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);
12679STBTT_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);
12751STBTT_DEF
int stbtt_FindMatchingFont(
const unsigned char *fontdata,
const char *name,
int flags);
12756#define STBTT_MACSTYLE_DONTCARE 0
12757#define STBTT_MACSTYLE_BOLD 1
12758#define STBTT_MACSTYLE_ITALIC 2
12759#define STBTT_MACSTYLE_UNDERSCORE 4
12760#define STBTT_MACSTYLE_NONE 8
12762STBTT_DEF
int stbtt_CompareUTF8toUTF16_bigendian(
const char *s1,
int len1,
const char *s2,
int len2);
12766STBTT_DEF
const char *stbtt_GetFontNameString(
const stbtt_fontinfo *font,
int *length,
int platformID,
int encodingID,
int languageID,
int nameID);
12775 STBTT_PLATFORM_ID_UNICODE =0,
12776 STBTT_PLATFORM_ID_MAC =1,
12777 STBTT_PLATFORM_ID_ISO =2,
12778 STBTT_PLATFORM_ID_MICROSOFT =3
12782 STBTT_UNICODE_EID_UNICODE_1_0 =0,
12783 STBTT_UNICODE_EID_UNICODE_1_1 =1,
12784 STBTT_UNICODE_EID_ISO_10646 =2,
12785 STBTT_UNICODE_EID_UNICODE_2_0_BMP=3,
12786 STBTT_UNICODE_EID_UNICODE_2_0_FULL=4
12790 STBTT_MS_EID_SYMBOL =0,
12791 STBTT_MS_EID_UNICODE_BMP =1,
12792 STBTT_MS_EID_SHIFTJIS =2,
12793 STBTT_MS_EID_UNICODE_FULL =10
12797 STBTT_MAC_EID_ROMAN =0, STBTT_MAC_EID_ARABIC =4,
12798 STBTT_MAC_EID_JAPANESE =1, STBTT_MAC_EID_HEBREW =5,
12799 STBTT_MAC_EID_CHINESE_TRAD =2, STBTT_MAC_EID_GREEK =6,
12800 STBTT_MAC_EID_KOREAN =3, STBTT_MAC_EID_RUSSIAN =7
12805 STBTT_MS_LANG_ENGLISH =0x0409, STBTT_MS_LANG_ITALIAN =0x0410,
12806 STBTT_MS_LANG_CHINESE =0x0804, STBTT_MS_LANG_JAPANESE =0x0411,
12807 STBTT_MS_LANG_DUTCH =0x0413, STBTT_MS_LANG_KOREAN =0x0412,
12808 STBTT_MS_LANG_FRENCH =0x040c, STBTT_MS_LANG_RUSSIAN =0x0419,
12809 STBTT_MS_LANG_GERMAN =0x0407, STBTT_MS_LANG_SPANISH =0x0409,
12810 STBTT_MS_LANG_HEBREW =0x040d, STBTT_MS_LANG_SWEDISH =0x041D
12814 STBTT_MAC_LANG_ENGLISH =0 , STBTT_MAC_LANG_JAPANESE =11,
12815 STBTT_MAC_LANG_ARABIC =12, STBTT_MAC_LANG_KOREAN =23,
12816 STBTT_MAC_LANG_DUTCH =4 , STBTT_MAC_LANG_RUSSIAN =32,
12817 STBTT_MAC_LANG_FRENCH =1 , STBTT_MAC_LANG_SPANISH =6 ,
12818 STBTT_MAC_LANG_GERMAN =2 , STBTT_MAC_LANG_SWEDISH =5 ,
12819 STBTT_MAC_LANG_HEBREW =10, STBTT_MAC_LANG_CHINESE_SIMPLIFIED =33,
12820 STBTT_MAC_LANG_ITALIAN =3 , STBTT_MAC_LANG_CHINESE_TRAD =19
12836#ifdef STB_TRUETYPE_IMPLEMENTATION
12838#ifndef STBTT_MAX_OVERSAMPLE
12839#define STBTT_MAX_OVERSAMPLE 8
12842#if STBTT_MAX_OVERSAMPLE > 255
12843#error "STBTT_MAX_OVERSAMPLE cannot be > 255"
12846typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE-1)) == 0 ? 1 : -1];
12848#ifndef STBTT_RASTERIZER_VERSION
12849#define STBTT_RASTERIZER_VERSION 2
12853#define STBTT__NOTUSED(v) (void)(v)
12855#define STBTT__NOTUSED(v) (void)sizeof(v)
12863static stbtt_uint8 stbtt__buf_get8(stbtt__buf *b)
12865 if (b->cursor >= b->size)
12867 return b->data[b->cursor++];
12870static stbtt_uint8 stbtt__buf_peek8(stbtt__buf *b)
12872 if (b->cursor >= b->size)
12874 return b->data[b->cursor];
12877static void stbtt__buf_seek(stbtt__buf *b,
int o)
12879 STBTT_assert(!(o > b->size || o < 0));
12880 b->cursor = (o > b->size || o < 0) ? b->size : o;
12883static void stbtt__buf_skip(stbtt__buf *b,
int o)
12885 stbtt__buf_seek(b, b->cursor + o);
12888static stbtt_uint32 stbtt__buf_get(stbtt__buf *b,
int n)
12890 stbtt_uint32 v = 0;
12892 STBTT_assert(n >= 1 && n <= 4);
12893 for (i = 0; i < n; i++)
12894 v = (v << 8) | stbtt__buf_get8(b);
12898static stbtt__buf stbtt__new_buf(
const void *p,
size_t size)
12901 STBTT_assert(size < 0x40000000);
12902 r.data = (stbtt_uint8*) p;
12903 r.size = (int) size;
12908#define stbtt__buf_get16(b) stbtt__buf_get((b), 2)
12909#define stbtt__buf_get32(b) stbtt__buf_get((b), 4)
12911static stbtt__buf stbtt__buf_range(
const stbtt__buf *b,
int o,
int s)
12913 stbtt__buf r = stbtt__new_buf(NULL, 0);
12914 if (o < 0 || s < 0 || o > b->size || s > b->size - o)
return r;
12915 r.data = b->data + o;
12920static stbtt__buf stbtt__cff_get_index(stbtt__buf *b)
12922 int count, start, offsize;
12924 count = stbtt__buf_get16(b);
12926 offsize = stbtt__buf_get8(b);
12927 STBTT_assert(offsize >= 1 && offsize <= 4);
12928 stbtt__buf_skip(b, offsize * count);
12929 stbtt__buf_skip(b, stbtt__buf_get(b, offsize) - 1);
12931 return stbtt__buf_range(b, start, b->cursor - start);
12934static stbtt_uint32 stbtt__cff_int(stbtt__buf *b)
12936 int b0 = stbtt__buf_get8(b);
12937 if (b0 >= 32 && b0 <= 246)
return b0 - 139;
12938 else if (b0 >= 247 && b0 <= 250)
return (b0 - 247)*256 + stbtt__buf_get8(b) + 108;
12939 else if (b0 >= 251 && b0 <= 254)
return -(b0 - 251)*256 - stbtt__buf_get8(b) - 108;
12940 else if (b0 == 28)
return stbtt__buf_get16(b);
12941 else if (b0 == 29)
return stbtt__buf_get32(b);
12946static void stbtt__cff_skip_operand(stbtt__buf *b) {
12947 int v, b0 = stbtt__buf_peek8(b);
12948 STBTT_assert(b0 >= 28);
12950 stbtt__buf_skip(b, 1);
12951 while (b->cursor < b->size) {
12952 v = stbtt__buf_get8(b);
12953 if ((v & 0xF) == 0xF || (v >> 4) == 0xF)
12961static stbtt__buf stbtt__dict_get(stbtt__buf *b,
int key)
12963 stbtt__buf_seek(b, 0);
12964 while (b->cursor < b->size) {
12965 int start = b->cursor, end, op;
12966 while (stbtt__buf_peek8(b) >= 28)
12967 stbtt__cff_skip_operand(b);
12969 op = stbtt__buf_get8(b);
12970 if (op == 12) op = stbtt__buf_get8(b) | 0x100;
12971 if (op == key)
return stbtt__buf_range(b, start, end-start);
12973 return stbtt__buf_range(b, 0, 0);
12976static void stbtt__dict_get_ints(stbtt__buf *b,
int key,
int outcount, stbtt_uint32 *out)
12979 stbtt__buf operands = stbtt__dict_get(b, key);
12980 for (i = 0; i < outcount && operands.cursor < operands.size; i++)
12981 out[i] = stbtt__cff_int(&operands);
12984static int stbtt__cff_index_count(stbtt__buf *b)
12986 stbtt__buf_seek(b, 0);
12987 return stbtt__buf_get16(b);
12990static stbtt__buf stbtt__cff_index_get(stbtt__buf b,
int i)
12992 int count, offsize, start, end;
12993 stbtt__buf_seek(&b, 0);
12994 count = stbtt__buf_get16(&b);
12995 offsize = stbtt__buf_get8(&b);
12996 STBTT_assert(i >= 0 && i < count);
12997 STBTT_assert(offsize >= 1 && offsize <= 4);
12998 stbtt__buf_skip(&b, i*offsize);
12999 start = stbtt__buf_get(&b, offsize);
13000 end = stbtt__buf_get(&b, offsize);
13001 return stbtt__buf_range(&b, 2+(count+1)*offsize+start, end - start);
13012#define ttBYTE(p) (* (stbtt_uint8 *) (p))
13013#define ttCHAR(p) (* (stbtt_int8 *) (p))
13014#define ttFixed(p) ttLONG(p)
13016static stbtt_uint16 ttUSHORT(stbtt_uint8 *p) {
return p[0]*256 + p[1]; }
13017static stbtt_int16 ttSHORT(stbtt_uint8 *p) {
return p[0]*256 + p[1]; }
13018static stbtt_uint32 ttULONG(stbtt_uint8 *p) {
return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
13019static stbtt_int32 ttLONG(stbtt_uint8 *p) {
return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
13021#define stbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3))
13022#define stbtt_tag(p,str) stbtt_tag4(p,str[0],str[1],str[2],str[3])
13024static int stbtt__isfont(stbtt_uint8 *font)
13027 if (stbtt_tag4(font,
'1',0,0,0))
return 1;
13028 if (stbtt_tag(font,
"typ1"))
return 1;
13029 if (stbtt_tag(font,
"OTTO"))
return 1;
13030 if (stbtt_tag4(font, 0,1,0,0))
return 1;
13031 if (stbtt_tag(font,
"true"))
return 1;
13036static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart,
const char *tag)
13038 stbtt_int32 num_tables = ttUSHORT(data+fontstart+4);
13039 stbtt_uint32 tabledir = fontstart + 12;
13041 for (i=0; i < num_tables; ++i) {
13042 stbtt_uint32 loc = tabledir + 16*i;
13043 if (stbtt_tag(data+loc+0, tag))
13044 return ttULONG(data+loc+8);
13049static int stbtt_GetFontOffsetForIndex_internal(
unsigned char *font_collection,
int index)
13052 if (stbtt__isfont(font_collection))
13053 return index == 0 ? 0 : -1;
13056 if (stbtt_tag(font_collection,
"ttcf")) {
13058 if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) {
13059 stbtt_int32 n = ttLONG(font_collection+8);
13062 return ttULONG(font_collection+12+index*4);
13068static int stbtt_GetNumberOfFonts_internal(
unsigned char *font_collection)
13071 if (stbtt__isfont(font_collection))
13075 if (stbtt_tag(font_collection,
"ttcf")) {
13077 if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) {
13078 return ttLONG(font_collection+8);
13084static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict)
13086 stbtt_uint32 subrsoff = 0, private_loc[2] = { 0, 0 };
13088 stbtt__dict_get_ints(&fontdict, 18, 2, private_loc);
13089 if (!private_loc[1] || !private_loc[0])
return stbtt__new_buf(NULL, 0);
13090 pdict = stbtt__buf_range(&cff, private_loc[1], private_loc[0]);
13091 stbtt__dict_get_ints(&pdict, 19, 1, &subrsoff);
13092 if (!subrsoff)
return stbtt__new_buf(NULL, 0);
13093 stbtt__buf_seek(&cff, private_loc[1]+subrsoff);
13094 return stbtt__cff_get_index(&cff);
13098static int stbtt__get_svg(stbtt_fontinfo *info)
13101 if (info->svg < 0) {
13102 t = stbtt__find_table(info->data, info->fontstart,
"SVG ");
13104 stbtt_uint32 offset = ttULONG(info->data + t + 2);
13105 info->svg = t + offset;
13113static int stbtt_InitFont_internal(stbtt_fontinfo *info,
unsigned char *data,
int fontstart)
13115 stbtt_uint32 cmap, t;
13116 stbtt_int32 i,numTables;
13119 info->fontstart = fontstart;
13120 info->cff = stbtt__new_buf(NULL, 0);
13122 cmap = stbtt__find_table(data, fontstart,
"cmap");
13123 info->loca = stbtt__find_table(data, fontstart,
"loca");
13124 info->head = stbtt__find_table(data, fontstart,
"head");
13125 info->glyf = stbtt__find_table(data, fontstart,
"glyf");
13126 info->hhea = stbtt__find_table(data, fontstart,
"hhea");
13127 info->hmtx = stbtt__find_table(data, fontstart,
"hmtx");
13128 info->kern = stbtt__find_table(data, fontstart,
"kern");
13129 info->gpos = stbtt__find_table(data, fontstart,
"GPOS");
13131 if (!cmap || !info->head || !info->hhea || !info->hmtx)
13135 if (!info->loca)
return 0;
13138 stbtt__buf b, topdict, topdictidx;
13139 stbtt_uint32 cstype = 2, charstrings = 0, fdarrayoff = 0, fdselectoff = 0;
13142 cff = stbtt__find_table(data, fontstart,
"CFF ");
13143 if (!cff)
return 0;
13145 info->fontdicts = stbtt__new_buf(NULL, 0);
13146 info->fdselect = stbtt__new_buf(NULL, 0);
13149 info->cff = stbtt__new_buf(data+cff, 512*1024*1024);
13153 stbtt__buf_skip(&b, 2);
13154 stbtt__buf_seek(&b, stbtt__buf_get8(&b));
13158 stbtt__cff_get_index(&b);
13159 topdictidx = stbtt__cff_get_index(&b);
13160 topdict = stbtt__cff_index_get(topdictidx, 0);
13161 stbtt__cff_get_index(&b);
13162 info->gsubrs = stbtt__cff_get_index(&b);
13164 stbtt__dict_get_ints(&topdict, 17, 1, &charstrings);
13165 stbtt__dict_get_ints(&topdict, 0x100 | 6, 1, &cstype);
13166 stbtt__dict_get_ints(&topdict, 0x100 | 36, 1, &fdarrayoff);
13167 stbtt__dict_get_ints(&topdict, 0x100 | 37, 1, &fdselectoff);
13168 info->subrs = stbtt__get_subrs(b, topdict);
13171 if (cstype != 2)
return 0;
13172 if (charstrings == 0)
return 0;
13176 if (!fdselectoff)
return 0;
13177 stbtt__buf_seek(&b, fdarrayoff);
13178 info->fontdicts = stbtt__cff_get_index(&b);
13179 info->fdselect = stbtt__buf_range(&b, fdselectoff, b.size-fdselectoff);
13182 stbtt__buf_seek(&b, charstrings);
13183 info->charstrings = stbtt__cff_get_index(&b);
13186 t = stbtt__find_table(data, fontstart,
"maxp");
13188 info->numGlyphs = ttUSHORT(data+t+4);
13190 info->numGlyphs = 0xffff;
13197 numTables = ttUSHORT(data + cmap + 2);
13198 info->index_map = 0;
13199 for (i=0; i < numTables; ++i) {
13200 stbtt_uint32 encoding_record = cmap + 4 + 8 * i;
13202 switch(ttUSHORT(data+encoding_record)) {
13203 case STBTT_PLATFORM_ID_MICROSOFT:
13204 switch (ttUSHORT(data+encoding_record+2)) {
13205 case STBTT_MS_EID_UNICODE_BMP:
13206 case STBTT_MS_EID_UNICODE_FULL:
13208 info->index_map = cmap + ttULONG(data+encoding_record+4);
13212 case STBTT_PLATFORM_ID_UNICODE:
13215 info->index_map = cmap + ttULONG(data+encoding_record+4);
13219 if (info->index_map == 0)
13222 info->indexToLocFormat = ttUSHORT(data+info->head + 50);
13226STBTT_DEF
int stbtt_FindGlyphIndex(
const stbtt_fontinfo *info,
int unicode_codepoint)
13228 stbtt_uint8 *data = info->data;
13229 stbtt_uint32 index_map = info->index_map;
13231 stbtt_uint16 format = ttUSHORT(data + index_map + 0);
13233 stbtt_int32 bytes = ttUSHORT(data + index_map + 2);
13234 if (unicode_codepoint < bytes-6)
13235 return ttBYTE(data + index_map + 6 + unicode_codepoint);
13237 }
else if (format == 6) {
13238 stbtt_uint32 first = ttUSHORT(data + index_map + 6);
13239 stbtt_uint32 count = ttUSHORT(data + index_map + 8);
13240 if ((stbtt_uint32) unicode_codepoint >= first && (stbtt_uint32) unicode_codepoint < first+count)
13241 return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first)*2);
13243 }
else if (format == 2) {
13246 }
else if (format == 4) {
13247 stbtt_uint16 segcount = ttUSHORT(data+index_map+6) >> 1;
13248 stbtt_uint16 searchRange = ttUSHORT(data+index_map+8) >> 1;
13249 stbtt_uint16 entrySelector = ttUSHORT(data+index_map+10);
13250 stbtt_uint16 rangeShift = ttUSHORT(data+index_map+12) >> 1;
13253 stbtt_uint32 endCount = index_map + 14;
13254 stbtt_uint32 search = endCount;
13256 if (unicode_codepoint > 0xffff)
13261 if (unicode_codepoint >= ttUSHORT(data + search + rangeShift*2))
13262 search += rangeShift*2;
13266 while (entrySelector) {
13269 end = ttUSHORT(data + search + searchRange*2);
13270 if (unicode_codepoint > end)
13271 search += searchRange*2;
13277 stbtt_uint16 offset, start, last;
13278 stbtt_uint16 item = (stbtt_uint16) ((search - endCount) >> 1);
13280 start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
13281 last = ttUSHORT(data + endCount + 2*item);
13282 if (unicode_codepoint < start || unicode_codepoint > last)
13285 offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item);
13287 return (stbtt_uint16) (unicode_codepoint + ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item));
13289 return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
13291 }
else if (format == 12 || format == 13) {
13292 stbtt_uint32 ngroups = ttULONG(data+index_map+12);
13293 stbtt_int32 low,high;
13294 low = 0; high = (stbtt_int32)ngroups;
13296 while (low < high) {
13297 stbtt_int32 mid = low + ((high-low) >> 1);
13298 stbtt_uint32 start_char = ttULONG(data+index_map+16+mid*12);
13299 stbtt_uint32 end_char = ttULONG(data+index_map+16+mid*12+4);
13300 if ((stbtt_uint32) unicode_codepoint < start_char)
13302 else if ((stbtt_uint32) unicode_codepoint > end_char)
13305 stbtt_uint32 start_glyph = ttULONG(data+index_map+16+mid*12+8);
13307 return start_glyph + unicode_codepoint-start_char;
13309 return start_glyph;
13319STBTT_DEF
int stbtt_GetCodepointShape(
const stbtt_fontinfo *info,
int unicode_codepoint, stbtt_vertex **vertices)
13321 return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices);
13324static void stbtt_setvertex(stbtt_vertex *v, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy)
13327 v->x = (stbtt_int16) x;
13328 v->y = (stbtt_int16) y;
13329 v->cx = (stbtt_int16) cx;
13330 v->cy = (stbtt_int16) cy;
13333static int stbtt__GetGlyfOffset(
const stbtt_fontinfo *info,
int glyph_index)
13337 STBTT_assert(!info->cff.size);
13339 if (glyph_index >= info->numGlyphs)
return -1;
13340 if (info->indexToLocFormat >= 2)
return -1;
13342 if (info->indexToLocFormat == 0) {
13343 g1 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2) * 2;
13344 g2 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2;
13346 g1 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4);
13347 g2 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4 + 4);
13350 return g1==g2 ? -1 : g1;
13353static int stbtt__GetGlyphInfoT2(
const stbtt_fontinfo *info,
int glyph_index,
int *x0,
int *y0,
int *x1,
int *y1);
13355STBTT_DEF
int stbtt_GetGlyphBox(
const stbtt_fontinfo *info,
int glyph_index,
int *x0,
int *y0,
int *x1,
int *y1)
13357 if (info->cff.size) {
13358 stbtt__GetGlyphInfoT2(info, glyph_index, x0, y0, x1, y1);
13360 int g = stbtt__GetGlyfOffset(info, glyph_index);
13361 if (g < 0)
return 0;
13363 if (x0) *x0 = ttSHORT(info->data + g + 2);
13364 if (y0) *y0 = ttSHORT(info->data + g + 4);
13365 if (x1) *x1 = ttSHORT(info->data + g + 6);
13366 if (y1) *y1 = ttSHORT(info->data + g + 8);
13371STBTT_DEF
int stbtt_GetCodepointBox(
const stbtt_fontinfo *info,
int codepoint,
int *x0,
int *y0,
int *x1,
int *y1)
13373 return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info,codepoint), x0,y0,x1,y1);
13376STBTT_DEF
int stbtt_IsGlyphEmpty(
const stbtt_fontinfo *info,
int glyph_index)
13378 stbtt_int16 numberOfContours;
13380 if (info->cff.size)
13381 return stbtt__GetGlyphInfoT2(info, glyph_index, NULL, NULL, NULL, NULL) == 0;
13382 g = stbtt__GetGlyfOffset(info, glyph_index);
13383 if (g < 0)
return 1;
13384 numberOfContours = ttSHORT(info->data + g);
13385 return numberOfContours == 0;
13388static int stbtt__close_shape(stbtt_vertex *vertices,
int num_vertices,
int was_off,
int start_off,
13389 stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy)
13393 stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy);
13394 stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx,sy,scx,scy);
13397 stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve,sx,sy,cx,cy);
13399 stbtt_setvertex(&vertices[num_vertices++], STBTT_vline,sx,sy,0,0);
13401 return num_vertices;
13404static int stbtt__GetGlyphShapeTT(
const stbtt_fontinfo *info,
int glyph_index, stbtt_vertex **pvertices)
13406 stbtt_int16 numberOfContours;
13407 stbtt_uint8 *endPtsOfContours;
13408 stbtt_uint8 *data = info->data;
13409 stbtt_vertex *vertices=0;
13410 int num_vertices=0;
13411 int g = stbtt__GetGlyfOffset(info, glyph_index);
13415 if (g < 0)
return 0;
13417 numberOfContours = ttSHORT(data + g);
13419 if (numberOfContours > 0) {
13420 stbtt_uint8 flags=0,flagcount;
13421 stbtt_int32 ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0;
13422 stbtt_int32 x,y,cx,cy,sx,sy, scx,scy;
13423 stbtt_uint8 *points;
13424 endPtsOfContours = (data + g + 10);
13425 ins = ttUSHORT(data + g + 10 + numberOfContours * 2);
13426 points = data + g + 10 + numberOfContours * 2 + 2 + ins;
13428 n = 1+ttUSHORT(endPtsOfContours + numberOfContours*2-2);
13430 m = n + 2*numberOfContours;
13431 vertices = (stbtt_vertex *) STBTT_malloc(m *
sizeof(vertices[0]), info->userdata);
13446 for (i=0; i < n; ++i) {
13447 if (flagcount == 0) {
13450 flagcount = *points++;
13453 vertices[off+i].type = flags;
13458 for (i=0; i < n; ++i) {
13459 flags = vertices[off+i].type;
13461 stbtt_int16 dx = *points++;
13462 x += (flags & 16) ? dx : -dx;
13464 if (!(flags & 16)) {
13465 x = x + (stbtt_int16) (points[0]*256 + points[1]);
13469 vertices[off+i].x = (stbtt_int16) x;
13474 for (i=0; i < n; ++i) {
13475 flags = vertices[off+i].type;
13477 stbtt_int16 dy = *points++;
13478 y += (flags & 32) ? dy : -dy;
13480 if (!(flags & 32)) {
13481 y = y + (stbtt_int16) (points[0]*256 + points[1]);
13485 vertices[off+i].y = (stbtt_int16) y;
13490 sx = sy = cx = cy = scx = scy = 0;
13491 for (i=0; i < n; ++i) {
13492 flags = vertices[off+i].type;
13493 x = (stbtt_int16) vertices[off+i].x;
13494 y = (stbtt_int16) vertices[off+i].y;
13496 if (next_move == i) {
13498 num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
13501 start_off = !(flags & 1);
13507 if (!(vertices[off+i+1].type & 1)) {
13509 sx = (x + (stbtt_int32) vertices[off+i+1].x) >> 1;
13510 sy = (y + (stbtt_int32) vertices[off+i+1].y) >> 1;
13513 sx = (stbtt_int32) vertices[off+i+1].x;
13514 sy = (stbtt_int32) vertices[off+i+1].y;
13521 stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove,sx,sy,0,0);
13523 next_move = 1 + ttUSHORT(endPtsOfContours+j*2);
13526 if (!(flags & 1)) {
13528 stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy);
13534 stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x,y, cx, cy);
13536 stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x,y,0,0);
13541 num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
13542 }
else if (numberOfContours < 0) {
13545 stbtt_uint8 *comp = data + g + 10;
13549 stbtt_uint16 flags, gidx;
13550 int comp_num_verts = 0, i;
13551 stbtt_vertex *comp_verts = 0, *tmp = 0;
13552 float mtx[6] = {1,0,0,1,0,0}, m, n;
13554 flags = ttSHORT(comp); comp+=2;
13555 gidx = ttSHORT(comp); comp+=2;
13559 mtx[4] = ttSHORT(comp); comp+=2;
13560 mtx[5] = ttSHORT(comp); comp+=2;
13562 mtx[4] = ttCHAR(comp); comp+=1;
13563 mtx[5] = ttCHAR(comp); comp+=1;
13570 if (flags & (1<<3)) {
13571 mtx[0] = mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
13572 mtx[1] = mtx[2] = 0;
13573 }
else if (flags & (1<<6)) {
13574 mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
13575 mtx[1] = mtx[2] = 0;
13576 mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
13577 }
else if (flags & (1<<7)) {
13578 mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
13579 mtx[1] = ttSHORT(comp)/16384.0f; comp+=2;
13580 mtx[2] = ttSHORT(comp)/16384.0f; comp+=2;
13581 mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
13585 m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
13586 n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
13589 comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts);
13590 if (comp_num_verts > 0) {
13592 for (i = 0; i < comp_num_verts; ++i) {
13593 stbtt_vertex* v = &comp_verts[i];
13594 stbtt_vertex_type x,y;
13596 v->x = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
13597 v->y = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
13599 v->cx = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
13600 v->cy = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
13603 tmp = (stbtt_vertex*)STBTT_malloc((num_vertices+comp_num_verts)*
sizeof(stbtt_vertex), info->userdata);
13605 if (vertices) STBTT_free(vertices, info->userdata);
13606 if (comp_verts) STBTT_free(comp_verts, info->userdata);
13609 if (num_vertices > 0 && vertices) STBTT_memcpy(tmp, vertices, num_vertices*
sizeof(stbtt_vertex));
13610 STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*
sizeof(stbtt_vertex));
13611 if (vertices) STBTT_free(vertices, info->userdata);
13613 STBTT_free(comp_verts, info->userdata);
13614 num_vertices += comp_num_verts;
13617 more = flags & (1<<5);
13623 *pvertices = vertices;
13624 return num_vertices;
13631 float first_x, first_y;
13633 stbtt_int32 min_x, max_x, min_y, max_y;
13635 stbtt_vertex *pvertices;
13639#define STBTT__CSCTX_INIT(bounds) {bounds,0, 0,0, 0,0, 0,0,0,0, NULL, 0}
13641static void stbtt__track_vertex(stbtt__csctx *c, stbtt_int32 x, stbtt_int32 y)
13643 if (x > c->max_x || !c->started) c->max_x = x;
13644 if (y > c->max_y || !c->started) c->max_y = y;
13645 if (x < c->min_x || !c->started) c->min_x = x;
13646 if (y < c->min_y || !c->started) c->min_y = y;
13650static 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)
13653 stbtt__track_vertex(c, x, y);
13654 if (type == STBTT_vcubic) {
13655 stbtt__track_vertex(c, cx, cy);
13656 stbtt__track_vertex(c, cx1, cy1);
13659 stbtt_setvertex(&c->pvertices[c->num_vertices], type, x, y, cx, cy);
13660 c->pvertices[c->num_vertices].cx1 = (stbtt_int16) cx1;
13661 c->pvertices[c->num_vertices].cy1 = (stbtt_int16) cy1;
13666static void stbtt__csctx_close_shape(stbtt__csctx *ctx)
13668 if (ctx->first_x != ctx->x || ctx->first_y != ctx->y)
13669 stbtt__csctx_v(ctx, STBTT_vline, (
int)ctx->first_x, (
int)ctx->first_y, 0, 0, 0, 0);
13672static void stbtt__csctx_rmove_to(stbtt__csctx *ctx,
float dx,
float dy)
13674 stbtt__csctx_close_shape(ctx);
13675 ctx->first_x = ctx->x = ctx->x + dx;
13676 ctx->first_y = ctx->y = ctx->y + dy;
13677 stbtt__csctx_v(ctx, STBTT_vmove, (
int)ctx->x, (
int)ctx->y, 0, 0, 0, 0);
13680static void stbtt__csctx_rline_to(stbtt__csctx *ctx,
float dx,
float dy)
13684 stbtt__csctx_v(ctx, STBTT_vline, (
int)ctx->x, (
int)ctx->y, 0, 0, 0, 0);
13687static void stbtt__csctx_rccurve_to(stbtt__csctx *ctx,
float dx1,
float dy1,
float dx2,
float dy2,
float dx3,
float dy3)
13689 float cx1 = ctx->x + dx1;
13690 float cy1 = ctx->y + dy1;
13691 float cx2 = cx1 + dx2;
13692 float cy2 = cy1 + dy2;
13693 ctx->x = cx2 + dx3;
13694 ctx->y = cy2 + dy3;
13695 stbtt__csctx_v(ctx, STBTT_vcubic, (
int)ctx->x, (
int)ctx->y, (
int)cx1, (
int)cy1, (
int)cx2, (
int)cy2);
13698static stbtt__buf stbtt__get_subr(stbtt__buf idx,
int n)
13700 int count = stbtt__cff_index_count(&idx);
13702 if (count >= 33900)
13704 else if (count >= 1240)
13707 if (n < 0 || n >= count)
13708 return stbtt__new_buf(NULL, 0);
13709 return stbtt__cff_index_get(idx, n);
13712static stbtt__buf stbtt__cid_get_glyph_subrs(
const stbtt_fontinfo *info,
int glyph_index)
13714 stbtt__buf fdselect = info->fdselect;
13715 int nranges, start, end, v, fmt, fdselector = -1, i;
13717 stbtt__buf_seek(&fdselect, 0);
13718 fmt = stbtt__buf_get8(&fdselect);
13721 stbtt__buf_skip(&fdselect, glyph_index);
13722 fdselector = stbtt__buf_get8(&fdselect);
13723 }
else if (fmt == 3) {
13724 nranges = stbtt__buf_get16(&fdselect);
13725 start = stbtt__buf_get16(&fdselect);
13726 for (i = 0; i < nranges; i++) {
13727 v = stbtt__buf_get8(&fdselect);
13728 end = stbtt__buf_get16(&fdselect);
13729 if (glyph_index >= start && glyph_index < end) {
13736 if (fdselector == -1) stbtt__new_buf(NULL, 0);
13737 return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector));
13740static int stbtt__run_charstring(
const stbtt_fontinfo *info,
int glyph_index, stbtt__csctx *c)
13742 int in_header = 1, maskbits = 0, subr_stack_height = 0, sp = 0, v, i, b0;
13743 int has_subrs = 0, clear_stack;
13745 stbtt__buf subr_stack[10], subrs = info->subrs, b;
13748#define STBTT__CSERR(s) (0)
13751 b = stbtt__cff_index_get(info->charstrings, glyph_index);
13752 while (b.cursor < b.size) {
13755 b0 = stbtt__buf_get8(&b);
13761 maskbits += (sp / 2);
13763 stbtt__buf_skip(&b, (maskbits + 7) / 8);
13770 maskbits += (sp / 2);
13775 if (sp < 2)
return STBTT__CSERR(
"rmoveto stack");
13776 stbtt__csctx_rmove_to(c, s[sp-2], s[sp-1]);
13780 if (sp < 1)
return STBTT__CSERR(
"vmoveto stack");
13781 stbtt__csctx_rmove_to(c, 0, s[sp-1]);
13785 if (sp < 1)
return STBTT__CSERR(
"hmoveto stack");
13786 stbtt__csctx_rmove_to(c, s[sp-1], 0);
13790 if (sp < 2)
return STBTT__CSERR(
"rlineto stack");
13791 for (; i + 1 < sp; i += 2)
13792 stbtt__csctx_rline_to(c, s[i], s[i+1]);
13799 if (sp < 1)
return STBTT__CSERR(
"vlineto stack");
13802 if (sp < 1)
return STBTT__CSERR(
"hlineto stack");
13804 if (i >= sp)
break;
13805 stbtt__csctx_rline_to(c, s[i], 0);
13808 if (i >= sp)
break;
13809 stbtt__csctx_rline_to(c, 0, s[i]);
13815 if (sp < 4)
return STBTT__CSERR(
"hvcurveto stack");
13818 if (sp < 4)
return STBTT__CSERR(
"vhcurveto stack");
13820 if (i + 3 >= sp)
break;
13821 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);
13824 if (i + 3 >= sp)
break;
13825 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]);
13831 if (sp < 6)
return STBTT__CSERR(
"rcurveline stack");
13832 for (; i + 5 < sp; i += 6)
13833 stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]);
13837 if (sp < 8)
return STBTT__CSERR(
"rcurveline stack");
13838 for (; i + 5 < sp - 2; i += 6)
13839 stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]);
13840 if (i + 1 >= sp)
return STBTT__CSERR(
"rcurveline stack");
13841 stbtt__csctx_rline_to(c, s[i], s[i+1]);
13845 if (sp < 8)
return STBTT__CSERR(
"rlinecurve stack");
13846 for (; i + 1 < sp - 6; i += 2)
13847 stbtt__csctx_rline_to(c, s[i], s[i+1]);
13848 if (i + 5 >= sp)
return STBTT__CSERR(
"rlinecurve stack");
13849 stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]);
13854 if (sp < 4)
return STBTT__CSERR(
"(vv|hh)curveto stack");
13856 if (sp & 1) { f = s[i]; i++; }
13857 for (; i + 3 < sp; i += 4) {
13859 stbtt__csctx_rccurve_to(c, s[i], f, s[i+1], s[i+2], s[i+3], 0.0);
13861 stbtt__csctx_rccurve_to(c, f, s[i], s[i+1], s[i+2], 0.0, s[i+3]);
13868 if (info->fdselect.size)
13869 subrs = stbtt__cid_get_glyph_subrs(info, glyph_index);
13874 if (sp < 1)
return STBTT__CSERR(
"call(g|)subr stack");
13876 if (subr_stack_height >= 10)
return STBTT__CSERR(
"recursion limit");
13877 subr_stack[subr_stack_height++] = b;
13878 b = stbtt__get_subr(b0 == 0x0A ? subrs : info->gsubrs, v);
13879 if (b.size == 0)
return STBTT__CSERR(
"subr not found");
13885 if (subr_stack_height <= 0)
return STBTT__CSERR(
"return outside subr");
13886 b = subr_stack[--subr_stack_height];
13891 stbtt__csctx_close_shape(c);
13895 float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy3, dy4, dy5, dy6;
13897 int b1 = stbtt__buf_get8(&b);
13902 if (sp < 7)
return STBTT__CSERR(
"hflex stack");
13910 stbtt__csctx_rccurve_to(c, dx1, 0, dx2, dy2, dx3, 0);
13911 stbtt__csctx_rccurve_to(c, dx4, 0, dx5, -dy2, dx6, 0);
13915 if (sp < 13)
return STBTT__CSERR(
"flex stack");
13929 stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3);
13930 stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6);
13934 if (sp < 9)
return STBTT__CSERR(
"hflex1 stack");
13944 stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, 0);
13945 stbtt__csctx_rccurve_to(c, dx4, 0, dx5, dy5, dx6, -(dy1+dy2+dy5));
13949 if (sp < 11)
return STBTT__CSERR(
"flex1 stack");
13961 dx = dx1+dx2+dx3+dx4+dx5;
13962 dy = dy1+dy2+dy3+dy4+dy5;
13963 if (STBTT_fabs(dx) > STBTT_fabs(dy))
13967 stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3);
13968 stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6);
13972 return STBTT__CSERR(
"unimplemented");
13977 if (b0 != 255 && b0 != 28 && b0 < 32)
13978 return STBTT__CSERR(
"reserved operator");
13982 f = (float)(stbtt_int32)stbtt__buf_get32(&b) / 0x10000;
13984 stbtt__buf_skip(&b, -1);
13985 f = (float)(stbtt_int16)stbtt__cff_int(&b);
13987 if (sp >= 48)
return STBTT__CSERR(
"push stack overflow");
13992 if (clear_stack) sp = 0;
13994 return STBTT__CSERR(
"no endchar");
13999static int stbtt__GetGlyphShapeT2(
const stbtt_fontinfo *info,
int glyph_index, stbtt_vertex **pvertices)
14002 stbtt__csctx count_ctx = STBTT__CSCTX_INIT(1);
14003 stbtt__csctx output_ctx = STBTT__CSCTX_INIT(0);
14004 if (stbtt__run_charstring(info, glyph_index, &count_ctx)) {
14005 *pvertices = (stbtt_vertex*)STBTT_malloc(count_ctx.num_vertices*
sizeof(stbtt_vertex), info->userdata);
14006 output_ctx.pvertices = *pvertices;
14007 if (stbtt__run_charstring(info, glyph_index, &output_ctx)) {
14008 STBTT_assert(output_ctx.num_vertices == count_ctx.num_vertices);
14009 return output_ctx.num_vertices;
14016static int stbtt__GetGlyphInfoT2(
const stbtt_fontinfo *info,
int glyph_index,
int *x0,
int *y0,
int *x1,
int *y1)
14018 stbtt__csctx c = STBTT__CSCTX_INIT(1);
14019 int r = stbtt__run_charstring(info, glyph_index, &c);
14020 if (x0) *x0 = r ? c.min_x : 0;
14021 if (y0) *y0 = r ? c.min_y : 0;
14022 if (x1) *x1 = r ? c.max_x : 0;
14023 if (y1) *y1 = r ? c.max_y : 0;
14024 return r ? c.num_vertices : 0;
14027STBTT_DEF
int stbtt_GetGlyphShape(
const stbtt_fontinfo *info,
int glyph_index, stbtt_vertex **pvertices)
14029 if (!info->cff.size)
14030 return stbtt__GetGlyphShapeTT(info, glyph_index, pvertices);
14032 return stbtt__GetGlyphShapeT2(info, glyph_index, pvertices);
14035STBTT_DEF
void stbtt_GetGlyphHMetrics(
const stbtt_fontinfo *info,
int glyph_index,
int *advanceWidth,
int *leftSideBearing)
14037 stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data+info->hhea + 34);
14038 if (glyph_index < numOfLongHorMetrics) {
14039 if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*glyph_index);
14040 if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*glyph_index + 2);
14042 if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1));
14043 if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics));
14047STBTT_DEF
int stbtt_GetKerningTableLength(
const stbtt_fontinfo *info)
14049 stbtt_uint8 *data = info->data + info->kern;
14054 if (ttUSHORT(data+2) < 1)
14056 if (ttUSHORT(data+8) != 1)
14059 return ttUSHORT(data+10);
14062STBTT_DEF
int stbtt_GetKerningTable(
const stbtt_fontinfo *info, stbtt_kerningentry* table,
int table_length)
14064 stbtt_uint8 *data = info->data + info->kern;
14070 if (ttUSHORT(data+2) < 1)
14072 if (ttUSHORT(data+8) != 1)
14075 length = ttUSHORT(data+10);
14076 if (table_length < length)
14077 length = table_length;
14079 for (k = 0; k < length; k++)
14081 table[k].glyph1 = ttUSHORT(data+18+(k*6));
14082 table[k].glyph2 = ttUSHORT(data+20+(k*6));
14083 table[k].advance = ttSHORT(data+22+(k*6));
14089static int stbtt__GetGlyphKernInfoAdvance(
const stbtt_fontinfo *info,
int glyph1,
int glyph2)
14091 stbtt_uint8 *data = info->data + info->kern;
14092 stbtt_uint32 needle, straw;
14098 if (ttUSHORT(data+2) < 1)
14100 if (ttUSHORT(data+8) != 1)
14104 r = ttUSHORT(data+10) - 1;
14105 needle = glyph1 << 16 | glyph2;
14108 straw = ttULONG(data+18+(m*6));
14109 if (needle < straw)
14111 else if (needle > straw)
14114 return ttSHORT(data+22+(m*6));
14119static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable,
int glyph)
14121 stbtt_uint16 coverageFormat = ttUSHORT(coverageTable);
14122 switch (coverageFormat) {
14124 stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2);
14127 stbtt_int32 l=0, r=glyphCount-1, m;
14128 int straw, needle=glyph;
14130 stbtt_uint8 *glyphArray = coverageTable + 4;
14131 stbtt_uint16 glyphID;
14133 glyphID = ttUSHORT(glyphArray + 2 * m);
14135 if (needle < straw)
14137 else if (needle > straw)
14147 stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2);
14148 stbtt_uint8 *rangeArray = coverageTable + 4;
14151 stbtt_int32 l=0, r=rangeCount-1, m;
14152 int strawStart, strawEnd, needle=glyph;
14154 stbtt_uint8 *rangeRecord;
14156 rangeRecord = rangeArray + 6 * m;
14157 strawStart = ttUSHORT(rangeRecord);
14158 strawEnd = ttUSHORT(rangeRecord + 2);
14159 if (needle < strawStart)
14161 else if (needle > strawEnd)
14164 stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4);
14165 return startCoverageIndex + glyph - strawStart;
14171 default:
return -1;
14177static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable,
int glyph)
14179 stbtt_uint16 classDefFormat = ttUSHORT(classDefTable);
14180 switch (classDefFormat)
14183 stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2);
14184 stbtt_uint16 glyphCount = ttUSHORT(classDefTable + 4);
14185 stbtt_uint8 *classDef1ValueArray = classDefTable + 6;
14187 if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount)
14188 return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID));
14193 stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2);
14194 stbtt_uint8 *classRangeRecords = classDefTable + 4;
14197 stbtt_int32 l=0, r=classRangeCount-1, m;
14198 int strawStart, strawEnd, needle=glyph;
14200 stbtt_uint8 *classRangeRecord;
14202 classRangeRecord = classRangeRecords + 6 * m;
14203 strawStart = ttUSHORT(classRangeRecord);
14204 strawEnd = ttUSHORT(classRangeRecord + 2);
14205 if (needle < strawStart)
14207 else if (needle > strawEnd)
14210 return (stbtt_int32)ttUSHORT(classRangeRecord + 4);
14224#define STBTT_GPOS_TODO_assert(x)
14226static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(
const stbtt_fontinfo *info,
int glyph1,
int glyph2)
14228 stbtt_uint16 lookupListOffset;
14229 stbtt_uint8 *lookupList;
14230 stbtt_uint16 lookupCount;
14232 stbtt_int32 i, sti;
14234 if (!info->gpos)
return 0;
14236 data = info->data + info->gpos;
14238 if (ttUSHORT(data+0) != 1)
return 0;
14239 if (ttUSHORT(data+2) != 0)
return 0;
14241 lookupListOffset = ttUSHORT(data+8);
14242 lookupList = data + lookupListOffset;
14243 lookupCount = ttUSHORT(lookupList);
14245 for (i=0; i<lookupCount; ++i) {
14246 stbtt_uint16 lookupOffset = ttUSHORT(lookupList + 2 + 2 * i);
14247 stbtt_uint8 *lookupTable = lookupList + lookupOffset;
14249 stbtt_uint16 lookupType = ttUSHORT(lookupTable);
14250 stbtt_uint16 subTableCount = ttUSHORT(lookupTable + 4);
14251 stbtt_uint8 *subTableOffsets = lookupTable + 6;
14252 if (lookupType != 2)
14255 for (sti=0; sti<subTableCount; sti++) {
14256 stbtt_uint16 subtableOffset = ttUSHORT(subTableOffsets + 2 * sti);
14257 stbtt_uint8 *table = lookupTable + subtableOffset;
14258 stbtt_uint16 posFormat = ttUSHORT(table);
14259 stbtt_uint16 coverageOffset = ttUSHORT(table + 2);
14260 stbtt_int32 coverageIndex = stbtt__GetCoverageIndex(table + coverageOffset, glyph1);
14261 if (coverageIndex == -1)
continue;
14263 switch (posFormat) {
14265 stbtt_int32 l, r, m;
14267 stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
14268 stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
14269 if (valueFormat1 == 4 && valueFormat2 == 0) {
14270 stbtt_int32 valueRecordPairSizeInBytes = 2;
14271 stbtt_uint16 pairSetCount = ttUSHORT(table + 8);
14272 stbtt_uint16 pairPosOffset = ttUSHORT(table + 10 + 2 * coverageIndex);
14273 stbtt_uint8 *pairValueTable = table + pairPosOffset;
14274 stbtt_uint16 pairValueCount = ttUSHORT(pairValueTable);
14275 stbtt_uint8 *pairValueArray = pairValueTable + 2;
14277 if (coverageIndex >= pairSetCount)
return 0;
14280 r=pairValueCount-1;
14285 stbtt_uint16 secondGlyph;
14286 stbtt_uint8 *pairValue;
14288 pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m;
14289 secondGlyph = ttUSHORT(pairValue);
14290 straw = secondGlyph;
14291 if (needle < straw)
14293 else if (needle > straw)
14296 stbtt_int16 xAdvance = ttSHORT(pairValue + 2);
14306 stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
14307 stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
14308 if (valueFormat1 == 4 && valueFormat2 == 0) {
14309 stbtt_uint16 classDef1Offset = ttUSHORT(table + 8);
14310 stbtt_uint16 classDef2Offset = ttUSHORT(table + 10);
14311 int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1);
14312 int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2);
14314 stbtt_uint16 class1Count = ttUSHORT(table + 12);
14315 stbtt_uint16 class2Count = ttUSHORT(table + 14);
14316 stbtt_uint8 *class1Records, *class2Records;
14317 stbtt_int16 xAdvance;
14319 if (glyph1class < 0 || glyph1class >= class1Count)
return 0;
14320 if (glyph2class < 0 || glyph2class >= class2Count)
return 0;
14322 class1Records = table + 16;
14323 class2Records = class1Records + 2 * (glyph1class * class2Count);
14324 xAdvance = ttSHORT(class2Records + 2 * glyph2class);
14340STBTT_DEF
int stbtt_GetGlyphKernAdvance(
const stbtt_fontinfo *info,
int g1,
int g2)
14345 xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2);
14346 else if (info->kern)
14347 xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2);
14352STBTT_DEF
int stbtt_GetCodepointKernAdvance(
const stbtt_fontinfo *info,
int ch1,
int ch2)
14354 if (!info->kern && !info->gpos)
14356 return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2));
14359STBTT_DEF
void stbtt_GetCodepointHMetrics(
const stbtt_fontinfo *info,
int codepoint,
int *advanceWidth,
int *leftSideBearing)
14361 stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info,codepoint), advanceWidth, leftSideBearing);
14364STBTT_DEF
void stbtt_GetFontVMetrics(
const stbtt_fontinfo *info,
int *ascent,
int *descent,
int *lineGap)
14366 if (ascent ) *ascent = ttSHORT(info->data+info->hhea + 4);
14367 if (descent) *descent = ttSHORT(info->data+info->hhea + 6);
14368 if (lineGap) *lineGap = ttSHORT(info->data+info->hhea + 8);
14371STBTT_DEF
int stbtt_GetFontVMetricsOS2(
const stbtt_fontinfo *info,
int *typoAscent,
int *typoDescent,
int *typoLineGap)
14373 int tab = stbtt__find_table(info->data, info->fontstart,
"OS/2");
14376 if (typoAscent ) *typoAscent = ttSHORT(info->data+tab + 68);
14377 if (typoDescent) *typoDescent = ttSHORT(info->data+tab + 70);
14378 if (typoLineGap) *typoLineGap = ttSHORT(info->data+tab + 72);
14382STBTT_DEF
void stbtt_GetFontBoundingBox(
const stbtt_fontinfo *info,
int *x0,
int *y0,
int *x1,
int *y1)
14384 *x0 = ttSHORT(info->data + info->head + 36);
14385 *y0 = ttSHORT(info->data + info->head + 38);
14386 *x1 = ttSHORT(info->data + info->head + 40);
14387 *y1 = ttSHORT(info->data + info->head + 42);
14390STBTT_DEF
float stbtt_ScaleForPixelHeight(
const stbtt_fontinfo *info,
float height)
14392 int fheight = ttSHORT(info->data + info->hhea + 4) - ttSHORT(info->data + info->hhea + 6);
14393 return (
float) height / fheight;
14396STBTT_DEF
float stbtt_ScaleForMappingEmToPixels(
const stbtt_fontinfo *info,
float pixels)
14398 int unitsPerEm = ttUSHORT(info->data + info->head + 18);
14399 return pixels / unitsPerEm;
14402STBTT_DEF
void stbtt_FreeShape(
const stbtt_fontinfo *info, stbtt_vertex *v)
14404 STBTT_free(v, info->userdata);
14407STBTT_DEF stbtt_uint8 *stbtt_FindSVGDoc(
const stbtt_fontinfo *info,
int gl)
14410 stbtt_uint8 *data = info->data;
14411 stbtt_uint8 *svg_doc_list = data + stbtt__get_svg((stbtt_fontinfo *) info);
14413 int numEntries = ttUSHORT(svg_doc_list);
14414 stbtt_uint8 *svg_docs = svg_doc_list + 2;
14416 for(i=0; i<numEntries; i++) {
14417 stbtt_uint8 *svg_doc = svg_docs + (12 * i);
14418 if ((gl >= ttUSHORT(svg_doc)) && (gl <= ttUSHORT(svg_doc + 2)))
14424STBTT_DEF
int stbtt_GetGlyphSVG(
const stbtt_fontinfo *info,
int gl,
const char **svg)
14426 stbtt_uint8 *data = info->data;
14427 stbtt_uint8 *svg_doc;
14429 if (info->svg == 0)
14432 svg_doc = stbtt_FindSVGDoc(info, gl);
14433 if (svg_doc != NULL) {
14434 *svg = (
char *) data + info->svg + ttULONG(svg_doc + 4);
14435 return ttULONG(svg_doc + 8);
14441STBTT_DEF
int stbtt_GetCodepointSVG(
const stbtt_fontinfo *info,
int unicode_codepoint,
const char **svg)
14443 return stbtt_GetGlyphSVG(info, stbtt_FindGlyphIndex(info, unicode_codepoint), svg);
14451STBTT_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)
14453 int x0=0,y0=0,x1,y1;
14454 if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) {
14462 if (ix0) *ix0 = STBTT_ifloor( x0 * scale_x + shift_x);
14463 if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y);
14464 if (ix1) *ix1 = STBTT_iceil ( x1 * scale_x + shift_x);
14465 if (iy1) *iy1 = STBTT_iceil (-y0 * scale_y + shift_y);
14469STBTT_DEF
void stbtt_GetGlyphBitmapBox(
const stbtt_fontinfo *font,
int glyph,
float scale_x,
float scale_y,
int *ix0,
int *iy0,
int *ix1,
int *iy1)
14471 stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1);
14474STBTT_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)
14476 stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font,codepoint), scale_x, scale_y,shift_x,shift_y, ix0,iy0,ix1,iy1);
14479STBTT_DEF
void stbtt_GetCodepointBitmapBox(
const stbtt_fontinfo *font,
int codepoint,
float scale_x,
float scale_y,
int *ix0,
int *iy0,
int *ix1,
int *iy1)
14481 stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y,0.0f,0.0f, ix0,iy0,ix1,iy1);
14488typedef struct stbtt__hheap_chunk
14490 struct stbtt__hheap_chunk *next;
14491} stbtt__hheap_chunk;
14493typedef struct stbtt__hheap
14495 struct stbtt__hheap_chunk *head;
14497 int num_remaining_in_head_chunk;
14500static void *stbtt__hheap_alloc(stbtt__hheap *hh,
size_t size,
void *userdata)
14502 if (hh->first_free) {
14503 void *p = hh->first_free;
14504 hh->first_free = * (
void **) p;
14507 if (hh->num_remaining_in_head_chunk == 0) {
14508 int count = (size < 32 ? 2000 : size < 128 ? 800 : 100);
14509 stbtt__hheap_chunk *c = (stbtt__hheap_chunk *) STBTT_malloc(
sizeof(stbtt__hheap_chunk) + size * count, userdata);
14512 c->next = hh->head;
14514 hh->num_remaining_in_head_chunk = count;
14516 --hh->num_remaining_in_head_chunk;
14517 return (
char *) (hh->head) +
sizeof(stbtt__hheap_chunk) + size * hh->num_remaining_in_head_chunk;
14521static void stbtt__hheap_free(stbtt__hheap *hh,
void *p)
14523 *(
void **) p = hh->first_free;
14524 hh->first_free = p;
14527static void stbtt__hheap_cleanup(stbtt__hheap *hh,
void *userdata)
14529 stbtt__hheap_chunk *c = hh->head;
14531 stbtt__hheap_chunk *n = c->next;
14532 STBTT_free(c, userdata);
14537typedef struct stbtt__edge {
14538 float x0,y0, x1,y1;
14543typedef struct stbtt__active_edge
14545 struct stbtt__active_edge *next;
14546 #if STBTT_RASTERIZER_VERSION==1
14550 #elif STBTT_RASTERIZER_VERSION==2
14556 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
14558} stbtt__active_edge;
14560#if STBTT_RASTERIZER_VERSION == 1
14561#define STBTT_FIXSHIFT 10
14562#define STBTT_FIX (1 << STBTT_FIXSHIFT)
14563#define STBTT_FIXMASK (STBTT_FIX-1)
14565static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e,
int off_x,
float start_point,
void *userdata)
14567 stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh,
sizeof(*z), userdata);
14568 float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
14569 STBTT_assert(z != NULL);
14574 z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy);
14576 z->dx = STBTT_ifloor(STBTT_FIX * dxdy);
14578 z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point - e->y0));
14579 z->x -= off_x * STBTT_FIX;
14583 z->direction = e->invert ? 1 : -1;
14586#elif STBTT_RASTERIZER_VERSION == 2
14587static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e,
int off_x,
float start_point,
void *userdata)
14589 stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh,
sizeof(*z), userdata);
14590 float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
14591 STBTT_assert(z != NULL);
14595 z->fdy = dxdy != 0.0f ? (1.0f/dxdy) : 0.0f;
14596 z->fx = e->x0 + dxdy * (start_point - e->y0);
14598 z->direction = e->invert ? 1.0f : -1.0f;
14605#error "Unrecognized value of STBTT_RASTERIZER_VERSION"
14608#if STBTT_RASTERIZER_VERSION == 1
14612static void stbtt__fill_active_edges(
unsigned char *scanline,
int len, stbtt__active_edge *e,
int max_weight)
14620 x0 = e->x; w += e->direction;
14622 int x1 = e->x; w += e->direction;
14625 int i = x0 >> STBTT_FIXSHIFT;
14626 int j = x1 >> STBTT_FIXSHIFT;
14628 if (i < len && j >= 0) {
14631 scanline[i] = scanline[i] + (stbtt_uint8) ((x1 - x0) * max_weight >> STBTT_FIXSHIFT);
14634 scanline[i] = scanline[i] + (stbtt_uint8) (((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT);
14639 scanline[j] = scanline[j] + (stbtt_uint8) (((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_FIXSHIFT);
14643 for (++i; i < j; ++i)
14644 scanline[i] = scanline[i] + (stbtt_uint8) max_weight;
14654static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
int n,
int vsubsample,
int off_x,
int off_y,
void *userdata)
14656 stbtt__hheap hh = { 0, 0, 0 };
14657 stbtt__active_edge *active = NULL;
14659 int max_weight = (255 / vsubsample);
14661 unsigned char scanline_data[512], *scanline;
14663 if (result->w > 512)
14664 scanline = (
unsigned char *) STBTT_malloc(result->w, userdata);
14666 scanline = scanline_data;
14668 y = off_y * vsubsample;
14669 e[n].y0 = (off_y + result->h) * (
float) vsubsample + 1;
14671 while (j < result->h) {
14672 STBTT_memset(scanline, 0, result->w);
14673 for (s=0; s < vsubsample; ++s) {
14675 float scan_y = y + 0.5f;
14676 stbtt__active_edge **step = &active;
14681 stbtt__active_edge * z = *step;
14682 if (z->ey <= scan_y) {
14684 STBTT_assert(z->direction);
14686 stbtt__hheap_free(&hh, z);
14689 step = &((*step)->next);
14697 while (*step && (*step)->next) {
14698 if ((*step)->x > (*step)->next->x) {
14699 stbtt__active_edge *t = *step;
14700 stbtt__active_edge *q = t->next;
14707 step = &(*step)->next;
14709 if (!changed)
break;
14713 while (e->y0 <= scan_y) {
14714 if (e->y1 > scan_y) {
14715 stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata);
14718 if (active == NULL)
14720 else if (z->x < active->x) {
14726 stbtt__active_edge *p = active;
14727 while (p->next && p->next->x < z->x)
14740 stbtt__fill_active_edges(scanline, result->w, active, max_weight);
14744 STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w);
14748 stbtt__hheap_cleanup(&hh, userdata);
14750 if (scanline != scanline_data)
14751 STBTT_free(scanline, userdata);
14754#elif STBTT_RASTERIZER_VERSION == 2
14758static void stbtt__handle_clipped_edge(
float *scanline,
int x, stbtt__active_edge *e,
float x0,
float y0,
float x1,
float y1)
14760 if (y0 == y1)
return;
14761 STBTT_assert(y0 < y1);
14762 STBTT_assert(e->sy <= e->ey);
14763 if (y0 > e->ey)
return;
14764 if (y1 < e->sy)
return;
14766 x0 += (x1-x0) * (e->sy - y0) / (y1-y0);
14770 x1 += (x1-x0) * (e->ey - y1) / (y1-y0);
14775 STBTT_assert(x1 <= x+1);
14776 else if (x0 == x+1)
14777 STBTT_assert(x1 >= x);
14779 STBTT_assert(x1 <= x);
14780 else if (x0 >= x+1)
14781 STBTT_assert(x1 >= x+1);
14783 STBTT_assert(x1 >= x && x1 <= x+1);
14785 if (x0 <= x && x1 <= x)
14786 scanline[x] += e->direction * (y1-y0);
14787 else if (x0 >= x+1 && x1 >= x+1)
14790 STBTT_assert(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1);
14791 scanline[x] += e->direction * (y1-y0) * (1-((x0-x)+(x1-x))/2);
14795static float stbtt__sized_trapezoid_area(
float height,
float top_width,
float bottom_width)
14797 STBTT_assert(top_width >= 0);
14798 STBTT_assert(bottom_width >= 0);
14799 return (top_width + bottom_width) / 2.0f * height;
14802static float stbtt__position_trapezoid_area(
float height,
float tx0,
float tx1,
float bx0,
float bx1)
14804 return stbtt__sized_trapezoid_area(height, tx1 - tx0, bx1 - bx0);
14807static float stbtt__sized_triangle_area(
float height,
float width)
14809 return height * width / 2;
14812static void stbtt__fill_active_edges_new(
float *scanline,
float *scanline_fill,
int len, stbtt__active_edge *e,
float y_top)
14814 float y_bottom = y_top+1;
14820 STBTT_assert(e->ey >= y_top);
14826 stbtt__handle_clipped_edge(scanline,(
int) x0,e, x0,y_top, x0,y_bottom);
14827 stbtt__handle_clipped_edge(scanline_fill-1,(
int) x0+1,e, x0,y_top, x0,y_bottom);
14829 stbtt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom);
14835 float xb = x0 + dx;
14836 float x_top, x_bottom;
14839 STBTT_assert(e->sy <= y_bottom && e->ey >= y_top);
14844 if (e->sy > y_top) {
14845 x_top = x0 + dx * (e->sy - y_top);
14851 if (e->ey < y_bottom) {
14852 x_bottom = x0 + dx * (e->ey - y_top);
14859 if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) {
14862 if ((
int) x_top == (int) x_bottom) {
14865 int x = (int) x_top;
14866 height = (sy1 - sy0) * e->direction;
14867 STBTT_assert(x >= 0 && x < len);
14868 scanline[x] += stbtt__position_trapezoid_area(height, x_top, x+1.0f, x_bottom, x+1.0f);
14869 scanline_fill[x] += height;
14872 float y_crossing, y_final, step, sign, area;
14874 if (x_top > x_bottom) {
14877 sy0 = y_bottom - (sy0 - y_top);
14878 sy1 = y_bottom - (sy1 - y_top);
14879 t = sy0, sy0 = sy1, sy1 = t;
14880 t = x_bottom, x_bottom = x_top, x_top = t;
14883 t = x0, x0 = xb, xb = t;
14885 STBTT_assert(dy >= 0);
14886 STBTT_assert(dx >= 0);
14889 x2 = (int) x_bottom;
14891 y_crossing = y_top + dy * (x1+1 - x0);
14894 y_final = y_top + dy * (x2 - x0);
14915 if (y_crossing > y_bottom)
14916 y_crossing = y_bottom;
14918 sign = e->direction;
14921 area = sign * (y_crossing-sy0);
14924 scanline[x1] += stbtt__sized_triangle_area(area, x1+1 - x_top);
14927 if (y_final > y_bottom) {
14928 y_final = y_bottom;
14929 dy = (y_final - y_crossing ) / (x2 - (x1+1));
14942 step = sign * dy * 1;
14946 for (x = x1+1; x < x2; ++x) {
14947 scanline[x] += area + step/2;
14950 STBTT_assert(STBTT_fabs(area) <= 1.01f);
14951 STBTT_assert(sy1 > y_final-0.01f);
14955 scanline[x2] += area + sign * stbtt__position_trapezoid_area(sy1-y_final, (
float) x2, x2+1.0f, x_bottom, x2+1.0f);
14958 scanline_fill[x2] += sign * (sy1-sy0);
14969 for (x=0; x < len; ++x) {
14985 float x1 = (float) (x);
14986 float x2 = (float) (x+1);
14988 float y3 = y_bottom;
14993 float y1 = (x - x0) / dx + y_top;
14994 float y2 = (x+1 - x0) / dx + y_top;
14996 if (x0 < x1 && x3 > x2) {
14997 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
14998 stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x2,y2);
14999 stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
15000 }
else if (x3 < x1 && x0 > x2) {
15001 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
15002 stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x1,y1);
15003 stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
15004 }
else if (x0 < x1 && x3 > x1) {
15005 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
15006 stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
15007 }
else if (x3 < x1 && x0 > x1) {
15008 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
15009 stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
15010 }
else if (x0 < x2 && x3 > x2) {
15011 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
15012 stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
15013 }
else if (x3 < x2 && x0 > x2) {
15014 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
15015 stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
15017 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x3,y3);
15027static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
int n,
int vsubsample,
int off_x,
int off_y,
void *userdata)
15029 stbtt__hheap hh = { 0, 0, 0 };
15030 stbtt__active_edge *active = NULL;
15032 float scanline_data[129], *scanline, *scanline2;
15034 STBTT__NOTUSED(vsubsample);
15036 if (result->w > 64)
15037 scanline = (
float *) STBTT_malloc((result->w*2+1) *
sizeof(float), userdata);
15039 scanline = scanline_data;
15041 scanline2 = scanline + result->w;
15044 e[n].y0 = (float) (off_y + result->h) + 1;
15046 while (j < result->h) {
15048 float scan_y_top = y + 0.0f;
15049 float scan_y_bottom = y + 1.0f;
15050 stbtt__active_edge **step = &active;
15052 STBTT_memset(scanline , 0, result->w*
sizeof(scanline[0]));
15053 STBTT_memset(scanline2, 0, (result->w+1)*
sizeof(scanline[0]));
15058 stbtt__active_edge * z = *step;
15059 if (z->ey <= scan_y_top) {
15061 STBTT_assert(z->direction);
15063 stbtt__hheap_free(&hh, z);
15065 step = &((*step)->next);
15070 while (e->y0 <= scan_y_bottom) {
15071 if (e->y0 != e->y1) {
15072 stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
15074 if (j == 0 && off_y != 0) {
15075 if (z->ey < scan_y_top) {
15077 z->ey = scan_y_top;
15080 STBTT_assert(z->ey >= scan_y_top);
15091 stbtt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top);
15095 for (i=0; i < result->w; ++i) {
15098 sum += scanline2[i];
15099 k = scanline[i] + sum;
15100 k = (float) STBTT_fabs(k)*255 + 0.5f;
15102 if (m > 255) m = 255;
15103 result->pixels[j*result->stride + i] = (
unsigned char) m;
15109 stbtt__active_edge *z = *step;
15111 step = &((*step)->next);
15118 stbtt__hheap_cleanup(&hh, userdata);
15120 if (scanline != scanline_data)
15121 STBTT_free(scanline, userdata);
15124#error "Unrecognized value of STBTT_RASTERIZER_VERSION"
15127#define STBTT__COMPARE(a,b) ((a)->y0 < (b)->y0)
15129static void stbtt__sort_edges_ins_sort(stbtt__edge *p,
int n)
15132 for (i=1; i < n; ++i) {
15133 stbtt__edge t = p[i], *a = &t;
15136 stbtt__edge *b = &p[j-1];
15137 int c = STBTT__COMPARE(a,b);
15147static void stbtt__sort_edges_quicksort(stbtt__edge *p,
int n)
15152 int c01,c12,c,m,i,j;
15156 c01 = STBTT__COMPARE(&p[0],&p[m]);
15157 c12 = STBTT__COMPARE(&p[m],&p[n-1]);
15162 c = STBTT__COMPARE(&p[0],&p[n-1]);
15165 z = (c == c12) ? 0 : n-1;
15183 if (!STBTT__COMPARE(&p[i], &p[0]))
break;
15186 if (!STBTT__COMPARE(&p[0], &p[j]))
break;
15199 stbtt__sort_edges_quicksort(p,j);
15203 stbtt__sort_edges_quicksort(p+i, n-i);
15209static void stbtt__sort_edges(stbtt__edge *p,
int n)
15211 stbtt__sort_edges_quicksort(p, n);
15212 stbtt__sort_edges_ins_sort(p, n);
15220static 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)
15222 float y_scale_inv = invert ? -scale_y : scale_y;
15225#if STBTT_RASTERIZER_VERSION == 1
15226 int vsubsample = result->h < 8 ? 15 : 5;
15227#elif STBTT_RASTERIZER_VERSION == 2
15228 int vsubsample = 1;
15230 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
15236 for (i=0; i < windings; ++i)
15239 e = (stbtt__edge *) STBTT_malloc(
sizeof(*e) * (n+1), userdata);
15240 if (e == 0)
return;
15244 for (i=0; i < windings; ++i) {
15245 stbtt__point *p = pts + m;
15248 for (k=0; k < wcount[i]; j=k++) {
15251 if (p[j].y == p[k].y)
15255 if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) {
15259 e[n].x0 = p[a].x * scale_x + shift_x;
15260 e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample;
15261 e[n].x1 = p[b].x * scale_x + shift_x;
15262 e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample;
15269 stbtt__sort_edges(e, n);
15272 stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata);
15274 STBTT_free(e, userdata);
15277static void stbtt__add_point(stbtt__point *points,
int n,
float x,
float y)
15279 if (!points)
return;
15285static 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)
15288 float mx = (x0 + 2*x1 + x2)/4;
15289 float my = (y0 + 2*y1 + y2)/4;
15291 float dx = (x0+x2)/2 - mx;
15292 float dy = (y0+y2)/2 - my;
15295 if (dx*dx+dy*dy > objspace_flatness_squared) {
15296 stbtt__tesselate_curve(points, num_points, x0,y0, (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1);
15297 stbtt__tesselate_curve(points, num_points, mx,my, (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1);
15299 stbtt__add_point(points, *num_points,x2,y2);
15300 *num_points = *num_points+1;
15305static 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)
15316 float longlen = (float) (STBTT_sqrt(dx0*dx0+dy0*dy0)+STBTT_sqrt(dx1*dx1+dy1*dy1)+STBTT_sqrt(dx2*dx2+dy2*dy2));
15317 float shortlen = (float) STBTT_sqrt(dx*dx+dy*dy);
15318 float flatness_squared = longlen*longlen-shortlen*shortlen;
15323 if (flatness_squared > objspace_flatness_squared) {
15324 float x01 = (x0+x1)/2;
15325 float y01 = (y0+y1)/2;
15326 float x12 = (x1+x2)/2;
15327 float y12 = (y1+y2)/2;
15328 float x23 = (x2+x3)/2;
15329 float y23 = (y2+y3)/2;
15331 float xa = (x01+x12)/2;
15332 float ya = (y01+y12)/2;
15333 float xb = (x12+x23)/2;
15334 float yb = (y12+y23)/2;
15336 float mx = (xa+xb)/2;
15337 float my = (ya+yb)/2;
15339 stbtt__tesselate_cubic(points, num_points, x0,y0, x01,y01, xa,ya, mx,my, objspace_flatness_squared,n+1);
15340 stbtt__tesselate_cubic(points, num_points, mx,my, xb,yb, x23,y23, x3,y3, objspace_flatness_squared,n+1);
15342 stbtt__add_point(points, *num_points,x3,y3);
15343 *num_points = *num_points+1;
15348static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices,
int num_verts,
float objspace_flatness,
int **contour_lengths,
int *num_contours,
void *userdata)
15350 stbtt__point *points=0;
15353 float objspace_flatness_squared = objspace_flatness * objspace_flatness;
15354 int i,n=0,start=0, pass;
15357 for (i=0; i < num_verts; ++i)
15358 if (vertices[i].type == STBTT_vmove)
15362 if (n == 0)
return 0;
15364 *contour_lengths = (
int *) STBTT_malloc(
sizeof(**contour_lengths) * n, userdata);
15366 if (*contour_lengths == 0) {
15372 for (pass=0; pass < 2; ++pass) {
15375 points = (stbtt__point *) STBTT_malloc(num_points *
sizeof(points[0]), userdata);
15376 if (points == NULL)
goto error;
15380 for (i=0; i < num_verts; ++i) {
15381 switch (vertices[i].type) {
15385 (*contour_lengths)[n] = num_points - start;
15387 start = num_points;
15389 x = vertices[i].x, y = vertices[i].y;
15390 stbtt__add_point(points, num_points++, x,y);
15393 x = vertices[i].x, y = vertices[i].y;
15394 stbtt__add_point(points, num_points++, x, y);
15397 stbtt__tesselate_curve(points, &num_points, x,y,
15398 vertices[i].cx, vertices[i].cy,
15399 vertices[i].x, vertices[i].y,
15400 objspace_flatness_squared, 0);
15401 x = vertices[i].x, y = vertices[i].y;
15404 stbtt__tesselate_cubic(points, &num_points, x,y,
15405 vertices[i].cx, vertices[i].cy,
15406 vertices[i].cx1, vertices[i].cy1,
15407 vertices[i].x, vertices[i].y,
15408 objspace_flatness_squared, 0);
15409 x = vertices[i].x, y = vertices[i].y;
15413 (*contour_lengths)[n] = num_points - start;
15418 STBTT_free(points, userdata);
15419 STBTT_free(*contour_lengths, userdata);
15420 *contour_lengths = 0;
15425STBTT_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)
15427 float scale = scale_x > scale_y ? scale_y : scale_x;
15428 int winding_count = 0;
15429 int *winding_lengths = NULL;
15430 stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata);
15432 stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata);
15433 STBTT_free(winding_lengths, userdata);
15434 STBTT_free(windings, userdata);
15438STBTT_DEF
void stbtt_FreeBitmap(
unsigned char *bitmap,
void *userdata)
15440 STBTT_free(bitmap, userdata);
15443STBTT_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)
15445 int ix0,iy0,ix1,iy1;
15447 stbtt_vertex *vertices;
15448 int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
15450 if (scale_x == 0) scale_x = scale_y;
15451 if (scale_y == 0) {
15452 if (scale_x == 0) {
15453 STBTT_free(vertices, info->userdata);
15459 stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,&ix1,&iy1);
15462 gbm.w = (ix1 - ix0);
15463 gbm.h = (iy1 - iy0);
15466 if (width ) *width = gbm.w;
15467 if (height) *height = gbm.h;
15468 if (xoff ) *xoff = ix0;
15469 if (yoff ) *yoff = iy0;
15471 if (gbm.w && gbm.h) {
15472 gbm.pixels = (
unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata);
15474 gbm.stride = gbm.w;
15476 stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata);
15479 STBTT_free(vertices, info->userdata);
15483STBTT_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)
15485 return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff);
15488STBTT_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)
15491 stbtt_vertex *vertices;
15492 int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
15495 stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0);
15496 gbm.pixels = output;
15499 gbm.stride = out_stride;
15501 if (gbm.w && gbm.h)
15502 stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0,iy0, 1, info->userdata);
15504 STBTT_free(vertices, info->userdata);
15507STBTT_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)
15509 stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, glyph);
15512STBTT_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)
15514 return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff);
15517STBTT_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)
15519 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));
15522STBTT_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)
15524 stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint));
15527STBTT_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)
15529 return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff);
15532STBTT_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)
15534 stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, codepoint);
15543static int stbtt_BakeFontBitmap_internal(
unsigned char *data,
int offset,
15544 float pixel_height,
15545 unsigned char *pixels,
int pw,
int ph,
15546 int first_char,
int num_chars,
15547 stbtt_bakedchar *chardata)
15550 int x,y,bottom_y, i;
15553 if (!stbtt_InitFont(&f, data, offset))
15555 STBTT_memset(pixels, 0, pw*ph);
15559 scale = stbtt_ScaleForPixelHeight(&f, pixel_height);
15561 for (i=0; i < num_chars; ++i) {
15562 int advance, lsb, x0,y0,x1,y1,gw,gh;
15563 int g = stbtt_FindGlyphIndex(&f, first_char + i);
15564 stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb);
15565 stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1);
15568 if (x + gw + 1 >= pw)
15569 y = bottom_y, x = 1;
15570 if (y + gh + 1 >= ph)
15572 STBTT_assert(x+gw < pw);
15573 STBTT_assert(y+gh < ph);
15574 stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g);
15575 chardata[i].x0 = (stbtt_int16) x;
15576 chardata[i].y0 = (stbtt_int16) y;
15577 chardata[i].x1 = (stbtt_int16) (x + gw);
15578 chardata[i].y1 = (stbtt_int16) (y + gh);
15579 chardata[i].xadvance = scale * advance;
15580 chardata[i].xoff = (float) x0;
15581 chardata[i].yoff = (float) y0;
15583 if (y+gh+1 > bottom_y)
15589STBTT_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)
15591 float d3d_bias = opengl_fillrule ? 0 : -0.5f;
15592 float ipw = 1.0f / pw, iph = 1.0f / ph;
15593 const stbtt_bakedchar *b = chardata + char_index;
15594 int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f);
15595 int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f);
15597 q->x0 = round_x + d3d_bias;
15598 q->y0 = round_y + d3d_bias;
15599 q->x1 = round_x + b->x1 - b->x0 + d3d_bias;
15600 q->y1 = round_y + b->y1 - b->y0 + d3d_bias;
15602 q->s0 = b->x0 * ipw;
15603 q->t0 = b->y0 * iph;
15604 q->s1 = b->x1 * ipw;
15605 q->t1 = b->y1 * iph;
15607 *xpos += b->xadvance;
15615#ifndef STB_RECT_PACK_VERSION
15617typedef int stbrp_coord;
15644 int id,w,h,was_packed;
15647static void stbrp_init_target(stbrp_context *con,
int pw,
int ph, stbrp_node *nodes,
int num_nodes)
15654 STBTT__NOTUSED(nodes);
15655 STBTT__NOTUSED(num_nodes);
15658static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects,
int num_rects)
15661 for (i=0; i < num_rects; ++i) {
15662 if (con->x + rects[i].w > con->width) {
15664 con->y = con->bottom_y;
15666 if (con->y + rects[i].h > con->height)
15668 rects[i].x = con->x;
15669 rects[i].y = con->y;
15670 rects[i].was_packed = 1;
15671 con->x += rects[i].w;
15672 if (con->y + rects[i].h > con->bottom_y)
15673 con->bottom_y = con->y + rects[i].h;
15675 for ( ; i < num_rects; ++i)
15676 rects[i].was_packed = 0;
15687STBTT_DEF
int stbtt_PackBegin(stbtt_pack_context *spc,
unsigned char *pixels,
int pw,
int ph,
int stride_in_bytes,
int padding,
void *alloc_context)
15689 stbrp_context *context = (stbrp_context *) STBTT_malloc(
sizeof(*context) ,alloc_context);
15690 int num_nodes = pw - padding;
15691 stbrp_node *nodes = (stbrp_node *) STBTT_malloc(
sizeof(*nodes ) * num_nodes,alloc_context);
15693 if (context == NULL || nodes == NULL) {
15694 if (context != NULL) STBTT_free(context, alloc_context);
15695 if (nodes != NULL) STBTT_free(nodes , alloc_context);
15699 spc->user_allocator_context = alloc_context;
15702 spc->pixels = pixels;
15703 spc->pack_info = context;
15704 spc->nodes = nodes;
15705 spc->padding = padding;
15706 spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw;
15707 spc->h_oversample = 1;
15708 spc->v_oversample = 1;
15709 spc->skip_missing = 0;
15711 stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
15714 STBTT_memset(pixels, 0, pw*ph);
15719STBTT_DEF
void stbtt_PackEnd (stbtt_pack_context *spc)
15721 STBTT_free(spc->nodes , spc->user_allocator_context);
15722 STBTT_free(spc->pack_info, spc->user_allocator_context);
15725STBTT_DEF
void stbtt_PackSetOversampling(stbtt_pack_context *spc,
unsigned int h_oversample,
unsigned int v_oversample)
15727 STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE);
15728 STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE);
15729 if (h_oversample <= STBTT_MAX_OVERSAMPLE)
15730 spc->h_oversample = h_oversample;
15731 if (v_oversample <= STBTT_MAX_OVERSAMPLE)
15732 spc->v_oversample = v_oversample;
15735STBTT_DEF
void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc,
int skip)
15737 spc->skip_missing = skip;
15740#define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1)
15742static void stbtt__h_prefilter(
unsigned char *pixels,
int w,
int h,
int stride_in_bytes,
unsigned int kernel_width)
15744 unsigned char buffer[STBTT_MAX_OVERSAMPLE];
15745 int safe_w = w - kernel_width;
15747 STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE);
15748 for (j=0; j < h; ++j) {
15750 unsigned int total;
15751 STBTT_memset(buffer, 0, kernel_width);
15756 switch (kernel_width) {
15758 for (i=0; i <= safe_w; ++i) {
15759 total += pixels[i] - buffer[i & STBTT__OVER_MASK];
15760 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
15761 pixels[i] = (
unsigned char) (total / 2);
15765 for (i=0; i <= safe_w; ++i) {
15766 total += pixels[i] - buffer[i & STBTT__OVER_MASK];
15767 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
15768 pixels[i] = (
unsigned char) (total / 3);
15772 for (i=0; i <= safe_w; ++i) {
15773 total += pixels[i] - buffer[i & STBTT__OVER_MASK];
15774 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
15775 pixels[i] = (
unsigned char) (total / 4);
15779 for (i=0; i <= safe_w; ++i) {
15780 total += pixels[i] - buffer[i & STBTT__OVER_MASK];
15781 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
15782 pixels[i] = (
unsigned char) (total / 5);
15786 for (i=0; i <= safe_w; ++i) {
15787 total += pixels[i] - buffer[i & STBTT__OVER_MASK];
15788 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
15789 pixels[i] = (
unsigned char) (total / kernel_width);
15794 for (; i < w; ++i) {
15795 STBTT_assert(pixels[i] == 0);
15796 total -= buffer[i & STBTT__OVER_MASK];
15797 pixels[i] = (
unsigned char) (total / kernel_width);
15800 pixels += stride_in_bytes;
15804static void stbtt__v_prefilter(
unsigned char *pixels,
int w,
int h,
int stride_in_bytes,
unsigned int kernel_width)
15806 unsigned char buffer[STBTT_MAX_OVERSAMPLE];
15807 int safe_h = h - kernel_width;
15809 STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE);
15810 for (j=0; j < w; ++j) {
15812 unsigned int total;
15813 STBTT_memset(buffer, 0, kernel_width);
15818 switch (kernel_width) {
15820 for (i=0; i <= safe_h; ++i) {
15821 total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
15822 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
15823 pixels[i*stride_in_bytes] = (
unsigned char) (total / 2);
15827 for (i=0; i <= safe_h; ++i) {
15828 total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
15829 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
15830 pixels[i*stride_in_bytes] = (
unsigned char) (total / 3);
15834 for (i=0; i <= safe_h; ++i) {
15835 total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
15836 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
15837 pixels[i*stride_in_bytes] = (
unsigned char) (total / 4);
15841 for (i=0; i <= safe_h; ++i) {
15842 total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
15843 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
15844 pixels[i*stride_in_bytes] = (
unsigned char) (total / 5);
15848 for (i=0; i <= safe_h; ++i) {
15849 total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
15850 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
15851 pixels[i*stride_in_bytes] = (
unsigned char) (total / kernel_width);
15856 for (; i < h; ++i) {
15857 STBTT_assert(pixels[i*stride_in_bytes] == 0);
15858 total -= buffer[i & STBTT__OVER_MASK];
15859 pixels[i*stride_in_bytes] = (
unsigned char) (total / kernel_width);
15866static float stbtt__oversample_shift(
int oversample)
15875 return (
float)-(oversample - 1) / (2.0f * (
float)oversample);
15879STBTT_DEF
int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc,
const stbtt_fontinfo *info, stbtt_pack_range *ranges,
int num_ranges, stbrp_rect *rects)
15882 int missing_glyph_added = 0;
15885 for (i=0; i < num_ranges; ++i) {
15886 float fh = ranges[i].font_size;
15887 float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh);
15888 ranges[i].h_oversample = (
unsigned char) spc->h_oversample;
15889 ranges[i].v_oversample = (
unsigned char) spc->v_oversample;
15890 for (j=0; j < ranges[i].num_chars; ++j) {
15892 int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
15893 int glyph = stbtt_FindGlyphIndex(info, codepoint);
15894 if (glyph == 0 && (spc->skip_missing || missing_glyph_added)) {
15895 rects[k].w = rects[k].h = 0;
15897 stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
15898 scale * spc->h_oversample,
15899 scale * spc->v_oversample,
15902 rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
15903 rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
15905 missing_glyph_added = 1;
15914STBTT_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)
15916 stbtt_MakeGlyphBitmapSubpixel(info,
15918 out_w - (prefilter_x - 1),
15919 out_h - (prefilter_y - 1),
15927 if (prefilter_x > 1)
15928 stbtt__h_prefilter(output, out_w, out_h, out_stride, prefilter_x);
15930 if (prefilter_y > 1)
15931 stbtt__v_prefilter(output, out_w, out_h, out_stride, prefilter_y);
15933 *sub_x = stbtt__oversample_shift(prefilter_x);
15934 *sub_y = stbtt__oversample_shift(prefilter_y);
15938STBTT_DEF
int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc,
const stbtt_fontinfo *info, stbtt_pack_range *ranges,
int num_ranges, stbrp_rect *rects)
15940 int i,j,k, missing_glyph = -1, return_value = 1;
15943 int old_h_over = spc->h_oversample;
15944 int old_v_over = spc->v_oversample;
15947 for (i=0; i < num_ranges; ++i) {
15948 float fh = ranges[i].font_size;
15949 float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh);
15950 float recip_h,recip_v,sub_x,sub_y;
15951 spc->h_oversample = ranges[i].h_oversample;
15952 spc->v_oversample = ranges[i].v_oversample;
15953 recip_h = 1.0f / spc->h_oversample;
15954 recip_v = 1.0f / spc->v_oversample;
15955 sub_x = stbtt__oversample_shift(spc->h_oversample);
15956 sub_y = stbtt__oversample_shift(spc->v_oversample);
15957 for (j=0; j < ranges[i].num_chars; ++j) {
15958 stbrp_rect *r = &rects[k];
15959 if (r->was_packed && r->w != 0 && r->h != 0) {
15960 stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
15961 int advance, lsb, x0,y0,x1,y1;
15962 int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
15963 int glyph = stbtt_FindGlyphIndex(info, codepoint);
15964 stbrp_coord pad = (stbrp_coord) spc->padding;
15971 stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb);
15972 stbtt_GetGlyphBitmapBox(info, glyph,
15973 scale * spc->h_oversample,
15974 scale * spc->v_oversample,
15976 stbtt_MakeGlyphBitmapSubpixel(info,
15977 spc->pixels + r->x + r->y*spc->stride_in_bytes,
15978 r->w - spc->h_oversample+1,
15979 r->h - spc->v_oversample+1,
15980 spc->stride_in_bytes,
15981 scale * spc->h_oversample,
15982 scale * spc->v_oversample,
15986 if (spc->h_oversample > 1)
15987 stbtt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
15988 r->w, r->h, spc->stride_in_bytes,
15989 spc->h_oversample);
15991 if (spc->v_oversample > 1)
15992 stbtt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
15993 r->w, r->h, spc->stride_in_bytes,
15994 spc->v_oversample);
15996 bc->x0 = (stbtt_int16) r->x;
15997 bc->y0 = (stbtt_int16) r->y;
15998 bc->x1 = (stbtt_int16) (r->x + r->w);
15999 bc->y1 = (stbtt_int16) (r->y + r->h);
16000 bc->xadvance = scale * advance;
16001 bc->xoff = (float) x0 * recip_h + sub_x;
16002 bc->yoff = (float) y0 * recip_v + sub_y;
16003 bc->xoff2 = (x0 + r->w) * recip_h + sub_x;
16004 bc->yoff2 = (y0 + r->h) * recip_v + sub_y;
16008 }
else if (spc->skip_missing) {
16010 }
else if (r->was_packed && r->w == 0 && r->h == 0 && missing_glyph >= 0) {
16011 ranges[i].chardata_for_range[j] = ranges[i].chardata_for_range[missing_glyph];
16021 spc->h_oversample = old_h_over;
16022 spc->v_oversample = old_v_over;
16024 return return_value;
16027STBTT_DEF
void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects,
int num_rects)
16029 stbrp_pack_rects((stbrp_context *) spc->pack_info, rects, num_rects);
16032STBTT_DEF
int stbtt_PackFontRanges(stbtt_pack_context *spc,
const unsigned char *fontdata,
int font_index, stbtt_pack_range *ranges,
int num_ranges)
16034 stbtt_fontinfo info;
16035 int i,j,n, return_value = 1;
16040 for (i=0; i < num_ranges; ++i)
16041 for (j=0; j < ranges[i].num_chars; ++j)
16042 ranges[i].chardata_for_range[j].x0 =
16043 ranges[i].chardata_for_range[j].y0 =
16044 ranges[i].chardata_for_range[j].x1 =
16045 ranges[i].chardata_for_range[j].y1 = 0;
16048 for (i=0; i < num_ranges; ++i)
16049 n += ranges[i].num_chars;
16051 rects = (stbrp_rect *) STBTT_malloc(
sizeof(*rects) * n, spc->user_allocator_context);
16055 info.userdata = spc->user_allocator_context;
16056 stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index));
16058 n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects);
16060 stbtt_PackFontRangesPackRects(spc, rects, n);
16062 return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects);
16064 STBTT_free(rects, spc->user_allocator_context);
16065 return return_value;
16068STBTT_DEF
int stbtt_PackFontRange(stbtt_pack_context *spc,
const unsigned char *fontdata,
int font_index,
float font_size,
16069 int first_unicode_codepoint_in_range,
int num_chars_in_range, stbtt_packedchar *chardata_for_range)
16071 stbtt_pack_range range;
16072 range.first_unicode_codepoint_in_range = first_unicode_codepoint_in_range;
16073 range.array_of_unicode_codepoints = NULL;
16074 range.num_chars = num_chars_in_range;
16075 range.chardata_for_range = chardata_for_range;
16076 range.font_size = font_size;
16077 return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
16080STBTT_DEF
void stbtt_GetScaledFontVMetrics(
const unsigned char *fontdata,
int index,
float size,
float *ascent,
float *descent,
float *lineGap)
16082 int i_ascent, i_descent, i_lineGap;
16084 stbtt_fontinfo info;
16085 stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, index));
16086 scale = size > 0 ? stbtt_ScaleForPixelHeight(&info, size) : stbtt_ScaleForMappingEmToPixels(&info, -size);
16087 stbtt_GetFontVMetrics(&info, &i_ascent, &i_descent, &i_lineGap);
16088 *ascent = (float) i_ascent * scale;
16089 *descent = (float) i_descent * scale;
16090 *lineGap = (float) i_lineGap * scale;
16093STBTT_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)
16095 float ipw = 1.0f / pw, iph = 1.0f / ph;
16096 const stbtt_packedchar *b = chardata + char_index;
16098 if (align_to_integer) {
16099 float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5f);
16100 float y = (float) STBTT_ifloor((*ypos + b->yoff) + 0.5f);
16103 q->x1 = x + b->xoff2 - b->xoff;
16104 q->y1 = y + b->yoff2 - b->yoff;
16106 q->x0 = *xpos + b->xoff;
16107 q->y0 = *ypos + b->yoff;
16108 q->x1 = *xpos + b->xoff2;
16109 q->y1 = *ypos + b->yoff2;
16112 q->s0 = b->x0 * ipw;
16113 q->t0 = b->y0 * iph;
16114 q->s1 = b->x1 * ipw;
16115 q->t1 = b->y1 * iph;
16117 *xpos += b->xadvance;
16125#define STBTT_min(a,b) ((a) < (b) ? (a) : (b))
16126#define STBTT_max(a,b) ((a) < (b) ? (b) : (a))
16128static int stbtt__ray_intersect_bezier(
float orig[2],
float ray[2],
float q0[2],
float q1[2],
float q2[2],
float hits[2][2])
16130 float q0perp = q0[1]*ray[0] - q0[0]*ray[1];
16131 float q1perp = q1[1]*ray[0] - q1[0]*ray[1];
16132 float q2perp = q2[1]*ray[0] - q2[0]*ray[1];
16133 float roperp = orig[1]*ray[0] - orig[0]*ray[1];
16135 float a = q0perp - 2*q1perp + q2perp;
16136 float b = q1perp - q0perp;
16137 float c = q0perp - roperp;
16139 float s0 = 0., s1 = 0.;
16143 float discr = b*b - a*c;
16145 float rcpna = -1 / a;
16146 float d = (float) STBTT_sqrt(discr);
16147 s0 = (b+d) * rcpna;
16148 s1 = (b-d) * rcpna;
16149 if (s0 >= 0.0 && s0 <= 1.0)
16151 if (d > 0.0 && s1 >= 0.0 && s1 <= 1.0) {
16152 if (num_s == 0) s0 = s1;
16160 if (s0 >= 0.0 && s0 <= 1.0)
16167 float rcp_len2 = 1 / (ray[0]*ray[0] + ray[1]*ray[1]);
16168 float rayn_x = ray[0] * rcp_len2, rayn_y = ray[1] * rcp_len2;
16170 float q0d = q0[0]*rayn_x + q0[1]*rayn_y;
16171 float q1d = q1[0]*rayn_x + q1[1]*rayn_y;
16172 float q2d = q2[0]*rayn_x + q2[1]*rayn_y;
16173 float rod = orig[0]*rayn_x + orig[1]*rayn_y;
16175 float q10d = q1d - q0d;
16176 float q20d = q2d - q0d;
16177 float q0rd = q0d - rod;
16179 hits[0][0] = q0rd + s0*(2.0f - 2.0f*s0)*q10d + s0*s0*q20d;
16180 hits[0][1] = a*s0+b;
16183 hits[1][0] = q0rd + s1*(2.0f - 2.0f*s1)*q10d + s1*s1*q20d;
16184 hits[1][1] = a*s1+b;
16192static int equal(
float *a,
float *b)
16194 return (a[0] == b[0] && a[1] == b[1]);
16197static int stbtt__compute_crossings_x(
float x,
float y,
int nverts, stbtt_vertex *verts)
16200 float orig[2], ray[2] = { 1, 0 };
16205 y_frac = (float) STBTT_fmod(y, 1.0f);
16206 if (y_frac < 0.01f)
16208 else if (y_frac > 0.99f)
16215 for (i=0; i < nverts; ++i) {
16216 if (verts[i].type == STBTT_vline) {
16217 int x0 = (int) verts[i-1].x, y0 = (
int) verts[i-1].y;
16218 int x1 = (int) verts[i ].x, y1 = (
int) verts[i ].y;
16219 if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) {
16220 float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0;
16222 winding += (y0 < y1) ? 1 : -1;
16225 if (verts[i].type == STBTT_vcurve) {
16226 int x0 = (int) verts[i-1].x , y0 = (
int) verts[i-1].y ;
16227 int x1 = (int) verts[i ].cx, y1 = (
int) verts[i ].cy;
16228 int x2 = (int) verts[i ].x , y2 = (
int) verts[i ].y ;
16229 int ax = STBTT_min(x0,STBTT_min(x1,x2)), ay = STBTT_min(y0,STBTT_min(y1,y2));
16230 int by = STBTT_max(y0,STBTT_max(y1,y2));
16231 if (y > ay && y < by && x > ax) {
16232 float q0[2],q1[2],q2[2];
16240 if (equal(q0,q1) || equal(q1,q2)) {
16241 x0 = (int)verts[i-1].x;
16242 y0 = (int)verts[i-1].y;
16243 x1 = (int)verts[i ].x;
16244 y1 = (int)verts[i ].y;
16245 if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) {
16246 float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0;
16248 winding += (y0 < y1) ? 1 : -1;
16251 int num_hits = stbtt__ray_intersect_bezier(orig, ray, q0, q1, q2, hits);
16253 if (hits[0][0] < 0)
16254 winding += (hits[0][1] < 0 ? -1 : 1);
16256 if (hits[1][0] < 0)
16257 winding += (hits[1][1] < 0 ? -1 : 1);
16265static float stbtt__cuberoot(
float x )
16268 return -(float) STBTT_pow(-x,1.0f/3.0f);
16270 return (
float) STBTT_pow( x,1.0f/3.0f);
16274static int stbtt__solve_cubic(
float a,
float b,
float c,
float* r)
16277 float p = b - a*a / 3;
16278 float q = a * (2*a*a - 9*b) / 27 + c;
16280 float d = q*q + 4*p3 / 27;
16282 float z = (float) STBTT_sqrt(d);
16283 float u = (-q + z) / 2;
16284 float v = (-q - z) / 2;
16285 u = stbtt__cuberoot(u);
16286 v = stbtt__cuberoot(v);
16290 float u = (float) STBTT_sqrt(-p/3);
16291 float v = (float) STBTT_acos(-STBTT_sqrt(-27/p3) * q / 2) / 3;
16292 float m = (float) STBTT_cos(v);
16293 float n = (float) STBTT_cos(v-3.141592/2)*1.732050808f;
16294 r[0] = s + u * 2 * m;
16295 r[1] = s - u * (m + n);
16296 r[2] = s - u * (m - n);
16305STBTT_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)
16307 float scale_x = scale, scale_y = scale;
16308 int ix0,iy0,ix1,iy1;
16310 unsigned char *data;
16312 if (scale == 0)
return NULL;
16314 stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f,0.0f, &ix0,&iy0,&ix1,&iy1);
16317 if (ix0 == ix1 || iy0 == iy1)
16328 if (width ) *width = w;
16329 if (height) *height = h;
16330 if (xoff ) *xoff = ix0;
16331 if (yoff ) *yoff = iy0;
16334 scale_y = -scale_y;
16339 stbtt_vertex *verts;
16340 int num_verts = stbtt_GetGlyphShape(info, glyph, &verts);
16341 data = (
unsigned char *) STBTT_malloc(w * h, info->userdata);
16342 precompute = (
float *) STBTT_malloc(num_verts *
sizeof(
float), info->userdata);
16344 for (i=0,j=num_verts-1; i < num_verts; j=i++) {
16345 if (verts[i].type == STBTT_vline) {
16346 float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y;
16347 float x1 = verts[j].x*scale_x, y1 = verts[j].y*scale_y;
16348 float dist = (float) STBTT_sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));
16349 precompute[i] = (dist == 0) ? 0.0f : 1.0f / dist;
16350 }
else if (verts[i].type == STBTT_vcurve) {
16351 float x2 = verts[j].x *scale_x, y2 = verts[j].y *scale_y;
16352 float x1 = verts[i].cx*scale_x, y1 = verts[i].cy*scale_y;
16353 float x0 = verts[i].x *scale_x, y0 = verts[i].y *scale_y;
16354 float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
16355 float len2 = bx*bx + by*by;
16357 precompute[i] = 1.0f / (bx*bx + by*by);
16359 precompute[i] = 0.0f;
16361 precompute[i] = 0.0f;
16364 for (y=iy0; y < iy1; ++y) {
16365 for (x=ix0; x < ix1; ++x) {
16367 float min_dist = 999999.0f;
16368 float sx = (float) x + 0.5f;
16369 float sy = (float) y + 0.5f;
16370 float x_gspace = (sx / scale_x);
16371 float y_gspace = (sy / scale_y);
16373 int winding = stbtt__compute_crossings_x(x_gspace, y_gspace, num_verts, verts);
16375 for (i=0; i < num_verts; ++i) {
16376 float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y;
16378 if (verts[i].type == STBTT_vline && precompute[i] != 0.0f) {
16379 float x1 = verts[i-1].x*scale_x, y1 = verts[i-1].y*scale_y;
16381 float dist,dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy);
16382 if (dist2 < min_dist*min_dist)
16383 min_dist = (float) STBTT_sqrt(dist2);
16388 dist = (float) STBTT_fabs((x1-x0)*(y0-sy) - (y1-y0)*(x0-sx)) * precompute[i];
16389 STBTT_assert(i != 0);
16390 if (dist < min_dist) {
16394 float dx = x1-x0, dy = y1-y0;
16395 float px = x0-sx, py = y0-sy;
16398 float t = -(px*dx + py*dy) / (dx*dx + dy*dy);
16399 if (t >= 0.0f && t <= 1.0f)
16402 }
else if (verts[i].type == STBTT_vcurve) {
16403 float x2 = verts[i-1].x *scale_x, y2 = verts[i-1].y *scale_y;
16404 float x1 = verts[i ].cx*scale_x, y1 = verts[i ].cy*scale_y;
16405 float box_x0 = STBTT_min(STBTT_min(x0,x1),x2);
16406 float box_y0 = STBTT_min(STBTT_min(y0,y1),y2);
16407 float box_x1 = STBTT_max(STBTT_max(x0,x1),x2);
16408 float box_y1 = STBTT_max(STBTT_max(y0,y1),y2);
16410 if (sx > box_x0-min_dist && sx < box_x1+min_dist && sy > box_y0-min_dist && sy < box_y1+min_dist) {
16412 float ax = x1-x0, ay = y1-y0;
16413 float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
16414 float mx = x0 - sx, my = y0 - sy;
16415 float res[3] = {0.f,0.f,0.f};
16416 float px,py,t,it,dist2;
16417 float a_inv = precompute[i];
16418 if (a_inv == 0.0) {
16419 float a = 3*(ax*bx + ay*by);
16420 float b = 2*(ax*ax + ay*ay) + (mx*bx+my*by);
16421 float c = mx*ax+my*ay;
16427 float discriminant = b*b - 4*a*c;
16428 if (discriminant < 0)
16431 float root = (float) STBTT_sqrt(discriminant);
16432 res[0] = (-b - root)/(2*a);
16433 res[1] = (-b + root)/(2*a);
16438 float b = 3*(ax*bx + ay*by) * a_inv;
16439 float c = (2*(ax*ax + ay*ay) + (mx*bx+my*by)) * a_inv;
16440 float d = (mx*ax+my*ay) * a_inv;
16441 num = stbtt__solve_cubic(b, c, d, res);
16443 dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy);
16444 if (dist2 < min_dist*min_dist)
16445 min_dist = (float) STBTT_sqrt(dist2);
16447 if (num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) {
16448 t = res[0], it = 1.0f - t;
16449 px = it*it*x0 + 2*t*it*x1 + t*t*x2;
16450 py = it*it*y0 + 2*t*it*y1 + t*t*y2;
16451 dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
16452 if (dist2 < min_dist * min_dist)
16453 min_dist = (float) STBTT_sqrt(dist2);
16455 if (num >= 2 && res[1] >= 0.0f && res[1] <= 1.0f) {
16456 t = res[1], it = 1.0f - t;
16457 px = it*it*x0 + 2*t*it*x1 + t*t*x2;
16458 py = it*it*y0 + 2*t*it*y1 + t*t*y2;
16459 dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
16460 if (dist2 < min_dist * min_dist)
16461 min_dist = (float) STBTT_sqrt(dist2);
16463 if (num >= 3 && res[2] >= 0.0f && res[2] <= 1.0f) {
16464 t = res[2], it = 1.0f - t;
16465 px = it*it*x0 + 2*t*it*x1 + t*t*x2;
16466 py = it*it*y0 + 2*t*it*y1 + t*t*y2;
16467 dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
16468 if (dist2 < min_dist * min_dist)
16469 min_dist = (float) STBTT_sqrt(dist2);
16475 min_dist = -min_dist;
16476 val = onedge_value + pixel_dist_scale * min_dist;
16479 else if (val > 255)
16481 data[(y-iy0)*w+(x-ix0)] = (
unsigned char) val;
16484 STBTT_free(precompute, info->userdata);
16485 STBTT_free(verts, info->userdata);
16490STBTT_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)
16492 return stbtt_GetGlyphSDF(info, scale, stbtt_FindGlyphIndex(info, codepoint), padding, onedge_value, pixel_dist_scale, width, height, xoff, yoff);
16495STBTT_DEF
void stbtt_FreeSDF(
unsigned char *bitmap,
void *userdata)
16497 STBTT_free(bitmap, userdata);
16506static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2)
16512 stbtt_uint16 ch = s2[0]*256 + s2[1];
16514 if (i >= len1)
return -1;
16515 if (s1[i++] != ch)
return -1;
16516 }
else if (ch < 0x800) {
16517 if (i+1 >= len1)
return -1;
16518 if (s1[i++] != 0xc0 + (ch >> 6))
return -1;
16519 if (s1[i++] != 0x80 + (ch & 0x3f))
return -1;
16520 }
else if (ch >= 0xd800 && ch < 0xdc00) {
16522 stbtt_uint16 ch2 = s2[2]*256 + s2[3];
16523 if (i+3 >= len1)
return -1;
16524 c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000;
16525 if (s1[i++] != 0xf0 + (c >> 18))
return -1;
16526 if (s1[i++] != 0x80 + ((c >> 12) & 0x3f))
return -1;
16527 if (s1[i++] != 0x80 + ((c >> 6) & 0x3f))
return -1;
16528 if (s1[i++] != 0x80 + ((c ) & 0x3f))
return -1;
16531 }
else if (ch >= 0xdc00 && ch < 0xe000) {
16534 if (i+2 >= len1)
return -1;
16535 if (s1[i++] != 0xe0 + (ch >> 12))
return -1;
16536 if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f))
return -1;
16537 if (s1[i++] != 0x80 + ((ch ) & 0x3f))
return -1;
16545static int stbtt_CompareUTF8toUTF16_bigendian_internal(
char *s1,
int len1,
char *s2,
int len2)
16547 return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8*) s1, len1, (stbtt_uint8*) s2, len2);
16552STBTT_DEF
const char *stbtt_GetFontNameString(
const stbtt_fontinfo *font,
int *length,
int platformID,
int encodingID,
int languageID,
int nameID)
16554 stbtt_int32 i,count,stringOffset;
16555 stbtt_uint8 *fc = font->data;
16556 stbtt_uint32 offset = font->fontstart;
16557 stbtt_uint32 nm = stbtt__find_table(fc, offset,
"name");
16558 if (!nm)
return NULL;
16560 count = ttUSHORT(fc+nm+2);
16561 stringOffset = nm + ttUSHORT(fc+nm+4);
16562 for (i=0; i < count; ++i) {
16563 stbtt_uint32 loc = nm + 6 + 12 * i;
16564 if (platformID == ttUSHORT(fc+loc+0) && encodingID == ttUSHORT(fc+loc+2)
16565 && languageID == ttUSHORT(fc+loc+4) && nameID == ttUSHORT(fc+loc+6)) {
16566 *length = ttUSHORT(fc+loc+8);
16567 return (
const char *) (fc+stringOffset+ttUSHORT(fc+loc+10));
16573static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id)
16576 stbtt_int32 count = ttUSHORT(fc+nm+2);
16577 stbtt_int32 stringOffset = nm + ttUSHORT(fc+nm+4);
16579 for (i=0; i < count; ++i) {
16580 stbtt_uint32 loc = nm + 6 + 12 * i;
16581 stbtt_int32
id = ttUSHORT(fc+loc+6);
16582 if (
id == target_id) {
16584 stbtt_int32 platform = ttUSHORT(fc+loc+0), encoding = ttUSHORT(fc+loc+2), language = ttUSHORT(fc+loc+4);
16587 if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) {
16588 stbtt_int32 slen = ttUSHORT(fc+loc+8);
16589 stbtt_int32 off = ttUSHORT(fc+loc+10);
16592 stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen);
16593 if (matchlen >= 0) {
16595 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) {
16596 slen = ttUSHORT(fc+loc+12+8);
16597 off = ttUSHORT(fc+loc+12+10);
16599 if (matchlen == nlen)
16601 }
else if (matchlen < nlen && name[matchlen] ==
' ') {
16603 if (stbtt_CompareUTF8toUTF16_bigendian_internal((
char*) (name+matchlen), nlen-matchlen, (
char*)(fc+stringOffset+off),slen))
16608 if (matchlen == nlen)
16620static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags)
16622 stbtt_int32 nlen = (stbtt_int32) STBTT_strlen((
char *) name);
16623 stbtt_uint32 nm,hd;
16624 if (!stbtt__isfont(fc+offset))
return 0;
16628 hd = stbtt__find_table(fc, offset,
"head");
16629 if ((ttUSHORT(fc+hd+44) & 7) != (flags & 7))
return 0;
16632 nm = stbtt__find_table(fc, offset,
"name");
16637 if (stbtt__matchpair(fc, nm, name, nlen, 16, -1))
return 1;
16638 if (stbtt__matchpair(fc, nm, name, nlen, 1, -1))
return 1;
16639 if (stbtt__matchpair(fc, nm, name, nlen, 3, -1))
return 1;
16641 if (stbtt__matchpair(fc, nm, name, nlen, 16, 17))
return 1;
16642 if (stbtt__matchpair(fc, nm, name, nlen, 1, 2))
return 1;
16643 if (stbtt__matchpair(fc, nm, name, nlen, 3, -1))
return 1;
16649static int stbtt_FindMatchingFont_internal(
unsigned char *font_collection,
char *name_utf8, stbtt_int32 flags)
16653 stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i);
16654 if (off < 0)
return off;
16655 if (stbtt__matches((stbtt_uint8 *) font_collection, off, (stbtt_uint8*) name_utf8, flags))
16660#if defined(__GNUC__) || defined(__clang__)
16661#pragma GCC diagnostic push
16662#pragma GCC diagnostic ignored "-Wcast-qual"
16665STBTT_DEF
int stbtt_BakeFontBitmap(
const unsigned char *data,
int offset,
16666 float pixel_height,
unsigned char *pixels,
int pw,
int ph,
16667 int first_char,
int num_chars, stbtt_bakedchar *chardata)
16669 return stbtt_BakeFontBitmap_internal((
unsigned char *) data, offset, pixel_height, pixels, pw, ph, first_char, num_chars, chardata);
16672STBTT_DEF
int stbtt_GetFontOffsetForIndex(
const unsigned char *data,
int index)
16674 return stbtt_GetFontOffsetForIndex_internal((
unsigned char *) data, index);
16677STBTT_DEF
int stbtt_GetNumberOfFonts(
const unsigned char *data)
16679 return stbtt_GetNumberOfFonts_internal((
unsigned char *) data);
16682STBTT_DEF
int stbtt_InitFont(stbtt_fontinfo *info,
const unsigned char *data,
int offset)
16684 return stbtt_InitFont_internal(info, (
unsigned char *) data, offset);
16687STBTT_DEF
int stbtt_FindMatchingFont(
const unsigned char *fontdata,
const char *name,
int flags)
16689 return stbtt_FindMatchingFont_internal((
unsigned char *) fontdata, (
char *) name, flags);
16692STBTT_DEF
int stbtt_CompareUTF8toUTF16_bigendian(
const char *s1,
int len1,
const char *s2,
int len2)
16694 return stbtt_CompareUTF8toUTF16_bigendian_internal((
char *) s1, len1, (
char *) s2, len2);
16697#if defined(__GNUC__) || defined(__clang__)
16698#pragma GCC diagnostic pop
16812#ifdef NK_INCLUDE_FONT_BAKING
16828#define STBTT_MAX_OVERSAMPLE 8
16836struct nk_font_bake_data {
16837 struct stbtt_fontinfo info;
16838 struct stbrp_rect *rects;
16839 stbtt_pack_range *ranges;
16840 nk_rune range_count;
16843struct nk_font_baker {
16845 struct stbtt_pack_context spc;
16846 struct nk_font_bake_data *build;
16847 stbtt_packedchar *packed_chars;
16848 struct stbrp_rect *rects;
16849 stbtt_pack_range *ranges;
16852NK_GLOBAL
const nk_size nk_rect_align = NK_ALIGNOF(
struct stbrp_rect);
16853NK_GLOBAL
const nk_size nk_range_align = NK_ALIGNOF(stbtt_pack_range);
16854NK_GLOBAL
const nk_size nk_char_align = NK_ALIGNOF(stbtt_packedchar);
16855NK_GLOBAL
const nk_size nk_build_align = NK_ALIGNOF(
struct nk_font_bake_data);
16856NK_GLOBAL
const nk_size nk_baker_align = NK_ALIGNOF(
struct nk_font_baker);
16859nk_range_count(
const nk_rune *range)
16861 const nk_rune *iter = range;
16863 if (!range)
return 0;
16864 while (*(iter++) != 0);
16865 return (iter == range) ? 0 : (int)((iter - range)/2);
16868nk_range_glyph_count(
const nk_rune *range,
int count)
16871 int total_glyphs = 0;
16872 for (i = 0; i < count; ++i) {
16874 nk_rune f = range[(i*2)+0];
16875 nk_rune t = range[(i*2)+1];
16877 diff = (int)((t - f) + 1);
16878 total_glyphs += diff;
16880 return total_glyphs;
16882NK_API
const nk_rune*
16883nk_font_default_glyph_ranges(
void)
16885 NK_STORAGE
const nk_rune ranges[] = {0x0020, 0x00FF, 0};
16888NK_API
const nk_rune*
16889nk_font_chinese_glyph_ranges(
void)
16891 NK_STORAGE
const nk_rune ranges[] = {
16901NK_API
const nk_rune*
16902nk_font_cyrillic_glyph_ranges(
void)
16904 NK_STORAGE
const nk_rune ranges[] = {
16913NK_API
const nk_rune*
16914nk_font_korean_glyph_ranges(
void)
16916 NK_STORAGE
const nk_rune ranges[] = {
16925nk_font_baker_memory(nk_size *temp,
int *glyph_count,
16926 struct nk_font_config *config_list,
int count)
16928 int range_count = 0;
16929 int total_range_count = 0;
16930 struct nk_font_config *iter, *i;
16932 NK_ASSERT(config_list);
16933 NK_ASSERT(glyph_count);
16934 if (!config_list) {
16940 for (iter = config_list; iter; iter = iter->next) {
16942 do {
if (!i->range) iter->range = nk_font_default_glyph_ranges();
16943 range_count = nk_range_count(i->range);
16944 total_range_count += range_count;
16945 *glyph_count += nk_range_glyph_count(i->range, range_count);
16946 }
while ((i = i->n) != iter);
16948 *temp = (nk_size)*glyph_count *
sizeof(
struct stbrp_rect);
16949 *temp += (nk_size)total_range_count *
sizeof(stbtt_pack_range);
16950 *temp += (nk_size)*glyph_count *
sizeof(stbtt_packedchar);
16951 *temp += (nk_size)count *
sizeof(
struct nk_font_bake_data);
16952 *temp +=
sizeof(
struct nk_font_baker);
16953 *temp += nk_rect_align + nk_range_align + nk_char_align;
16954 *temp += nk_build_align + nk_baker_align;
16956NK_INTERN
struct nk_font_baker*
16957nk_font_baker(
void *memory,
int glyph_count,
int count,
const struct nk_allocator *alloc)
16959 struct nk_font_baker *baker;
16960 if (!memory)
return 0;
16962 baker = (
struct nk_font_baker*)NK_ALIGN_PTR(memory, nk_baker_align);
16963 baker->build = (
struct nk_font_bake_data*)NK_ALIGN_PTR((baker + 1), nk_build_align);
16964 baker->packed_chars = (stbtt_packedchar*)NK_ALIGN_PTR((baker->build + count), nk_char_align);
16965 baker->rects = (
struct stbrp_rect*)NK_ALIGN_PTR((baker->packed_chars + glyph_count), nk_rect_align);
16966 baker->ranges = (stbtt_pack_range*)NK_ALIGN_PTR((baker->rects + glyph_count), nk_range_align);
16967 baker->alloc = *alloc;
16971nk_font_bake_pack(
struct nk_font_baker *baker,
16972 nk_size *image_memory,
int *width,
int *height,
struct nk_recti *custom,
16973 const struct nk_font_config *config_list,
int count,
16976 NK_STORAGE
const nk_size max_height = 1024 * 32;
16977 const struct nk_font_config *config_iter, *it;
16978 int total_glyph_count = 0;
16979 int total_range_count = 0;
16980 int range_count = 0;
16983 NK_ASSERT(image_memory);
16986 NK_ASSERT(config_list);
16990 if (!image_memory || !width || !height || !config_list || !count)
return nk_false;
16991 for (config_iter = config_list; config_iter; config_iter = config_iter->next) {
16993 do {range_count = nk_range_count(it->range);
16994 total_range_count += range_count;
16995 total_glyph_count += nk_range_glyph_count(it->range, range_count);
16996 }
while ((it = it->n) != config_iter);
16999 for (config_iter = config_list; config_iter; config_iter = config_iter->next) {
17002 struct stbtt_fontinfo *font_info = &baker->build[i++].info;
17003 font_info->userdata = (
void*)alloc;
17005 if (!stbtt_InitFont(font_info, (
const unsigned char*)it->ttf_blob, stbtt_GetFontOffsetForIndex((
const unsigned char*)it->ttf_blob, 0)))
17007 }
while ((it = it->n) != config_iter);
17010 *width = (total_glyph_count > 1000) ? 1024 : 512;
17011 stbtt_PackBegin(&baker->spc, 0, (
int)*width, (
int)max_height, 0, 1, (
void*)alloc);
17020 struct stbrp_rect custom_space;
17021 nk_zero(&custom_space,
sizeof(custom_space));
17022 custom_space.w = (stbrp_coord)(custom->w);
17023 custom_space.h = (stbrp_coord)(custom->h);
17025 stbtt_PackSetOversampling(&baker->spc, 1, 1);
17026 stbrp_pack_rects((
struct stbrp_context*)baker->spc.pack_info, &custom_space, 1);
17027 *height = NK_MAX(*height, (
int)(custom_space.y + custom_space.h));
17029 custom->x = (short)custom_space.x;
17030 custom->y = (short)custom_space.y;
17031 custom->w = (short)custom_space.w;
17032 custom->h = (short)custom_space.h;
17036 for (input_i = 0, config_iter = config_list; input_i < count && config_iter;
17037 config_iter = config_iter->next) {
17041 const nk_rune *in_range;
17042 const struct nk_font_config *cfg = it;
17043 struct nk_font_bake_data *tmp = &baker->build[input_i++];
17046 glyph_count = 0; range_count = 0;
17047 for (in_range = cfg->range; in_range[0] && in_range[1]; in_range += 2) {
17048 glyph_count += (int)(in_range[1] - in_range[0]) + 1;
17053 tmp->ranges = baker->ranges + range_n;
17054 tmp->range_count = (nk_rune)range_count;
17055 range_n += range_count;
17056 for (i = 0; i < range_count; ++i) {
17057 in_range = &cfg->range[i * 2];
17058 tmp->ranges[i].font_size = cfg->size;
17059 tmp->ranges[i].first_unicode_codepoint_in_range = (int)in_range[0];
17060 tmp->ranges[i].num_chars = (int)(in_range[1]- in_range[0]) + 1;
17061 tmp->ranges[i].chardata_for_range = baker->packed_chars + char_n;
17062 char_n += tmp->ranges[i].num_chars;
17066 tmp->rects = baker->rects + rect_n;
17067 rect_n += glyph_count;
17068 stbtt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v);
17069 n = stbtt_PackFontRangesGatherRects(&baker->spc, &tmp->info,
17070 tmp->ranges, (
int)tmp->range_count, tmp->rects);
17071 stbrp_pack_rects((
struct stbrp_context*)baker->spc.pack_info, tmp->rects, (
int)n);
17074 for (i = 0; i < n; ++i) {
17075 if (tmp->rects[i].was_packed)
17076 *height = NK_MAX(*height, tmp->rects[i].y + tmp->rects[i].h);
17078 }
while ((it = it->n) != config_iter);
17080 NK_ASSERT(rect_n == total_glyph_count);
17081 NK_ASSERT(char_n == total_glyph_count);
17082 NK_ASSERT(range_n == total_range_count);
17084 *height = (int)nk_round_up_pow2((nk_uint)*height);
17085 *image_memory = (nk_size)(*width) * (nk_size)(*height);
17089nk_font_bake(
struct nk_font_baker *baker,
void *image_memory,
int width,
int height,
17090 struct nk_font_glyph *glyphs,
int glyphs_count,
17091 const struct nk_font_config *config_list,
int font_count)
17094 nk_rune glyph_n = 0;
17095 const struct nk_font_config *config_iter;
17096 const struct nk_font_config *it;
17098 NK_ASSERT(image_memory);
17101 NK_ASSERT(config_list);
17103 NK_ASSERT(font_count);
17104 NK_ASSERT(glyphs_count);
17105 if (!image_memory || !width || !height || !config_list ||
17106 !font_count || !glyphs || !glyphs_count)
17110 nk_zero(image_memory, (nk_size)((nk_size)width * (nk_size)height));
17111 baker->spc.pixels = (
unsigned char*)image_memory;
17112 baker->spc.height = (int)height;
17113 for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter;
17114 config_iter = config_iter->next) {
17116 do {
const struct nk_font_config *cfg = it;
17117 struct nk_font_bake_data *tmp = &baker->build[input_i++];
17118 stbtt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v);
17119 stbtt_PackFontRangesRenderIntoRects(&baker->spc, &tmp->info, tmp->ranges, (
int)tmp->range_count, tmp->rects);
17120 }
while ((it = it->n) != config_iter);
17121 } stbtt_PackEnd(&baker->spc);
17124 for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter;
17125 config_iter = config_iter->next) {
17129 nk_rune glyph_count = 0;
17130 const struct nk_font_config *cfg = it;
17131 struct nk_font_bake_data *tmp = &baker->build[input_i++];
17132 struct nk_baked_font *dst_font = cfg->font;
17134 float font_scale = stbtt_ScaleForPixelHeight(&tmp->info, cfg->size);
17135 int unscaled_ascent, unscaled_descent, unscaled_line_gap;
17136 stbtt_GetFontVMetrics(&tmp->info, &unscaled_ascent, &unscaled_descent,
17137 &unscaled_line_gap);
17140 if (!cfg->merge_mode) {
17141 dst_font->ranges = cfg->range;
17142 dst_font->height = cfg->size;
17143 dst_font->ascent = ((float)unscaled_ascent * font_scale);
17144 dst_font->descent = ((float)unscaled_descent * font_scale);
17145 dst_font->glyph_offset = glyph_n;
17150 dst_font->glyph_count = 0;
17154 for (i = 0; i < tmp->range_count; ++i) {
17155 stbtt_pack_range *range = &tmp->ranges[i];
17156 for (char_idx = 0; char_idx < range->num_chars; char_idx++)
17158 nk_rune codepoint = 0;
17159 float dummy_x = 0, dummy_y = 0;
17160 stbtt_aligned_quad q;
17161 struct nk_font_glyph *glyph;
17164 const stbtt_packedchar *pc = &range->chardata_for_range[char_idx];
17165 codepoint = (nk_rune)(range->first_unicode_codepoint_in_range + char_idx);
17166 stbtt_GetPackedQuad(range->chardata_for_range, (
int)width,
17167 (
int)height, char_idx, &dummy_x, &dummy_y, &q, 0);
17170 glyph = &glyphs[dst_font->glyph_offset + dst_font->glyph_count + (
unsigned int)glyph_count];
17171 glyph->codepoint = codepoint;
17172 glyph->x0 = q.x0; glyph->y0 = q.y0;
17173 glyph->x1 = q.x1; glyph->y1 = q.y1;
17174 glyph->y0 += (dst_font->ascent + 0.5f);
17175 glyph->y1 += (dst_font->ascent + 0.5f);
17176 glyph->w = glyph->x1 - glyph->x0 + 0.5f;
17177 glyph->h = glyph->y1 - glyph->y0;
17179 if (cfg->coord_type == NK_COORD_PIXEL) {
17180 glyph->u0 = q.s0 * (float)width;
17181 glyph->v0 = q.t0 * (float)height;
17182 glyph->u1 = q.s1 * (float)width;
17183 glyph->v1 = q.t1 * (float)height;
17190 glyph->xadvance = (pc->xadvance + cfg->spacing.x);
17191 if (cfg->pixel_snap)
17192 glyph->xadvance = (float)(
int)(glyph->xadvance + 0.5f);
17196 dst_font->glyph_count += glyph_count;
17197 glyph_n += glyph_count;
17198 }
while ((it = it->n) != config_iter);
17202nk_font_bake_custom_data(
void *img_memory,
int img_width,
int img_height,
17203 struct nk_recti img_dst,
const char *texture_data_mask,
int tex_width,
17204 int tex_height,
char white,
char black)
17211 NK_ASSERT(img_memory);
17212 NK_ASSERT(img_width);
17213 NK_ASSERT(img_height);
17214 NK_ASSERT(texture_data_mask);
17215 NK_UNUSED(tex_height);
17216 if (!img_memory || !img_width || !img_height || !texture_data_mask)
17219 pixels = (nk_byte*)img_memory;
17220 for (y = 0, n = 0; y < tex_height; ++y) {
17221 for (x = 0; x < tex_width; ++x, ++n) {
17222 const int off0 = ((img_dst.x + x) + (img_dst.y + y) * img_width);
17223 const int off1 = off0 + 1 + tex_width;
17224 pixels[off0] = (texture_data_mask[n] == white) ? 0xFF : 0x00;
17225 pixels[off1] = (texture_data_mask[n] == black) ? 0xFF : 0x00;
17230nk_font_bake_convert(
void *out_memory,
int img_width,
int img_height,
17231 const void *in_memory)
17235 const nk_byte *src;
17237 NK_ASSERT(out_memory);
17238 NK_ASSERT(in_memory);
17239 NK_ASSERT(img_width);
17240 NK_ASSERT(img_height);
17241 if (!out_memory || !in_memory || !img_height || !img_width)
return;
17243 dst = (nk_rune*)out_memory;
17244 src = (
const nk_byte*)in_memory;
17245 for (n = (
int)(img_width * img_height); n > 0; n--)
17246 *dst++ = ((nk_rune)(*src++) << 24) | 0x00FFFFFF;
17255nk_font_text_width(
nk_handle handle,
float height,
const char *text,
int len)
17259 float text_width = 0;
17263 struct nk_font *font = (
struct nk_font*)handle.ptr;
17265 NK_ASSERT(font->glyphs);
17266 if (!font || !text || !len)
17269 scale = height/font->info.height;
17270 glyph_len = text_len = nk_utf_decode(text, &unicode, (
int)len);
17271 if (!glyph_len)
return 0;
17272 while (text_len <= (
int)len && glyph_len) {
17273 const struct nk_font_glyph *g;
17277 g = nk_font_find_glyph(font, unicode);
17278 text_width += g->xadvance * scale;
17281 glyph_len = nk_utf_decode(text + text_len, &unicode, (
int)len - text_len);
17282 text_len += glyph_len;
17286#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
17288nk_font_query_font_glyph(
nk_handle handle,
float height,
17289 struct nk_user_font_glyph *glyph, nk_rune codepoint, nk_rune next_codepoint)
17292 const struct nk_font_glyph *g;
17293 struct nk_font *font;
17296 NK_UNUSED(next_codepoint);
17298 font = (
struct nk_font*)handle.ptr;
17300 NK_ASSERT(font->glyphs);
17301 if (!font || !glyph)
17304 scale = height/font->info.height;
17305 g = nk_font_find_glyph(font, codepoint);
17306 glyph->width = (g->x1 - g->x0) * scale;
17307 glyph->height = (g->y1 - g->y0) * scale;
17308 glyph->offset =
nk_vec2(g->x0 * scale, g->y0 * scale);
17309 glyph->xadvance = (g->xadvance * scale);
17310 glyph->uv[0] =
nk_vec2(g->u0, g->v0);
17311 glyph->uv[1] =
nk_vec2(g->u1, g->v1);
17314NK_API
const struct nk_font_glyph*
17315nk_font_find_glyph(
const struct nk_font *font, nk_rune unicode)
17319 int total_glyphs = 0;
17320 const struct nk_font_glyph *glyph = 0;
17321 const struct nk_font_config *iter = 0;
17324 NK_ASSERT(font->glyphs);
17325 NK_ASSERT(font->info.ranges);
17326 if (!font || !font->glyphs)
return 0;
17328 glyph = font->fallback;
17329 iter = font->config;
17330 do {count = nk_range_count(iter->range);
17331 for (i = 0; i < count; ++i) {
17332 nk_rune f = iter->range[(i*2)+0];
17333 nk_rune t = iter->range[(i*2)+1];
17334 int diff = (int)((t - f) + 1);
17335 if (unicode >= f && unicode <= t)
17336 return &font->glyphs[((nk_rune)total_glyphs + (unicode - f))];
17337 total_glyphs += diff;
17339 }
while ((iter = iter->n) != font->config);
17343nk_font_init(
struct nk_font *font,
float pixel_height,
17344 nk_rune fallback_codepoint,
struct nk_font_glyph *glyphs,
17345 const struct nk_baked_font *baked_font,
nk_handle atlas)
17347 struct nk_baked_font baked;
17350 NK_ASSERT(baked_font);
17351 if (!font || !glyphs || !baked_font)
17354 baked = *baked_font;
17355 font->fallback = 0;
17356 font->info = baked;
17357 font->scale = (float)pixel_height / (
float)font->info.height;
17358 font->glyphs = &glyphs[baked_font->glyph_offset];
17359 font->texture = atlas;
17360 font->fallback_codepoint = fallback_codepoint;
17361 font->fallback = nk_font_find_glyph(font, fallback_codepoint);
17363 font->handle.height = font->info.height * font->scale;
17364 font->handle.width = nk_font_text_width;
17365 font->handle.userdata.ptr = font;
17366#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
17367 font->handle.query = nk_font_query_font_glyph;
17368 font->handle.texture = font->texture;
17382#pragma clang diagnostic push
17383#pragma clang diagnostic ignored "-Woverlength-strings"
17384#elif defined(__GNUC__) || defined(__GNUG__)
17385#pragma GCC diagnostic push
17386#pragma GCC diagnostic ignored "-Woverlength-strings"
17389#ifdef NK_INCLUDE_DEFAULT_FONT
17391NK_GLOBAL
const char nk_proggy_clean_ttf_compressed_data_base85[11980+1] =
17392 "7])#######hV0qs'/###[),##/l:$#Q6>##5[n42>c-TH`->>#/e>11NNV=Bv(*:.F?uu#(gRU.o0XGH`$vhLG1hxt9?W`#,5LsCp#-i>.r$<$6pD>Lb';9Crc6tgXmKVeU2cD4Eo3R/"
17393 "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#"
17394 "`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"
17395 "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"
17396 "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"
17397 "*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)"
17398 "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"
17399 "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."
17400 "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"
17401 "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(,)"
17402 "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#"
17403 "'/###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"
17404 "_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"
17405 "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/"
17406 "/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"
17407 "%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&#"
17408 "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)("
17409 "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"
17410 "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"
17411 "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^-"
17412 "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-"
17413 "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"
17414 "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%"
17415 "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]"
17416 "%(?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"
17417 "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:"
17418 "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("
17419 "$/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<"
17420 "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'?"
17421 "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/;"
17422 ")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"
17423 "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("
17424 "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"
17425 "bIu)'Z,*[>br5fX^:FPAWr-m2KgL<LUN098kTF&#lvo58=/vjDo;.;)Ka*hLR#/k=rKbxuV`>Q_nN6'8uTGT5g)uLv:873UpTLgH+#FgpH'_o1780Ph8KmxQJ8#H72L4@768@Tm&Q"
17426 "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<-"
17427 "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"
17428 "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"
17429 ".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@@"
17430 "$&)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*"
17431 "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"
17432 "@-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&#"
17433 "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#"
17434 "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"
17435 "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"
17436 "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&#"
17437 "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"
17438 ":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+"
17439 "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*"
17440 "$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"
17441 ":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"
17442 "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"
17443 "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"
17444 "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"
17445 ":^#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@&]>"
17446 "_>@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%"
17447 "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;"
17448 "^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:"
17449 "+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%"
17450 "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-"
17451 "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*"
17452 "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"
17453 "8kD2)2fU/M#$e.)T4,_=8hLim[&);?UkK'-x?'(:siIfL<$pFM`i<?%W(mGDHM%>iWP,##P`%/L<eXi:@Z9C.7o=@(pXdAO/NLQ8lPl+HPOQa8wD8=^GlPa8TKI1CjhsCTSLJM'/Wl>-"
17454 "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`"
17455 "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]%/"
17456 "+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"
17457 "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"
17458 "?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"
17459 "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"
17460 ">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'>"
17461 "[%$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"
17462 "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#"
17463 "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$"
17464 "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,)"
17465 "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"
17466 "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"
17467 "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"
17468 "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(#"
17469 ";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&>"
17470 "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#"
17471 "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"
17472 "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#"
17473 "/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-#"
17474 "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#"
17475 "TmD<#%JSMFove:CTBEXI:<eh2g)B,3h2^G3i;#d3jD>)4kMYD4lVu`4m`:&5niUA5@(A5BA1]PBB:xlBCC=2CDLXMCEUtiCf&0g2'tN?PGT4CPGT4CPGT4CPGT4CPGT4CPGT4CPGT4CP"
17476 "GT4CPGT4CPGT4CPGT4CPGT4CPGT4CP-qekC`.9kEg^+F$kwViFJTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5o,^<-28ZI'O?;xp"
17477 "O?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xp;7q-#lLYI:xvD=#";
17481#define NK_CURSOR_DATA_W 90
17482#define NK_CURSOR_DATA_H 27
17483NK_GLOBAL
const char nk_custom_cursor_data[NK_CURSOR_DATA_W * NK_CURSOR_DATA_H + 1] =
17485 "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX"
17486 "..- -X.....X- X.X - X.X -X.....X - X.....X"
17487 "--- -XXX.XXX- X...X - X...X -X....X - X....X"
17488 "X - X.X - X.....X - X.....X -X...X - X...X"
17489 "XX - X.X -X.......X- X.......X -X..X.X - X.X..X"
17490 "X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X"
17491 "X..X - X.X - X.X - X.X -XX X.X - X.X XX"
17492 "X...X - X.X - X.X - XX X.X XX - X.X - X.X "
17493 "X....X - X.X - X.X - X.X X.X X.X - X.X - X.X "
17494 "X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X "
17495 "X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X "
17496 "X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X "
17497 "X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X "
17498 "X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X "
17499 "X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X "
17500 "X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X "
17501 "X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX "
17502 "X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------"
17503 "X.X X..X - -X.......X- X.......X - XX XX - "
17504 "XX X..X - - X.....X - X.....X - X.X X.X - "
17505 " X..X - X...X - X...X - X..X X..X - "
17506 " XX - X.X - X.X - X...XXXXXXXXXXXXX...X - "
17507 "------------ - X - X -X.....................X- "
17508 " ----------------------------------- X...XXXXXXXXXXXXX...X - "
17515#pragma clang diagnostic pop
17516#elif defined(__GNUC__) || defined(__GNUG__)
17517#pragma GCC diagnostic pop
17520NK_GLOBAL
unsigned char *nk__barrier;
17521NK_GLOBAL
unsigned char *nk__barrier2;
17522NK_GLOBAL
unsigned char *nk__barrier3;
17523NK_GLOBAL
unsigned char *nk__barrier4;
17524NK_GLOBAL
unsigned char *nk__dout;
17526NK_INTERN
unsigned int
17527nk_decompress_length(
unsigned char *input)
17529 return (
unsigned int)((input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11]);
17532nk__match(
unsigned char *data,
unsigned int length)
17535 NK_ASSERT (nk__dout + length <= nk__barrier);
17536 if (nk__dout + length > nk__barrier) { nk__dout += length;
return; }
17537 if (data < nk__barrier4) { nk__dout = nk__barrier+1;
return; }
17538 while (length--) *nk__dout++ = *data++;
17541nk__lit(
unsigned char *data,
unsigned int length)
17543 NK_ASSERT (nk__dout + length <= nk__barrier);
17544 if (nk__dout + length > nk__barrier) { nk__dout += length;
return; }
17545 if (data < nk__barrier2) { nk__dout = nk__barrier+1;
return; }
17546 NK_MEMCPY(nk__dout, data, length);
17547 nk__dout += length;
17549NK_INTERN
unsigned char*
17550nk_decompress_token(
unsigned char *i)
17552 #define nk__in2(x) ((i[x] << 8) + i[(x)+1])
17553 #define nk__in3(x) ((i[x] << 16) + nk__in2((x)+1))
17554 #define nk__in4(x) ((i[x] << 24) + nk__in3((x)+1))
17557 if (*i >= 0x80) nk__match(nk__dout-i[1]-1, (
unsigned int)i[0] - 0x80 + 1), i += 2;
17558 else if (*i >= 0x40) nk__match(nk__dout-(nk__in2(0) - 0x4000 + 1), (
unsigned int)i[2]+1), i += 3;
17559 else nk__lit(i+1, (
unsigned int)i[0] - 0x20 + 1), i += 1 + (i[0] - 0x20 + 1);
17561 if (*i >= 0x18) nk__match(nk__dout-(
unsigned int)(nk__in3(0) - 0x180000 + 1), (
unsigned int)i[3]+1), i += 4;
17562 else if (*i >= 0x10) nk__match(nk__dout-(
unsigned int)(nk__in3(0) - 0x100000 + 1), (
unsigned int)nk__in2(3)+1), i += 5;
17563 else if (*i >= 0x08) nk__lit(i+2, (
unsigned int)nk__in2(0) - 0x0800 + 1), i += 2 + (nk__in2(0) - 0x0800 + 1);
17564 else if (*i == 0x07) nk__lit(i+3, (
unsigned int)nk__in2(1) + 1), i += 3 + (nk__in2(1) + 1);
17565 else if (*i == 0x06) nk__match(nk__dout-(
unsigned int)(nk__in3(1)+1), i[4]+1u), i += 5;
17566 else if (*i == 0x04) nk__match(nk__dout-(
unsigned int)(nk__in3(1)+1), (
unsigned int)nk__in2(4)+1u), i += 6;
17570NK_INTERN
unsigned int
17571nk_adler32(
unsigned int adler32,
unsigned char *buffer,
unsigned int buflen)
17573 const unsigned long ADLER_MOD = 65521;
17574 unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16;
17575 unsigned long blocklen, i;
17577 blocklen = buflen % 5552;
17579 for (i=0; i + 7 < blocklen; i += 8) {
17580 s1 += buffer[0]; s2 += s1;
17581 s1 += buffer[1]; s2 += s1;
17582 s1 += buffer[2]; s2 += s1;
17583 s1 += buffer[3]; s2 += s1;
17584 s1 += buffer[4]; s2 += s1;
17585 s1 += buffer[5]; s2 += s1;
17586 s1 += buffer[6]; s2 += s1;
17587 s1 += buffer[7]; s2 += s1;
17590 for (; i < blocklen; ++i) {
17591 s1 += *buffer++; s2 += s1;
17594 s1 %= ADLER_MOD; s2 %= ADLER_MOD;
17595 buflen -= (
unsigned int)blocklen;
17598 return (
unsigned int)(s2 << 16) + (
unsigned int)s1;
17600NK_INTERN
unsigned int
17601nk_decompress(
unsigned char *output,
unsigned char *i,
unsigned int length)
17604 if (nk__in4(0) != 0x57bC0000)
return 0;
17605 if (nk__in4(4) != 0)
return 0;
17606 olen = nk_decompress_length(i);
17608 nk__barrier3 = i+length;
17609 nk__barrier = output + olen;
17610 nk__barrier4 = output;
17615 unsigned char *old_i = i;
17616 i = nk_decompress_token(i);
17618 if (*i == 0x05 && i[1] == 0xfa) {
17619 NK_ASSERT(nk__dout == output + olen);
17620 if (nk__dout != output + olen)
return 0;
17621 if (nk_adler32(1, output, olen) != (
unsigned int) nk__in4(2))
17629 NK_ASSERT(nk__dout <= output + olen);
17630 if (nk__dout > output + olen)
17634NK_INTERN
unsigned int
17635nk_decode_85_byte(
char c)
17637 return (
unsigned int)((c >=
'\\') ? c-36 : c-35);
17640nk_decode_85(
unsigned char* dst,
const unsigned char* src)
17645 nk_decode_85_byte((
char)src[0]) +
17646 85 * (nk_decode_85_byte((
char)src[1]) +
17647 85 * (nk_decode_85_byte((
char)src[2]) +
17648 85 * (nk_decode_85_byte((
char)src[3]) +
17649 85 * nk_decode_85_byte((
char)src[4]))));
17652 dst[0] = (
unsigned char)((tmp >> 0) & 0xFF);
17653 dst[1] = (
unsigned char)((tmp >> 8) & 0xFF);
17654 dst[2] = (
unsigned char)((tmp >> 16) & 0xFF);
17655 dst[3] = (
unsigned char)((tmp >> 24) & 0xFF);
17667NK_API
struct nk_font_config
17668nk_font_config(float pixel_height)
17670 struct nk_font_config cfg;
17671 nk_zero_struct(cfg);
17674 cfg.ttf_data_owned_by_atlas = 0;
17675 cfg.size = pixel_height;
17676 cfg.oversample_h = 3;
17677 cfg.oversample_v = 1;
17678 cfg.pixel_snap = 0;
17679 cfg.coord_type = NK_COORD_UV;
17681 cfg.range = nk_font_default_glyph_ranges();
17682 cfg.merge_mode = 0;
17683 cfg.fallback_glyph =
'?';
17688#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
17690nk_font_atlas_init_default(
struct nk_font_atlas *atlas)
17693 if (!atlas)
return;
17694 nk_zero_struct(*atlas);
17695 atlas->temporary.userdata.ptr = 0;
17696 atlas->temporary.alloc = nk_malloc;
17697 atlas->temporary.free = nk_mfree;
17698 atlas->permanent.userdata.ptr = 0;
17699 atlas->permanent.alloc = nk_malloc;
17700 atlas->permanent.free = nk_mfree;
17704nk_font_atlas_init(
struct nk_font_atlas *atlas,
const struct nk_allocator *alloc)
17708 if (!atlas || !alloc)
return;
17709 nk_zero_struct(*atlas);
17710 atlas->permanent = *alloc;
17711 atlas->temporary = *alloc;
17714nk_font_atlas_init_custom(
struct nk_font_atlas *atlas,
17718 NK_ASSERT(permanent);
17719 NK_ASSERT(temporary);
17720 if (!atlas || !permanent || !temporary)
return;
17721 nk_zero_struct(*atlas);
17722 atlas->permanent = *permanent;
17723 atlas->temporary = *temporary;
17726nk_font_atlas_begin(
struct nk_font_atlas *atlas)
17729 NK_ASSERT(atlas->temporary.alloc && atlas->temporary.free);
17730 NK_ASSERT(atlas->permanent.alloc && atlas->permanent.free);
17731 if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free ||
17732 !atlas->temporary.alloc || !atlas->temporary.free)
return;
17733 if (atlas->glyphs) {
17734 atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
17737 if (atlas->pixel) {
17738 atlas->permanent.free(atlas->permanent.userdata, atlas->pixel);
17742NK_API
struct nk_font*
17743nk_font_atlas_add(
struct nk_font_atlas *atlas,
const struct nk_font_config *config)
17745 struct nk_font *font = 0;
17746 struct nk_font_config *cfg;
17749 NK_ASSERT(atlas->permanent.alloc);
17750 NK_ASSERT(atlas->permanent.free);
17751 NK_ASSERT(atlas->temporary.alloc);
17752 NK_ASSERT(atlas->temporary.free);
17755 NK_ASSERT(config->ttf_blob);
17756 NK_ASSERT(config->ttf_size);
17757 NK_ASSERT(config->size > 0.0f);
17759 if (!atlas || !config || !config->ttf_blob || !config->ttf_size || config->size <= 0.0f||
17760 !atlas->permanent.alloc || !atlas->permanent.free ||
17761 !atlas->temporary.alloc || !atlas->temporary.free)
17765 cfg = (
struct nk_font_config*)
17766 atlas->permanent.alloc(atlas->permanent.userdata,0,
sizeof(
struct nk_font_config));
17767 NK_MEMCPY(cfg, config,
sizeof(*config));
17771 if (!config->merge_mode) {
17773 if (!atlas->config) {
17774 atlas->config = cfg;
17777 struct nk_font_config *i = atlas->config;
17778 while (i->next) i = i->next;
17783 font = (
struct nk_font*)
17784 atlas->permanent.alloc(atlas->permanent.userdata,0,
sizeof(
struct nk_font));
17786 nk_zero(font,
sizeof(*font));
17787 if (!font)
return 0;
17788 font->config = cfg;
17791 if (!atlas->fonts) {
17792 atlas->fonts = font;
17795 struct nk_font *i = atlas->fonts;
17796 while (i->next) i = i->next;
17800 cfg->font = &font->info;
17803 struct nk_font *f = 0;
17804 struct nk_font_config *c = 0;
17805 NK_ASSERT(atlas->font_num);
17808 cfg->font = &f->info;
17816 if (!config->ttf_data_owned_by_atlas) {
17817 cfg->ttf_blob = atlas->permanent.alloc(atlas->permanent.userdata,0, cfg->ttf_size);
17818 NK_ASSERT(cfg->ttf_blob);
17819 if (!cfg->ttf_blob) {
17823 NK_MEMCPY(cfg->ttf_blob, config->ttf_blob, cfg->ttf_size);
17824 cfg->ttf_data_owned_by_atlas = 1;
17829NK_API
struct nk_font*
17830nk_font_atlas_add_from_memory(
struct nk_font_atlas *atlas,
void *memory,
17831 nk_size size,
float height,
const struct nk_font_config *config)
17833 struct nk_font_config cfg;
17838 NK_ASSERT(atlas->temporary.alloc);
17839 NK_ASSERT(atlas->temporary.free);
17840 NK_ASSERT(atlas->permanent.alloc);
17841 NK_ASSERT(atlas->permanent.free);
17842 if (!atlas || !atlas->temporary.alloc || !atlas->temporary.free || !memory || !size ||
17843 !atlas->permanent.alloc || !atlas->permanent.free)
17846 cfg = (config) ? *config: nk_font_config(height);
17847 cfg.ttf_blob = memory;
17848 cfg.ttf_size = size;
17850 cfg.ttf_data_owned_by_atlas = 0;
17851 return nk_font_atlas_add(atlas, &cfg);
17853#ifdef NK_INCLUDE_STANDARD_IO
17854NK_API
struct nk_font*
17855nk_font_atlas_add_from_file(
struct nk_font_atlas *atlas,
const char *file_path,
17856 float height,
const struct nk_font_config *config)
17860 struct nk_font_config cfg;
17863 NK_ASSERT(atlas->temporary.alloc);
17864 NK_ASSERT(atlas->temporary.free);
17865 NK_ASSERT(atlas->permanent.alloc);
17866 NK_ASSERT(atlas->permanent.free);
17868 if (!atlas || !file_path)
return 0;
17869 memory = nk_file_load(file_path, &size, &atlas->permanent);
17870 if (!memory)
return 0;
17872 cfg = (config) ? *config: nk_font_config(height);
17873 cfg.ttf_blob = memory;
17874 cfg.ttf_size = size;
17876 cfg.ttf_data_owned_by_atlas = 1;
17877 return nk_font_atlas_add(atlas, &cfg);
17880NK_API
struct nk_font*
17881nk_font_atlas_add_compressed(
struct nk_font_atlas *atlas,
17882 void *compressed_data, nk_size compressed_size,
float height,
17883 const struct nk_font_config *config)
17885 unsigned int decompressed_size;
17886 void *decompressed_data;
17887 struct nk_font_config cfg;
17890 NK_ASSERT(atlas->temporary.alloc);
17891 NK_ASSERT(atlas->temporary.free);
17892 NK_ASSERT(atlas->permanent.alloc);
17893 NK_ASSERT(atlas->permanent.free);
17895 NK_ASSERT(compressed_data);
17896 NK_ASSERT(compressed_size);
17897 if (!atlas || !compressed_data || !atlas->temporary.alloc || !atlas->temporary.free ||
17898 !atlas->permanent.alloc || !atlas->permanent.free)
17901 decompressed_size = nk_decompress_length((
unsigned char*)compressed_data);
17902 decompressed_data = atlas->permanent.alloc(atlas->permanent.userdata,0,decompressed_size);
17903 NK_ASSERT(decompressed_data);
17904 if (!decompressed_data)
return 0;
17905 nk_decompress((
unsigned char*)decompressed_data, (
unsigned char*)compressed_data,
17906 (
unsigned int)compressed_size);
17908 cfg = (config) ? *config: nk_font_config(height);
17909 cfg.ttf_blob = decompressed_data;
17910 cfg.ttf_size = decompressed_size;
17912 cfg.ttf_data_owned_by_atlas = 1;
17913 return nk_font_atlas_add(atlas, &cfg);
17915NK_API
struct nk_font*
17916nk_font_atlas_add_compressed_base85(
struct nk_font_atlas *atlas,
17917 const char *data_base85,
float height,
const struct nk_font_config *config)
17919 int compressed_size;
17920 void *compressed_data;
17921 struct nk_font *font;
17924 NK_ASSERT(atlas->temporary.alloc);
17925 NK_ASSERT(atlas->temporary.free);
17926 NK_ASSERT(atlas->permanent.alloc);
17927 NK_ASSERT(atlas->permanent.free);
17929 NK_ASSERT(data_base85);
17930 if (!atlas || !data_base85 || !atlas->temporary.alloc || !atlas->temporary.free ||
17931 !atlas->permanent.alloc || !atlas->permanent.free)
17934 compressed_size = (((int)nk_strlen(data_base85) + 4) / 5) * 4;
17935 compressed_data = atlas->temporary.alloc(atlas->temporary.userdata,0, (nk_size)compressed_size);
17936 NK_ASSERT(compressed_data);
17937 if (!compressed_data)
return 0;
17938 nk_decode_85((
unsigned char*)compressed_data, (
const unsigned char*)data_base85);
17939 font = nk_font_atlas_add_compressed(atlas, compressed_data,
17940 (nk_size)compressed_size, height, config);
17941 atlas->temporary.free(atlas->temporary.userdata, compressed_data);
17945#ifdef NK_INCLUDE_DEFAULT_FONT
17946NK_API
struct nk_font*
17947nk_font_atlas_add_default(
struct nk_font_atlas *atlas,
17948 float pixel_height,
const struct nk_font_config *config)
17951 NK_ASSERT(atlas->temporary.alloc);
17952 NK_ASSERT(atlas->temporary.free);
17953 NK_ASSERT(atlas->permanent.alloc);
17954 NK_ASSERT(atlas->permanent.free);
17955 return nk_font_atlas_add_compressed_base85(atlas,
17956 nk_proggy_clean_ttf_compressed_data_base85, pixel_height, config);
17960nk_font_atlas_bake(
struct nk_font_atlas *atlas,
int *width,
int *height,
17961 enum nk_font_atlas_format fmt)
17965 nk_size tmp_size, img_size;
17966 struct nk_font *font_iter;
17967 struct nk_font_baker *baker;
17970 NK_ASSERT(atlas->temporary.alloc);
17971 NK_ASSERT(atlas->temporary.free);
17972 NK_ASSERT(atlas->permanent.alloc);
17973 NK_ASSERT(atlas->permanent.free);
17977 if (!atlas || !width || !height ||
17978 !atlas->temporary.alloc || !atlas->temporary.free ||
17979 !atlas->permanent.alloc || !atlas->permanent.free)
17982#ifdef NK_INCLUDE_DEFAULT_FONT
17984 if (!atlas->font_num)
17985 atlas->default_font = nk_font_atlas_add_default(atlas, 13.0f, 0);
17987 NK_ASSERT(atlas->font_num);
17988 if (!atlas->font_num)
return 0;
17991 nk_font_baker_memory(&tmp_size, &atlas->glyph_count, atlas->config, atlas->font_num);
17992 tmp = atlas->temporary.alloc(atlas->temporary.userdata,0, tmp_size);
17994 if (!tmp)
goto failed;
17995 NK_MEMSET(tmp,0,tmp_size);
17998 baker = nk_font_baker(tmp, atlas->glyph_count, atlas->font_num, &atlas->temporary);
17999 atlas->glyphs = (
struct nk_font_glyph*)atlas->permanent.alloc(
18000 atlas->permanent.userdata,0,
sizeof(
struct nk_font_glyph)*(nk_size)atlas->glyph_count);
18001 NK_ASSERT(atlas->glyphs);
18002 if (!atlas->glyphs)
18006 atlas->custom.w = (NK_CURSOR_DATA_W*2)+1;
18007 atlas->custom.h = NK_CURSOR_DATA_H + 1;
18008 if (!nk_font_bake_pack(baker, &img_size, width, height, &atlas->custom,
18009 atlas->config, atlas->font_num, &atlas->temporary))
18013 atlas->pixel = atlas->temporary.alloc(atlas->temporary.userdata,0, img_size);
18014 NK_ASSERT(atlas->pixel);
18019 nk_font_bake(baker, atlas->pixel, *width, *height,
18020 atlas->glyphs, atlas->glyph_count, atlas->config, atlas->font_num);
18021 nk_font_bake_custom_data(atlas->pixel, *width, *height, atlas->custom,
18022 nk_custom_cursor_data, NK_CURSOR_DATA_W, NK_CURSOR_DATA_H,
'.',
'X');
18024 if (fmt == NK_FONT_ATLAS_RGBA32) {
18026 void *img_rgba = atlas->temporary.alloc(atlas->temporary.userdata,0,
18027 (nk_size)(*width * *height * 4));
18028 NK_ASSERT(img_rgba);
18029 if (!img_rgba)
goto failed;
18030 nk_font_bake_convert(img_rgba, *width, *height, atlas->pixel);
18031 atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
18032 atlas->pixel = img_rgba;
18034 atlas->tex_width = *width;
18035 atlas->tex_height = *height;
18038 for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) {
18039 struct nk_font *font = font_iter;
18040 struct nk_font_config *config = font->config;
18041 nk_font_init(font, config->size, config->fallback_glyph, atlas->glyphs,
18042 config->font, nk_handle_ptr(0));
18046 {NK_STORAGE
const struct nk_vec2 nk_cursor_data[NK_CURSOR_COUNT][3] = {
18048 {{ 0, 3}, {12,19}, { 0, 0}},
18049 {{13, 0}, { 7,16}, { 4, 8}},
18050 {{31, 0}, {23,23}, {11,11}},
18051 {{21, 0}, { 9, 23}, { 5,11}},
18052 {{55,18}, {23, 9}, {11, 5}},
18053 {{73, 0}, {17,17}, { 9, 9}},
18054 {{55, 0}, {17,17}, { 9, 9}}
18056 for (i = 0; i < NK_CURSOR_COUNT; ++i) {
18057 struct nk_cursor *cursor = &atlas->cursors[i];
18058 cursor->img.w = (
unsigned short)*width;
18059 cursor->img.h = (
unsigned short)*height;
18060 cursor->img.region[0] = (
unsigned short)(atlas->custom.x + nk_cursor_data[i][0].x);
18061 cursor->img.region[1] = (
unsigned short)(atlas->custom.y + nk_cursor_data[i][0].y);
18062 cursor->img.region[2] = (
unsigned short)nk_cursor_data[i][1].x;
18063 cursor->img.region[3] = (
unsigned short)nk_cursor_data[i][1].y;
18064 cursor->size = nk_cursor_data[i][1];
18065 cursor->offset = nk_cursor_data[i][2];
18068 atlas->temporary.free(atlas->temporary.userdata, tmp);
18069 return atlas->pixel;
18073 if (tmp) atlas->temporary.free(atlas->temporary.userdata, tmp);
18074 if (atlas->glyphs) {
18075 atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
18078 if (atlas->pixel) {
18079 atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
18085nk_font_atlas_end(
struct nk_font_atlas *atlas,
nk_handle texture,
18089 struct nk_font *font_iter;
18092 if (!tex_null)
return;
18093 tex_null->texture = texture;
18097 tex_null->texture = texture;
18098 tex_null->
uv.x = (atlas->custom.x + 0.5f)/(
float)atlas->tex_width;
18099 tex_null->
uv.y = (atlas->custom.y + 0.5f)/(
float)atlas->tex_height;
18101 for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) {
18102 font_iter->texture = texture;
18103#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
18104 font_iter->handle.texture = texture;
18107 for (i = 0; i < NK_CURSOR_COUNT; ++i)
18108 atlas->cursors[i].img.handle = texture;
18110 atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
18112 atlas->tex_width = 0;
18113 atlas->tex_height = 0;
18114 atlas->custom.x = 0;
18115 atlas->custom.y = 0;
18116 atlas->custom.w = 0;
18117 atlas->custom.h = 0;
18120nk_font_atlas_cleanup(
struct nk_font_atlas *atlas)
18123 NK_ASSERT(atlas->temporary.alloc);
18124 NK_ASSERT(atlas->temporary.free);
18125 NK_ASSERT(atlas->permanent.alloc);
18126 NK_ASSERT(atlas->permanent.free);
18127 if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free)
return;
18128 if (atlas->config) {
18129 struct nk_font_config *iter;
18130 for (iter = atlas->config; iter; iter = iter->next) {
18131 struct nk_font_config *i;
18132 for (i = iter->n; i != iter; i = i->n) {
18133 atlas->permanent.free(atlas->permanent.userdata, i->ttf_blob);
18136 atlas->permanent.free(atlas->permanent.userdata, iter->ttf_blob);
18137 iter->ttf_blob = 0;
18142nk_font_atlas_clear(
struct nk_font_atlas *atlas)
18145 NK_ASSERT(atlas->temporary.alloc);
18146 NK_ASSERT(atlas->temporary.free);
18147 NK_ASSERT(atlas->permanent.alloc);
18148 NK_ASSERT(atlas->permanent.free);
18149 if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free)
return;
18151 if (atlas->config) {
18152 struct nk_font_config *iter, *next;
18153 for (iter = atlas->config; iter; iter = next) {
18154 struct nk_font_config *i, *n;
18155 for (i = iter->n; i != iter; i = n) {
18158 atlas->permanent.free(atlas->permanent.userdata, i->ttf_blob);
18159 atlas->permanent.free(atlas->permanent.userdata, i);
18163 atlas->permanent.free(atlas->permanent.userdata, iter->ttf_blob);
18164 atlas->permanent.free(atlas->permanent.userdata, iter);
18168 if (atlas->fonts) {
18169 struct nk_font *iter, *next;
18170 for (iter = atlas->fonts; iter; iter = next) {
18172 atlas->permanent.free(atlas->permanent.userdata, iter);
18177 atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
18178 nk_zero_struct(*atlas);
18198 for (i = 0; i < NK_BUTTON_MAX; ++i)
18199 in->mouse.buttons[i].clicked = 0;
18201 in->keyboard.text_len = 0;
18202 in->mouse.scroll_delta =
nk_vec2(0,0);
18203 in->mouse.prev.x = in->mouse.pos.x;
18204 in->mouse.prev.y = in->mouse.pos.y;
18205 in->mouse.delta.x = 0;
18206 in->mouse.delta.y = 0;
18207 for (i = 0; i < NK_KEY_MAX; i++)
18208 in->keyboard.keys[i].clicked = 0;
18217 if (in->mouse.grab)
18218 in->mouse.grab = 0;
18219 if (in->mouse.ungrab) {
18220 in->mouse.grabbed = 0;
18221 in->mouse.ungrab = 0;
18222 in->mouse.grab = 0;
18232 in->mouse.pos.x = (float)x;
18233 in->mouse.pos.y = (float)y;
18234 in->mouse.delta.x = in->mouse.pos.x - in->mouse.prev.x;
18235 in->mouse.delta.y = in->mouse.pos.y - in->mouse.prev.y;
18244#ifdef NK_KEYSTATE_BASED_INPUT
18245 if (in->keyboard.keys[key].down != down)
18246 in->keyboard.keys[key].clicked++;
18248 in->keyboard.keys[key].clicked++;
18250 in->keyboard.keys[key].down = down;
18260 if (in->mouse.buttons[
id].down == down)
return;
18262 btn = &in->mouse.buttons[id];
18263 btn->clicked_pos.x = (float)x;
18264 btn->clicked_pos.y = (float)y;
18269 in->mouse.delta.x = 0;
18270 in->mouse.delta.y = 0;
18271#ifdef NK_BUTTON_TRIGGER_ON_RELEASE
18272 if (down == 1 &&
id == NK_BUTTON_LEFT)
18274 in->mouse.down_pos.x = btn->clicked_pos.x;
18275 in->mouse.down_pos.y = btn->clicked_pos.y;
18284 ctx->input.mouse.scroll_delta.x += val.x;
18285 ctx->input.mouse.scroll_delta.y += val.y;
18298 len = nk_utf_decode(glyph, &unicode,
NK_UTF_SIZE);
18299 if (len && ((in->keyboard.text_len + len) < NK_INPUT_MAX)) {
18300 nk_utf_encode(unicode, &in->keyboard.text[in->keyboard.text_len],
18301 NK_INPUT_MAX - in->keyboard.text_len);
18302 in->keyboard.text_len += len;
18308 nk_glyph glyph = {0};
18324nk_input_has_mouse_click(
const struct nk_input *i,
enum nk_buttons
id)
18327 if (!i)
return nk_false;
18328 btn = &i->mouse.buttons[id];
18329 return (btn->clicked && btn->down == nk_false) ? nk_true : nk_false;
18332nk_input_has_mouse_click_in_rect(
const struct nk_input *i,
enum nk_buttons
id,
18336 if (!i)
return nk_false;
18337 btn = &i->mouse.buttons[id];
18338 if (!NK_INBOX(btn->clicked_pos.x,btn->clicked_pos.y,b.x,b.y,b.w,b.h))
18343nk_input_has_mouse_click_in_button_rect(
const struct nk_input *i,
enum nk_buttons
id,
18347 if (!i)
return nk_false;
18348 btn = &i->mouse.buttons[id];
18349#ifdef NK_BUTTON_TRIGGER_ON_RELEASE
18350 if (!NK_INBOX(btn->clicked_pos.x,btn->clicked_pos.y,b.x,b.y,b.w,b.h)
18351 || !NK_INBOX(i->mouse.down_pos.x,i->mouse.down_pos.y,b.x,b.y,b.w,b.h))
18353 if (!NK_INBOX(btn->clicked_pos.x,btn->clicked_pos.y,b.x,b.y,b.w,b.h))
18359nk_input_has_mouse_click_down_in_rect(
const struct nk_input *i,
enum nk_buttons
id,
18360 struct nk_rect b, nk_bool down)
18363 if (!i)
return nk_false;
18364 btn = &i->mouse.buttons[id];
18365 return nk_input_has_mouse_click_in_rect(i,
id, b) && (btn->down == down);
18368nk_input_is_mouse_click_in_rect(
const struct nk_input *i,
enum nk_buttons
id,
18372 if (!i)
return nk_false;
18373 btn = &i->mouse.buttons[id];
18374 return (nk_input_has_mouse_click_down_in_rect(i,
id, b, nk_false) &&
18375 btn->clicked) ? nk_true : nk_false;
18378nk_input_is_mouse_click_down_in_rect(
const struct nk_input *i,
enum nk_buttons
id,
18379 struct nk_rect b, nk_bool down)
18382 if (!i)
return nk_false;
18383 btn = &i->mouse.buttons[id];
18384 return (nk_input_has_mouse_click_down_in_rect(i,
id, b, down) &&
18385 btn->clicked) ? nk_true : nk_false;
18388nk_input_any_mouse_click_in_rect(
const struct nk_input *in,
struct nk_rect b)
18391 for (i = 0; i < NK_BUTTON_MAX; ++i)
18392 down = down || nk_input_is_mouse_click_in_rect(in, (
enum nk_buttons)i, b);
18396nk_input_is_mouse_hovering_rect(
const struct nk_input *i,
struct nk_rect rect)
18398 if (!i)
return nk_false;
18399 return NK_INBOX(i->mouse.pos.x, i->mouse.pos.y, rect.x, rect.y, rect.w, rect.h);
18402nk_input_is_mouse_prev_hovering_rect(
const struct nk_input *i,
struct nk_rect rect)
18404 if (!i)
return nk_false;
18405 return NK_INBOX(i->mouse.prev.x, i->mouse.prev.y, rect.x, rect.y, rect.w, rect.h);
18408nk_input_mouse_clicked(
const struct nk_input *i,
enum nk_buttons
id,
struct nk_rect rect)
18410 if (!i)
return nk_false;
18411 if (!nk_input_is_mouse_hovering_rect(i, rect))
return nk_false;
18412 return nk_input_is_mouse_click_in_rect(i,
id, rect);
18415nk_input_is_mouse_down(
const struct nk_input *i,
enum nk_buttons
id)
18417 if (!i)
return nk_false;
18418 return i->mouse.buttons[id].down;
18421nk_input_is_mouse_pressed(
const struct nk_input *i,
enum nk_buttons
id)
18424 if (!i)
return nk_false;
18425 b = &i->mouse.buttons[id];
18426 if (b->down && b->clicked)
18431nk_input_is_mouse_released(
const struct nk_input *i,
enum nk_buttons
id)
18433 if (!i)
return nk_false;
18434 return (!i->mouse.buttons[
id].down && i->mouse.buttons[
id].clicked);
18437nk_input_is_key_pressed(
const struct nk_input *i,
enum nk_keys key)
18440 if (!i)
return nk_false;
18441 k = &i->keyboard.keys[key];
18442 if ((k->down && k->clicked) || (!k->down && k->clicked >= 2))
18447nk_input_is_key_released(
const struct nk_input *i,
enum nk_keys key)
18450 if (!i)
return nk_false;
18451 k = &i->keyboard.keys[key];
18452 if ((!k->down && k->clicked) || (k->down && k->clicked >= 2))
18457nk_input_is_key_down(
const struct nk_input *i,
enum nk_keys key)
18460 if (!i)
return nk_false;
18461 k = &i->keyboard.keys[key];
18462 if (k->down)
return nk_true;
18475NK_API
void nk_style_default(
struct nk_context *ctx){nk_style_from_table(ctx, 0);}
18476#define NK_COLOR_MAP(NK_COLOR)\
18477 NK_COLOR(NK_COLOR_TEXT, 175,175,175,255) \
18478 NK_COLOR(NK_COLOR_WINDOW, 45, 45, 45, 255) \
18479 NK_COLOR(NK_COLOR_HEADER, 40, 40, 40, 255) \
18480 NK_COLOR(NK_COLOR_BORDER, 65, 65, 65, 255) \
18481 NK_COLOR(NK_COLOR_BUTTON, 50, 50, 50, 255) \
18482 NK_COLOR(NK_COLOR_BUTTON_HOVER, 40, 40, 40, 255) \
18483 NK_COLOR(NK_COLOR_BUTTON_ACTIVE, 35, 35, 35, 255) \
18484 NK_COLOR(NK_COLOR_TOGGLE, 100,100,100,255) \
18485 NK_COLOR(NK_COLOR_TOGGLE_HOVER, 120,120,120,255) \
18486 NK_COLOR(NK_COLOR_TOGGLE_CURSOR, 45, 45, 45, 255) \
18487 NK_COLOR(NK_COLOR_SELECT, 45, 45, 45, 255) \
18488 NK_COLOR(NK_COLOR_SELECT_ACTIVE, 35, 35, 35,255) \
18489 NK_COLOR(NK_COLOR_SLIDER, 38, 38, 38, 255) \
18490 NK_COLOR(NK_COLOR_SLIDER_CURSOR, 100,100,100,255) \
18491 NK_COLOR(NK_COLOR_SLIDER_CURSOR_HOVER, 120,120,120,255) \
18492 NK_COLOR(NK_COLOR_SLIDER_CURSOR_ACTIVE, 150,150,150,255) \
18493 NK_COLOR(NK_COLOR_PROPERTY, 38, 38, 38, 255) \
18494 NK_COLOR(NK_COLOR_EDIT, 38, 38, 38, 255) \
18495 NK_COLOR(NK_COLOR_EDIT_CURSOR, 175,175,175,255) \
18496 NK_COLOR(NK_COLOR_COMBO, 45, 45, 45, 255) \
18497 NK_COLOR(NK_COLOR_CHART, 120,120,120,255) \
18498 NK_COLOR(NK_COLOR_CHART_COLOR, 45, 45, 45, 255) \
18499 NK_COLOR(NK_COLOR_CHART_COLOR_HIGHLIGHT, 255, 0, 0, 255) \
18500 NK_COLOR(NK_COLOR_SCROLLBAR, 40, 40, 40, 255) \
18501 NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR, 100,100,100,255) \
18502 NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR_HOVER, 120,120,120,255) \
18503 NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR_ACTIVE, 150,150,150,255) \
18504 NK_COLOR(NK_COLOR_TAB_HEADER, 40, 40, 40,255) \
18505 NK_COLOR(NK_COLOR_KNOB, 38, 38, 38, 255) \
18506 NK_COLOR(NK_COLOR_KNOB_CURSOR, 100,100,100,255) \
18507 NK_COLOR(NK_COLOR_KNOB_CURSOR_HOVER, 120,120,120,255) \
18508 NK_COLOR(NK_COLOR_KNOB_CURSOR_ACTIVE, 150,150,150,255)
18511nk_default_color_style[NK_COLOR_COUNT] = {
18512#define NK_COLOR(a,b,c,d,e) {b,c,d,e},
18513 NK_COLOR_MAP(NK_COLOR)
18516NK_GLOBAL
const char *nk_color_names[NK_COLOR_COUNT] = {
18517#define NK_COLOR(a,b,c,d,e) #a,
18518 NK_COLOR_MAP(NK_COLOR)
18523nk_style_get_color_by_name(
enum nk_style_colors c)
18525 return nk_color_names[c];
18528nk_style_item_color(struct
nk_color col)
18531 i.type = NK_STYLE_ITEM_COLOR;
18532 i.data.color = col;
18536nk_style_item_image(struct
nk_image img)
18539 i.type = NK_STYLE_ITEM_IMAGE;
18540 i.data.image = img;
18547 i.type = NK_STYLE_ITEM_NINE_SLICE;
18548 i.data.slice = slice;
18552nk_style_item_hide(void)
18555 i.type = NK_STYLE_ITEM_COLOR;
18556 i.data.color = nk_rgba(0,0,0,0);
18580 style = &ctx->style;
18581 table = (!table) ? nk_default_color_style: table;
18584 text = &style->text;
18585 text->color = table[NK_COLOR_TEXT];
18586 text->padding =
nk_vec2(0,0);
18587 text->color_factor = 1.0f;
18588 text->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
18591 button = &style->button;
18592 nk_zero_struct(*button);
18593 button->normal = nk_style_item_color(table[NK_COLOR_BUTTON]);
18594 button->hover = nk_style_item_color(table[NK_COLOR_BUTTON_HOVER]);
18595 button->active = nk_style_item_color(table[NK_COLOR_BUTTON_ACTIVE]);
18596 button->border_color = table[NK_COLOR_BORDER];
18597 button->text_background = table[NK_COLOR_BUTTON];
18598 button->text_normal = table[NK_COLOR_TEXT];
18599 button->text_hover = table[NK_COLOR_TEXT];
18600 button->text_active = table[NK_COLOR_TEXT];
18601 button->padding =
nk_vec2(2.0f,2.0f);
18602 button->image_padding =
nk_vec2(0.0f,0.0f);
18603 button->touch_padding =
nk_vec2(0.0f, 0.0f);
18604 button->userdata = nk_handle_ptr(0);
18605 button->text_alignment = NK_TEXT_CENTERED;
18606 button->border = 1.0f;
18607 button->rounding = 4.0f;
18608 button->color_factor_text = 1.0f;
18609 button->color_factor_background = 1.0f;
18610 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
18611 button->draw_begin = 0;
18612 button->draw_end = 0;
18615 button = &style->contextual_button;
18616 nk_zero_struct(*button);
18617 button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]);
18618 button->hover = nk_style_item_color(table[NK_COLOR_BUTTON_HOVER]);
18619 button->active = nk_style_item_color(table[NK_COLOR_BUTTON_ACTIVE]);
18620 button->border_color = table[NK_COLOR_WINDOW];
18621 button->text_background = table[NK_COLOR_WINDOW];
18622 button->text_normal = table[NK_COLOR_TEXT];
18623 button->text_hover = table[NK_COLOR_TEXT];
18624 button->text_active = table[NK_COLOR_TEXT];
18625 button->padding =
nk_vec2(2.0f,2.0f);
18626 button->touch_padding =
nk_vec2(0.0f,0.0f);
18627 button->userdata = nk_handle_ptr(0);
18628 button->text_alignment = NK_TEXT_CENTERED;
18629 button->border = 0.0f;
18630 button->rounding = 0.0f;
18631 button->color_factor_text = 1.0f;
18632 button->color_factor_background = 1.0f;
18633 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
18634 button->draw_begin = 0;
18635 button->draw_end = 0;
18638 button = &style->menu_button;
18639 nk_zero_struct(*button);
18640 button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]);
18641 button->hover = nk_style_item_color(table[NK_COLOR_WINDOW]);
18642 button->active = nk_style_item_color(table[NK_COLOR_WINDOW]);
18643 button->border_color = table[NK_COLOR_WINDOW];
18644 button->text_background = table[NK_COLOR_WINDOW];
18645 button->text_normal = table[NK_COLOR_TEXT];
18646 button->text_hover = table[NK_COLOR_TEXT];
18647 button->text_active = table[NK_COLOR_TEXT];
18648 button->padding =
nk_vec2(2.0f,2.0f);
18649 button->touch_padding =
nk_vec2(0.0f,0.0f);
18650 button->userdata = nk_handle_ptr(0);
18651 button->text_alignment = NK_TEXT_CENTERED;
18652 button->border = 0.0f;
18653 button->rounding = 1.0f;
18654 button->color_factor_text = 1.0f;
18655 button->color_factor_background = 1.0f;
18656 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
18657 button->draw_begin = 0;
18658 button->draw_end = 0;
18661 toggle = &style->checkbox;
18662 nk_zero_struct(*toggle);
18663 toggle->normal = nk_style_item_color(table[NK_COLOR_TOGGLE]);
18664 toggle->hover = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]);
18665 toggle->active = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]);
18666 toggle->cursor_normal = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]);
18667 toggle->cursor_hover = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]);
18668 toggle->userdata = nk_handle_ptr(0);
18669 toggle->text_background = table[NK_COLOR_WINDOW];
18670 toggle->text_normal = table[NK_COLOR_TEXT];
18671 toggle->text_hover = table[NK_COLOR_TEXT];
18672 toggle->text_active = table[NK_COLOR_TEXT];
18673 toggle->padding =
nk_vec2(2.0f, 2.0f);
18674 toggle->touch_padding =
nk_vec2(0,0);
18675 toggle->border_color = nk_rgba(0,0,0,0);
18676 toggle->border = 0.0f;
18677 toggle->spacing = 4;
18678 toggle->color_factor = 1.0f;
18679 toggle->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
18682 toggle = &style->option;
18683 nk_zero_struct(*toggle);
18684 toggle->normal = nk_style_item_color(table[NK_COLOR_TOGGLE]);
18685 toggle->hover = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]);
18686 toggle->active = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]);
18687 toggle->cursor_normal = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]);
18688 toggle->cursor_hover = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]);
18689 toggle->userdata = nk_handle_ptr(0);
18690 toggle->text_background = table[NK_COLOR_WINDOW];
18691 toggle->text_normal = table[NK_COLOR_TEXT];
18692 toggle->text_hover = table[NK_COLOR_TEXT];
18693 toggle->text_active = table[NK_COLOR_TEXT];
18694 toggle->padding =
nk_vec2(3.0f, 3.0f);
18695 toggle->touch_padding =
nk_vec2(0,0);
18696 toggle->border_color = nk_rgba(0,0,0,0);
18697 toggle->border = 0.0f;
18698 toggle->spacing = 4;
18699 toggle->color_factor = 1.0f;
18700 toggle->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
18703 select = &style->selectable;
18704 nk_zero_struct(*select);
18705 select->normal = nk_style_item_color(table[NK_COLOR_SELECT]);
18706 select->hover = nk_style_item_color(table[NK_COLOR_SELECT]);
18707 select->pressed = nk_style_item_color(table[NK_COLOR_SELECT]);
18708 select->normal_active = nk_style_item_color(table[NK_COLOR_SELECT_ACTIVE]);
18709 select->hover_active = nk_style_item_color(table[NK_COLOR_SELECT_ACTIVE]);
18710 select->pressed_active = nk_style_item_color(table[NK_COLOR_SELECT_ACTIVE]);
18711 select->text_normal = table[NK_COLOR_TEXT];
18712 select->text_hover = table[NK_COLOR_TEXT];
18713 select->text_pressed = table[NK_COLOR_TEXT];
18714 select->text_normal_active = table[NK_COLOR_TEXT];
18715 select->text_hover_active = table[NK_COLOR_TEXT];
18716 select->text_pressed_active = table[NK_COLOR_TEXT];
18717 select->padding =
nk_vec2(2.0f,2.0f);
18718 select->image_padding =
nk_vec2(2.0f,2.0f);
18719 select->touch_padding =
nk_vec2(0,0);
18720 select->userdata = nk_handle_ptr(0);
18721 select->rounding = 0.0f;
18722 select->color_factor = 1.0f;
18723 select->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
18724 select->draw_begin = 0;
18725 select->draw_end = 0;
18728 slider = &style->slider;
18729 nk_zero_struct(*slider);
18730 slider->normal = nk_style_item_hide();
18731 slider->hover = nk_style_item_hide();
18732 slider->active = nk_style_item_hide();
18733 slider->bar_normal = table[NK_COLOR_SLIDER];
18734 slider->bar_hover = table[NK_COLOR_SLIDER];
18735 slider->bar_active = table[NK_COLOR_SLIDER];
18736 slider->bar_filled = table[NK_COLOR_SLIDER_CURSOR];
18737 slider->cursor_normal = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR]);
18738 slider->cursor_hover = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_HOVER]);
18739 slider->cursor_active = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_ACTIVE]);
18740 slider->inc_symbol = NK_SYMBOL_TRIANGLE_RIGHT;
18741 slider->dec_symbol = NK_SYMBOL_TRIANGLE_LEFT;
18742 slider->cursor_size =
nk_vec2(16,16);
18743 slider->padding =
nk_vec2(2,2);
18744 slider->spacing =
nk_vec2(2,2);
18745 slider->userdata = nk_handle_ptr(0);
18746 slider->show_buttons = nk_false;
18747 slider->bar_height = 8;
18748 slider->rounding = 0;
18749 slider->color_factor = 1.0f;
18750 slider->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
18751 slider->draw_begin = 0;
18752 slider->draw_end = 0;
18755 button = &style->slider.inc_button;
18756 button->normal = nk_style_item_color(nk_rgb(40,40,40));
18757 button->hover = nk_style_item_color(nk_rgb(42,42,42));
18758 button->active = nk_style_item_color(nk_rgb(44,44,44));
18759 button->border_color = nk_rgb(65,65,65);
18760 button->text_background = nk_rgb(40,40,40);
18761 button->text_normal = nk_rgb(175,175,175);
18762 button->text_hover = nk_rgb(175,175,175);
18763 button->text_active = nk_rgb(175,175,175);
18764 button->padding =
nk_vec2(8.0f,8.0f);
18765 button->touch_padding =
nk_vec2(0.0f,0.0f);
18766 button->userdata = nk_handle_ptr(0);
18767 button->text_alignment = NK_TEXT_CENTERED;
18768 button->border = 1.0f;
18769 button->rounding = 0.0f;
18770 button->color_factor_text = 1.0f;
18771 button->color_factor_background = 1.0f;
18772 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
18773 button->draw_begin = 0;
18774 button->draw_end = 0;
18775 style->slider.dec_button = style->slider.inc_button;
18778 knob = &style->knob;
18779 nk_zero_struct(*knob);
18780 knob->normal = nk_style_item_hide();
18781 knob->hover = nk_style_item_hide();
18782 knob->active = nk_style_item_hide();
18783 knob->knob_normal = table[NK_COLOR_KNOB];
18784 knob->knob_hover = table[NK_COLOR_KNOB];
18785 knob->knob_active = table[NK_COLOR_KNOB];
18786 knob->cursor_normal = table[NK_COLOR_KNOB_CURSOR];
18787 knob->cursor_hover = table[NK_COLOR_KNOB_CURSOR_HOVER];
18788 knob->cursor_active = table[NK_COLOR_KNOB_CURSOR_ACTIVE];
18790 knob->knob_border_color = table[NK_COLOR_BORDER];
18791 knob->knob_border = 1.0f;
18793 knob->padding =
nk_vec2(2,2);
18794 knob->spacing =
nk_vec2(2,2);
18795 knob->cursor_width = 2;
18796 knob->color_factor = 1.0f;
18797 knob->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
18799 knob->userdata = nk_handle_ptr(0);
18800 knob->draw_begin = 0;
18801 knob->draw_end = 0;
18804 prog = &style->progress;
18805 nk_zero_struct(*prog);
18806 prog->normal = nk_style_item_color(table[NK_COLOR_SLIDER]);
18807 prog->hover = nk_style_item_color(table[NK_COLOR_SLIDER]);
18808 prog->active = nk_style_item_color(table[NK_COLOR_SLIDER]);
18809 prog->cursor_normal = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR]);
18810 prog->cursor_hover = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_HOVER]);
18811 prog->cursor_active = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_ACTIVE]);
18812 prog->border_color = nk_rgba(0,0,0,0);
18813 prog->cursor_border_color = nk_rgba(0,0,0,0);
18814 prog->userdata = nk_handle_ptr(0);
18815 prog->padding =
nk_vec2(4,4);
18816 prog->rounding = 0;
18818 prog->cursor_rounding = 0;
18819 prog->cursor_border = 0;
18820 prog->color_factor = 1.0f;
18821 prog->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
18822 prog->draw_begin = 0;
18823 prog->draw_end = 0;
18826 scroll = &style->scrollh;
18827 nk_zero_struct(*scroll);
18828 scroll->normal = nk_style_item_color(table[NK_COLOR_SCROLLBAR]);
18829 scroll->hover = nk_style_item_color(table[NK_COLOR_SCROLLBAR]);
18830 scroll->active = nk_style_item_color(table[NK_COLOR_SCROLLBAR]);
18831 scroll->cursor_normal = nk_style_item_color(table[NK_COLOR_SCROLLBAR_CURSOR]);
18832 scroll->cursor_hover = nk_style_item_color(table[NK_COLOR_SCROLLBAR_CURSOR_HOVER]);
18833 scroll->cursor_active = nk_style_item_color(table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE]);
18834 scroll->dec_symbol = NK_SYMBOL_CIRCLE_SOLID;
18835 scroll->inc_symbol = NK_SYMBOL_CIRCLE_SOLID;
18836 scroll->userdata = nk_handle_ptr(0);
18837 scroll->border_color = table[NK_COLOR_SCROLLBAR];
18838 scroll->cursor_border_color = table[NK_COLOR_SCROLLBAR];
18839 scroll->padding =
nk_vec2(0,0);
18840 scroll->show_buttons = nk_false;
18841 scroll->border = 0;
18842 scroll->rounding = 0;
18843 scroll->border_cursor = 0;
18844 scroll->rounding_cursor = 0;
18845 scroll->color_factor = 1.0f;
18846 scroll->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
18847 scroll->draw_begin = 0;
18848 scroll->draw_end = 0;
18849 style->scrollv = style->scrollh;
18852 button = &style->scrollh.inc_button;
18853 button->normal = nk_style_item_color(nk_rgb(40,40,40));
18854 button->hover = nk_style_item_color(nk_rgb(42,42,42));
18855 button->active = nk_style_item_color(nk_rgb(44,44,44));
18856 button->border_color = nk_rgb(65,65,65);
18857 button->text_background = nk_rgb(40,40,40);
18858 button->text_normal = nk_rgb(175,175,175);
18859 button->text_hover = nk_rgb(175,175,175);
18860 button->text_active = nk_rgb(175,175,175);
18861 button->padding =
nk_vec2(4.0f,4.0f);
18862 button->touch_padding =
nk_vec2(0.0f,0.0f);
18863 button->userdata = nk_handle_ptr(0);
18864 button->text_alignment = NK_TEXT_CENTERED;
18865 button->border = 1.0f;
18866 button->rounding = 0.0f;
18867 button->color_factor_text = 1.0f;
18868 button->color_factor_background = 1.0f;
18869 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
18870 button->draw_begin = 0;
18871 button->draw_end = 0;
18872 style->scrollh.dec_button = style->scrollh.inc_button;
18873 style->scrollv.inc_button = style->scrollh.inc_button;
18874 style->scrollv.dec_button = style->scrollh.inc_button;
18877 edit = &style->edit;
18878 nk_zero_struct(*edit);
18879 edit->normal = nk_style_item_color(table[NK_COLOR_EDIT]);
18880 edit->hover = nk_style_item_color(table[NK_COLOR_EDIT]);
18881 edit->active = nk_style_item_color(table[NK_COLOR_EDIT]);
18882 edit->cursor_normal = table[NK_COLOR_TEXT];
18883 edit->cursor_hover = table[NK_COLOR_TEXT];
18884 edit->cursor_text_normal= table[NK_COLOR_EDIT];
18885 edit->cursor_text_hover = table[NK_COLOR_EDIT];
18886 edit->border_color = table[NK_COLOR_BORDER];
18887 edit->text_normal = table[NK_COLOR_TEXT];
18888 edit->text_hover = table[NK_COLOR_TEXT];
18889 edit->text_active = table[NK_COLOR_TEXT];
18890 edit->selected_normal = table[NK_COLOR_TEXT];
18891 edit->selected_hover = table[NK_COLOR_TEXT];
18892 edit->selected_text_normal = table[NK_COLOR_EDIT];
18893 edit->selected_text_hover = table[NK_COLOR_EDIT];
18894 edit->scrollbar_size =
nk_vec2(10,10);
18895 edit->scrollbar = style->scrollv;
18896 edit->padding =
nk_vec2(4,4);
18897 edit->row_padding = 2;
18898 edit->cursor_size = 4;
18900 edit->rounding = 0;
18901 edit->color_factor = 1.0f;
18902 edit->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
18905 property = &style->property;
18906 nk_zero_struct(*property);
18907 property->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]);
18908 property->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]);
18909 property->active = nk_style_item_color(table[NK_COLOR_PROPERTY]);
18910 property->border_color = table[NK_COLOR_BORDER];
18911 property->label_normal = table[NK_COLOR_TEXT];
18912 property->label_hover = table[NK_COLOR_TEXT];
18913 property->label_active = table[NK_COLOR_TEXT];
18914 property->sym_left = NK_SYMBOL_TRIANGLE_LEFT;
18915 property->sym_right = NK_SYMBOL_TRIANGLE_RIGHT;
18916 property->userdata = nk_handle_ptr(0);
18917 property->padding =
nk_vec2(4,4);
18918 property->border = 1;
18919 property->rounding = 10;
18920 property->draw_begin = 0;
18921 property->draw_end = 0;
18922 property->color_factor = 1.0f;
18923 property->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
18926 button = &style->property.dec_button;
18927 nk_zero_struct(*button);
18928 button->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]);
18929 button->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]);
18930 button->active = nk_style_item_color(table[NK_COLOR_PROPERTY]);
18931 button->border_color = nk_rgba(0,0,0,0);
18932 button->text_background = table[NK_COLOR_PROPERTY];
18933 button->text_normal = table[NK_COLOR_TEXT];
18934 button->text_hover = table[NK_COLOR_TEXT];
18935 button->text_active = table[NK_COLOR_TEXT];
18936 button->padding =
nk_vec2(0.0f,0.0f);
18937 button->touch_padding =
nk_vec2(0.0f,0.0f);
18938 button->userdata = nk_handle_ptr(0);
18939 button->text_alignment = NK_TEXT_CENTERED;
18940 button->border = 0.0f;
18941 button->rounding = 0.0f;
18942 button->color_factor_text = 1.0f;
18943 button->color_factor_background = 1.0f;
18944 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
18945 button->draw_begin = 0;
18946 button->draw_end = 0;
18947 style->property.inc_button = style->property.dec_button;
18950 edit = &style->property.edit;
18951 nk_zero_struct(*edit);
18952 edit->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]);
18953 edit->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]);
18954 edit->active = nk_style_item_color(table[NK_COLOR_PROPERTY]);
18955 edit->border_color = nk_rgba(0,0,0,0);
18956 edit->cursor_normal = table[NK_COLOR_TEXT];
18957 edit->cursor_hover = table[NK_COLOR_TEXT];
18958 edit->cursor_text_normal= table[NK_COLOR_EDIT];
18959 edit->cursor_text_hover = table[NK_COLOR_EDIT];
18960 edit->text_normal = table[NK_COLOR_TEXT];
18961 edit->text_hover = table[NK_COLOR_TEXT];
18962 edit->text_active = table[NK_COLOR_TEXT];
18963 edit->selected_normal = table[NK_COLOR_TEXT];
18964 edit->selected_hover = table[NK_COLOR_TEXT];
18965 edit->selected_text_normal = table[NK_COLOR_EDIT];
18966 edit->selected_text_hover = table[NK_COLOR_EDIT];
18967 edit->padding =
nk_vec2(0,0);
18968 edit->cursor_size = 8;
18970 edit->rounding = 0;
18971 edit->color_factor = 1.0f;
18972 edit->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
18975 chart = &style->chart;
18976 nk_zero_struct(*chart);
18977 chart->background = nk_style_item_color(table[NK_COLOR_CHART]);
18978 chart->border_color = table[NK_COLOR_BORDER];
18979 chart->selected_color = table[NK_COLOR_CHART_COLOR_HIGHLIGHT];
18980 chart->color = table[NK_COLOR_CHART_COLOR];
18981 chart->padding =
nk_vec2(4,4);
18983 chart->rounding = 0;
18984 chart->color_factor = 1.0f;
18985 chart->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
18986 chart->show_markers = nk_true;
18989 combo = &style->combo;
18990 combo->normal = nk_style_item_color(table[NK_COLOR_COMBO]);
18991 combo->hover = nk_style_item_color(table[NK_COLOR_COMBO]);
18992 combo->active = nk_style_item_color(table[NK_COLOR_COMBO]);
18993 combo->border_color = table[NK_COLOR_BORDER];
18994 combo->label_normal = table[NK_COLOR_TEXT];
18995 combo->label_hover = table[NK_COLOR_TEXT];
18996 combo->label_active = table[NK_COLOR_TEXT];
18997 combo->sym_normal = NK_SYMBOL_TRIANGLE_DOWN;
18998 combo->sym_hover = NK_SYMBOL_TRIANGLE_DOWN;
18999 combo->sym_active = NK_SYMBOL_TRIANGLE_DOWN;
19000 combo->content_padding =
nk_vec2(4,4);
19001 combo->button_padding =
nk_vec2(0,4);
19002 combo->spacing =
nk_vec2(4,0);
19004 combo->rounding = 0;
19005 combo->color_factor = 1.0f;
19006 combo->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
19009 button = &style->combo.button;
19010 nk_zero_struct(*button);
19011 button->normal = nk_style_item_color(table[NK_COLOR_COMBO]);
19012 button->hover = nk_style_item_color(table[NK_COLOR_COMBO]);
19013 button->active = nk_style_item_color(table[NK_COLOR_COMBO]);
19014 button->border_color = nk_rgba(0,0,0,0);
19015 button->text_background = table[NK_COLOR_COMBO];
19016 button->text_normal = table[NK_COLOR_TEXT];
19017 button->text_hover = table[NK_COLOR_TEXT];
19018 button->text_active = table[NK_COLOR_TEXT];
19019 button->padding =
nk_vec2(2.0f,2.0f);
19020 button->touch_padding =
nk_vec2(0.0f,0.0f);
19021 button->userdata = nk_handle_ptr(0);
19022 button->text_alignment = NK_TEXT_CENTERED;
19023 button->border = 0.0f;
19024 button->rounding = 0.0f;
19025 button->color_factor_text = 1.0f;
19026 button->color_factor_background = 1.0f;
19027 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
19028 button->draw_begin = 0;
19029 button->draw_end = 0;
19033 tab->background = nk_style_item_color(table[NK_COLOR_TAB_HEADER]);
19034 tab->border_color = table[NK_COLOR_BORDER];
19035 tab->text = table[NK_COLOR_TEXT];
19036 tab->sym_minimize = NK_SYMBOL_TRIANGLE_RIGHT;
19037 tab->sym_maximize = NK_SYMBOL_TRIANGLE_DOWN;
19040 tab->indent = 10.0f;
19043 tab->color_factor = 1.0f;
19044 tab->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
19047 button = &style->tab.tab_minimize_button;
19048 nk_zero_struct(*button);
19049 button->normal = nk_style_item_color(table[NK_COLOR_TAB_HEADER]);
19050 button->hover = nk_style_item_color(table[NK_COLOR_TAB_HEADER]);
19051 button->active = nk_style_item_color(table[NK_COLOR_TAB_HEADER]);
19052 button->border_color = nk_rgba(0,0,0,0);
19053 button->text_background = table[NK_COLOR_TAB_HEADER];
19054 button->text_normal = table[NK_COLOR_TEXT];
19055 button->text_hover = table[NK_COLOR_TEXT];
19056 button->text_active = table[NK_COLOR_TEXT];
19057 button->padding =
nk_vec2(2.0f,2.0f);
19058 button->touch_padding =
nk_vec2(0.0f,0.0f);
19059 button->userdata = nk_handle_ptr(0);
19060 button->text_alignment = NK_TEXT_CENTERED;
19061 button->border = 0.0f;
19062 button->rounding = 0.0f;
19063 button->color_factor_text = 1.0f;
19064 button->color_factor_background = 1.0f;
19065 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
19066 button->draw_begin = 0;
19067 button->draw_end = 0;
19068 style->tab.tab_maximize_button =*button;
19071 button = &style->tab.node_minimize_button;
19072 nk_zero_struct(*button);
19073 button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]);
19074 button->hover = nk_style_item_color(table[NK_COLOR_WINDOW]);
19075 button->active = nk_style_item_color(table[NK_COLOR_WINDOW]);
19076 button->border_color = nk_rgba(0,0,0,0);
19077 button->text_background = table[NK_COLOR_TAB_HEADER];
19078 button->text_normal = table[NK_COLOR_TEXT];
19079 button->text_hover = table[NK_COLOR_TEXT];
19080 button->text_active = table[NK_COLOR_TEXT];
19081 button->padding =
nk_vec2(2.0f,2.0f);
19082 button->touch_padding =
nk_vec2(0.0f,0.0f);
19083 button->userdata = nk_handle_ptr(0);
19084 button->text_alignment = NK_TEXT_CENTERED;
19085 button->border = 0.0f;
19086 button->rounding = 0.0f;
19087 button->color_factor_text = 1.0f;
19088 button->color_factor_background = 1.0f;
19089 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
19090 button->draw_begin = 0;
19091 button->draw_end = 0;
19092 style->tab.node_maximize_button =*button;
19095 win = &style->window;
19096 win->header.align = NK_HEADER_RIGHT;
19097 win->header.close_symbol = NK_SYMBOL_X;
19098 win->header.minimize_symbol = NK_SYMBOL_MINUS;
19099 win->header.maximize_symbol = NK_SYMBOL_PLUS;
19100 win->header.normal = nk_style_item_color(table[NK_COLOR_HEADER]);
19101 win->header.hover = nk_style_item_color(table[NK_COLOR_HEADER]);
19102 win->header.active = nk_style_item_color(table[NK_COLOR_HEADER]);
19103 win->header.label_normal = table[NK_COLOR_TEXT];
19104 win->header.label_hover = table[NK_COLOR_TEXT];
19105 win->header.label_active = table[NK_COLOR_TEXT];
19106 win->header.label_padding =
nk_vec2(4,4);
19107 win->header.padding =
nk_vec2(4,4);
19108 win->header.spacing =
nk_vec2(0,0);
19111 button = &style->window.header.close_button;
19112 nk_zero_struct(*button);
19113 button->normal = nk_style_item_color(table[NK_COLOR_HEADER]);
19114 button->hover = nk_style_item_color(table[NK_COLOR_HEADER]);
19115 button->active = nk_style_item_color(table[NK_COLOR_HEADER]);
19116 button->border_color = nk_rgba(0,0,0,0);
19117 button->text_background = table[NK_COLOR_HEADER];
19118 button->text_normal = table[NK_COLOR_TEXT];
19119 button->text_hover = table[NK_COLOR_TEXT];
19120 button->text_active = table[NK_COLOR_TEXT];
19121 button->padding =
nk_vec2(0.0f,0.0f);
19122 button->touch_padding =
nk_vec2(0.0f,0.0f);
19123 button->userdata = nk_handle_ptr(0);
19124 button->text_alignment = NK_TEXT_CENTERED;
19125 button->border = 0.0f;
19126 button->rounding = 0.0f;
19127 button->color_factor_text = 1.0f;
19128 button->color_factor_background = 1.0f;
19129 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
19130 button->draw_begin = 0;
19131 button->draw_end = 0;
19134 button = &style->window.header.minimize_button;
19135 nk_zero_struct(*button);
19136 button->normal = nk_style_item_color(table[NK_COLOR_HEADER]);
19137 button->hover = nk_style_item_color(table[NK_COLOR_HEADER]);
19138 button->active = nk_style_item_color(table[NK_COLOR_HEADER]);
19139 button->border_color = nk_rgba(0,0,0,0);
19140 button->text_background = table[NK_COLOR_HEADER];
19141 button->text_normal = table[NK_COLOR_TEXT];
19142 button->text_hover = table[NK_COLOR_TEXT];
19143 button->text_active = table[NK_COLOR_TEXT];
19144 button->padding =
nk_vec2(0.0f,0.0f);
19145 button->touch_padding =
nk_vec2(0.0f,0.0f);
19146 button->userdata = nk_handle_ptr(0);
19147 button->text_alignment = NK_TEXT_CENTERED;
19148 button->border = 0.0f;
19149 button->rounding = 0.0f;
19150 button->color_factor_text = 1.0f;
19151 button->color_factor_background = 1.0f;
19152 button->disabled_factor = NK_WIDGET_DISABLED_FACTOR;
19153 button->draw_begin = 0;
19154 button->draw_end = 0;
19157 win->background = table[NK_COLOR_WINDOW];
19158 win->fixed_background = nk_style_item_color(table[NK_COLOR_WINDOW]);
19159 win->border_color = table[NK_COLOR_BORDER];
19160 win->popup_border_color = table[NK_COLOR_BORDER];
19161 win->combo_border_color = table[NK_COLOR_BORDER];
19162 win->contextual_border_color = table[NK_COLOR_BORDER];
19163 win->menu_border_color = table[NK_COLOR_BORDER];
19164 win->group_border_color = table[NK_COLOR_BORDER];
19165 win->tooltip_border_color = table[NK_COLOR_BORDER];
19166 win->scaler = nk_style_item_color(table[NK_COLOR_TEXT]);
19168 win->rounding = 0.0f;
19170 win->scrollbar_size =
nk_vec2(10,10);
19171 win->min_size =
nk_vec2(64,64);
19173 win->combo_border = 1.0f;
19174 win->contextual_border = 1.0f;
19175 win->menu_border = 1.0f;
19176 win->group_border = 1.0f;
19177 win->tooltip_border = 1.0f;
19178 win->popup_border = 1.0f;
19179 win->border = 2.0f;
19180 win->min_row_height_padding = 8;
19183 win->group_padding =
nk_vec2(4,4);
19184 win->popup_padding =
nk_vec2(4,4);
19185 win->combo_padding =
nk_vec2(4,4);
19186 win->contextual_padding =
nk_vec2(4,4);
19187 win->menu_padding =
nk_vec2(4,4);
19188 win->tooltip_padding =
nk_vec2(4,4);
19197 style = &ctx->style;
19198 style->font = font;
19199 ctx->stacks.fonts.head = 0;
19206 struct nk_config_stack_user_font *font_stack;
19207 struct nk_config_stack_user_font_element *element;
19210 if (!ctx)
return 0;
19212 font_stack = &ctx->stacks.fonts;
19213 NK_ASSERT(font_stack->head < (
int)NK_LEN(font_stack->elements));
19214 if (font_stack->head >= (
int)NK_LEN(font_stack->elements))
19217 element = &font_stack->elements[font_stack->head++];
19218 element->address = &ctx->style.font;
19219 element->old_value = ctx->style.font;
19220 ctx->style.font = font;
19226 struct nk_config_stack_user_font *font_stack;
19227 struct nk_config_stack_user_font_element *element;
19230 if (!ctx)
return 0;
19232 font_stack = &ctx->stacks.fonts;
19233 NK_ASSERT(font_stack->head > 0);
19234 if (font_stack->head < 1)
19237 element = &font_stack->elements[--font_stack->head];
19238 *element->address = element->old_value;
19241#define NK_STYLE_PUSH_IMPLEMENATION(prefix, type, stack) \
19242nk_style_push_##type(struct nk_context *ctx, prefix##_##type *address, prefix##_##type value)\
19244 struct nk_config_stack_##type * type_stack;\
19245 struct nk_config_stack_##type##_element *element;\
19247 if (!ctx) return 0;\
19248 type_stack = &ctx->stacks.stack;\
19249 NK_ASSERT(type_stack->head < (int)NK_LEN(type_stack->elements));\
19250 if (type_stack->head >= (int)NK_LEN(type_stack->elements))\
19252 element = &type_stack->elements[type_stack->head++];\
19253 element->address = address;\
19254 element->old_value = *address;\
19258#define NK_STYLE_POP_IMPLEMENATION(type, stack) \
19259nk_style_pop_##type(struct nk_context *ctx)\
19261 struct nk_config_stack_##type *type_stack;\
19262 struct nk_config_stack_##type##_element *element;\
19264 if (!ctx) return 0;\
19265 type_stack = &ctx->stacks.stack;\
19266 NK_ASSERT(type_stack->head > 0);\
19267 if (type_stack->head < 1)\
19269 element = &type_stack->elements[--type_stack->head];\
19270 *element->address = element->old_value;\
19273NK_API nk_bool NK_STYLE_PUSH_IMPLEMENATION(
struct nk, style_item, style_items)
19274NK_API nk_bool NK_STYLE_PUSH_IMPLEMENATION(nk,
float, floats)
19275NK_API nk_bool NK_STYLE_PUSH_IMPLEMENATION(
struct nk,
vec2, vectors)
19276NK_API nk_bool NK_STYLE_PUSH_IMPLEMENATION(nk,flags, flags)
19277NK_API nk_bool NK_STYLE_PUSH_IMPLEMENATION(
struct nk,color, colors)
19279NK_API nk_bool NK_STYLE_POP_IMPLEMENATION(style_item, style_items)
19280NK_API nk_bool NK_STYLE_POP_IMPLEMENATION(
float,floats)
19281NK_API nk_bool NK_STYLE_POP_IMPLEMENATION(
vec2, vectors)
19282NK_API nk_bool NK_STYLE_POP_IMPLEMENATION(flags,flags)
19283NK_API nk_bool NK_STYLE_POP_IMPLEMENATION(color,colors)
19286nk_style_set_cursor(
struct nk_context *ctx,
enum nk_style_cursor c)
19290 if (!ctx)
return 0;
19291 style = &ctx->style;
19292 if (style->cursors[c]) {
19293 style->cursor_active = style->cursors[c];
19301 ctx->style.cursor_visible = nk_true;
19306 ctx->style.cursor_visible = nk_false;
19309nk_style_load_cursor(
struct nk_context *ctx,
enum nk_style_cursor cursor,
19315 style = &ctx->style;
19316 style->cursors[cursor] = c;
19325 style = &ctx->style;
19326 for (i = 0; i < NK_CURSOR_COUNT; ++i)
19327 style->cursors[i] = &cursors[i];
19328 style->cursor_visible = nk_true;
19344 nk_zero_struct(*ctx);
19345 nk_style_default(ctx);
19347 if (font) ctx->style.font = font;
19348#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
19349 nk_draw_list_init(&ctx->draw_list);
19352#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
19357 alloc.userdata.ptr = 0;
19358 alloc.alloc = nk_malloc;
19359 alloc.free = nk_mfree;
19360 return nk_init(ctx, &alloc, font);
19368 if (!memory)
return 0;
19369 nk_setup(ctx, font);
19370 nk_buffer_init_fixed(&ctx->memory, memory, size);
19371 ctx->use_pool = nk_false;
19380 if (!cmds || !pool)
return 0;
19382 nk_setup(ctx, font);
19383 ctx->memory = *cmds;
19384 if (pool->
type == NK_BUFFER_FIXED) {
19386 nk_pool_init_fixed(&ctx->pool, pool->
memory.ptr, pool->
memory.size);
19390 nk_pool_init(&ctx->pool, alloc, NK_POOL_DEFAULT_CAPACITY);
19392 ctx->use_pool = nk_true;
19400 if (!alloc)
return 0;
19401 nk_setup(ctx, font);
19402 nk_buffer_init(&ctx->memory, alloc, NK_DEFAULT_COMMAND_BUFFER_SIZE);
19403 nk_pool_init(&ctx->pool, alloc, NK_POOL_DEFAULT_CAPACITY);
19404 ctx->use_pool = nk_true;
19407#ifdef NK_INCLUDE_COMMAND_USERDATA
19412 ctx->userdata = handle;
19414 ctx->current->buffer.userdata = handle;
19422 nk_buffer_free(&ctx->memory);
19424 nk_pool_free(&ctx->pool);
19426 nk_zero(&ctx->input,
sizeof(ctx->input));
19427 nk_zero(&ctx->style,
sizeof(ctx->style));
19428 nk_zero(&ctx->memory,
sizeof(ctx->memory));
19448 nk_buffer_clear(&ctx->memory);
19449 else nk_buffer_reset(&ctx->memory, NK_BUFFER_FRONT);
19452 ctx->memory.
calls = 0;
19453 ctx->last_widget_state = 0;
19454 ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_ARROW];
19463 iter->seq == ctx->seq) {
19470 iter == ctx->active) {
19471 ctx->active = iter->prev;
19472 ctx->end = iter->prev;
19479 if (iter->popup.win && iter->popup.win->seq != ctx->seq) {
19480 nk_free_window(ctx, iter->popup.win);
19481 iter->popup.win = 0;
19484 {
struct nk_table *n, *it = iter->tables;
19487 if (it->seq != ctx->seq) {
19488 nk_remove_table(iter, it);
19490 nk_free_table(ctx, it);
19491 if (it == iter->tables)
19498 nk_remove_window(ctx, iter);
19499 nk_free_window(ctx, iter);
19501 }
else iter = iter->next;
19510 if (!ctx || !buffer)
return;
19512 buffer->end = buffer->begin;
19513 buffer->last = buffer->begin;
19514 buffer->clip = nk_null_rect;
19521 nk_start_buffer(ctx, &win->buffer);
19529 if (!ctx || !win)
return;
19532 buf = &win->popup.buf;
19533 buf->begin = win->buffer.end;
19534 buf->end = win->buffer.end;
19535 buf->parent = win->buffer.last;
19536 buf->last = buf->begin;
19537 buf->active = nk_true;
19545 if (!ctx || !win)
return;
19547 buf = &win->popup.buf;
19548 buf->last = win->buffer.last;
19549 buf->end = win->buffer.end;
19556 if (!ctx || !buffer)
return;
19568 if (!ctx || !win)
return;
19569 nk_finish_buffer(ctx, &win->buffer);
19570 if (!win->popup.buf.active)
return;
19572 buf = &win->popup.buf;
19573 memory = ctx->memory.
memory.ptr;
19574 parent_last = nk_ptr_add(
struct nk_command, memory, buf->parent);
19575 parent_last->next = buf->end;
19582 nk_byte *buffer = 0;
19585 if (!ctx->style.cursor_active)
19586 ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_ARROW];
19587 if (ctx->style.cursor_active && !ctx->input.mouse.grabbed && ctx->style.cursor_visible) {
19589 const struct nk_cursor *cursor = ctx->style.cursor_active;
19590 nk_command_buffer_init(&ctx->
overlay, &ctx->memory, NK_CLIPPING_OFF);
19591 nk_start_buffer(ctx, &ctx->
overlay);
19593 mouse_bounds.x = ctx->input.mouse.pos.x - cursor->offset.x;
19594 mouse_bounds.y = ctx->input.mouse.pos.y - cursor->offset.y;
19595 mouse_bounds.w = cursor->size.x;
19596 mouse_bounds.h = cursor->size.y;
19599 nk_finish_buffer(ctx, &ctx->
overlay);
19603 buffer = (nk_byte*)ctx->memory.
memory.ptr;
19606 if (it->buffer.last == it->buffer.begin || (it->flags &
NK_WINDOW_HIDDEN)||
19607 it->seq != ctx->seq)
19610 cmd = nk_ptr_add(
struct nk_command, buffer, it->buffer.last);
19611 while (next && ((next->buffer.last == next->buffer.begin) ||
19615 if (next) cmd->next = next->buffer.begin;
19623 if (!it->popup.buf.active)
19626 buf = &it->popup.buf;
19627 cmd->next = buf->begin;
19628 cmd = nk_ptr_add(
struct nk_command, buffer, buf->last);
19629 buf->active = nk_false;
19635 cmd->next = ctx->
overlay.begin;
19636 else cmd->next = ctx->memory.
allocated;
19645 if (!ctx)
return 0;
19646 if (!ctx->count)
return 0;
19648 buffer = (nk_byte*)ctx->memory.
memory.ptr;
19651 ctx->
build = nk_true;
19654 while (iter && ((iter->buffer.begin == iter->buffer.end) ||
19657 if (!iter)
return 0;
19658 return nk_ptr_add_const(
struct nk_command, buffer, iter->buffer.begin);
19667 if (!ctx || !cmd || !ctx->count)
return 0;
19668 if (cmd->next >= ctx->memory.
allocated)
return 0;
19669 buffer = (nk_byte*)ctx->memory.
memory.ptr;
19670 next = nk_ptr_add_const(
struct nk_command, buffer, cmd->next);
19686 unsigned int capacity)
19688 NK_ASSERT(capacity >= 1);
19689 nk_zero(pool,
sizeof(*pool));
19690 pool->alloc = *alloc;
19691 pool->capacity = capacity;
19692 pool->type = NK_BUFFER_DYNAMIC;
19696nk_pool_free(
struct nk_pool *pool)
19700 iter = pool->pages;
19701 if (pool->type == NK_BUFFER_FIXED)
return;
19703 struct nk_page *next = iter->next;
19704 pool->alloc.free(pool->alloc.userdata, iter);
19709nk_pool_init_fixed(
struct nk_pool *pool,
void *memory, nk_size size)
19711 nk_zero(pool,
sizeof(*pool));
19712 NK_ASSERT(size >=
sizeof(
struct nk_page));
19713 if (size <
sizeof(
struct nk_page))
return;
19716 pool->pages = (
struct nk_page*)memory;
19717 pool->type = NK_BUFFER_FIXED;
19721nk_pool_alloc(
struct nk_pool *pool)
19723 if (!pool->pages || pool->pages->size >= pool->capacity) {
19726 if (pool->type == NK_BUFFER_FIXED) {
19727 NK_ASSERT(pool->pages);
19728 if (!pool->pages)
return 0;
19729 NK_ASSERT(pool->pages->size < pool->capacity);
19732 nk_size size =
sizeof(
struct nk_page);
19734 page = (
struct nk_page*)pool->alloc.alloc(pool->alloc.userdata,0, size);
19735 page->next = pool->pages;
19736 pool->pages = page;
19739 }
return &pool->pages->win[pool->pages->size++];
19752nk_create_page_element(
struct nk_context *ctx)
19755 if (ctx->freelist) {
19757 elem = ctx->freelist;
19758 ctx->freelist = elem->next;
19759 }
else if (ctx->use_pool) {
19761 elem = nk_pool_alloc(&ctx->pool);
19763 if (!elem)
return 0;
19768 elem = (
struct nk_page_element*)nk_buffer_alloc(&ctx->memory, NK_BUFFER_BACK, size, align);
19770 if (!elem)
return 0;
19772 nk_zero_struct(*elem);
19778nk_link_page_element_into_freelist(
struct nk_context *ctx,
19782 if (!ctx->freelist) {
19783 ctx->freelist = elem;
19785 elem->next = ctx->freelist;
19786 ctx->freelist = elem;
19793 if (ctx->use_pool) {
19794 nk_link_page_element_into_freelist(ctx, elem);
19798 {
void *elem_end = (
void*)(elem + 1);
19799 void *buffer_end = (nk_byte*)ctx->memory.
memory.ptr + ctx->memory.
size;
19800 if (elem_end == buffer_end)
19802 else nk_link_page_element_into_freelist(ctx, elem);}
19818 elem = nk_create_page_element(ctx);
19819 if (!elem)
return 0;
19820 nk_zero_struct(*elem);
19821 return &elem->data.tbl;
19828 nk_free_page_element(ctx, pe);
19833 if (!win->tables) {
19838 win->table_count = 1;
19841 win->tables->prev = tbl;
19842 tbl->next = win->tables;
19846 win->table_count++;
19851 if (win->tables == tbl)
19852 win->tables = tbl->next;
19854 tbl->next->prev = tbl->prev;
19856 tbl->prev->next = tbl->next;
19862 nk_hash name, nk_uint value)
19866 if (!win || !ctx)
return 0;
19867 if (!win->tables || win->tables->size >= NK_VALUE_PAGE_CAPACITY) {
19868 struct nk_table *tbl = nk_create_table(ctx);
19870 if (!tbl)
return 0;
19871 nk_push_table(win, tbl);
19873 win->tables->seq = win->seq;
19874 win->tables->keys[win->tables->size] = name;
19875 win->tables->values[win->tables->size] = value;
19876 return &win->tables->values[win->tables->size++];
19879nk_find_value(
const struct nk_window *win, nk_hash name)
19881 struct nk_table *iter = win->tables;
19883 unsigned int i = 0;
19884 unsigned int size = iter->size;
19885 for (i = 0; i < size; ++i) {
19886 if (iter->keys[i] == name) {
19887 iter->seq = win->seq;
19888 return &iter->values[i];
19890 } size = NK_VALUE_PAGE_CAPACITY;
19908 elem = nk_create_page_element(ctx);
19909 if (!elem)
return 0;
19910 nk_zero_struct(*elem);
19911 return &elem->data.pan;
19918 nk_free_page_element(ctx, pe);
19921nk_panel_has_header(nk_flags flags,
const char *title)
19923 nk_bool active = 0;
19924 active = (flags & (NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE));
19925 active = active || (flags & NK_WINDOW_TITLE);
19930nk_panel_get_padding(const struct
nk_style *style,
enum nk_panel_type type)
19934 case NK_PANEL_WINDOW:
return style->window.padding;
19935 case NK_PANEL_GROUP:
return style->window.group_padding;
19936 case NK_PANEL_POPUP:
return style->window.popup_padding;
19937 case NK_PANEL_CONTEXTUAL:
return style->window.contextual_padding;
19938 case NK_PANEL_COMBO:
return style->window.combo_padding;
19939 case NK_PANEL_MENU:
return style->window.menu_padding;
19940 case NK_PANEL_TOOLTIP:
return style->window.menu_padding;}
19943nk_panel_get_border(
const struct nk_style *style, nk_flags flags,
19944 enum nk_panel_type type)
19946 if (flags & NK_WINDOW_BORDER) {
19949 case NK_PANEL_WINDOW:
return style->window.border;
19950 case NK_PANEL_GROUP:
return style->window.group_border;
19951 case NK_PANEL_POPUP:
return style->window.popup_border;
19952 case NK_PANEL_CONTEXTUAL:
return style->window.contextual_border;
19953 case NK_PANEL_COMBO:
return style->window.combo_border;
19954 case NK_PANEL_MENU:
return style->window.menu_border;
19955 case NK_PANEL_TOOLTIP:
return style->window.menu_border;
19959nk_panel_get_border_color(const struct
nk_style *style,
enum nk_panel_type type)
19963 case NK_PANEL_WINDOW:
return style->window.border_color;
19964 case NK_PANEL_GROUP:
return style->window.group_border_color;
19965 case NK_PANEL_POPUP:
return style->window.popup_border_color;
19966 case NK_PANEL_CONTEXTUAL:
return style->window.contextual_border_color;
19967 case NK_PANEL_COMBO:
return style->window.combo_border_color;
19968 case NK_PANEL_MENU:
return style->window.menu_border_color;
19969 case NK_PANEL_TOOLTIP:
return style->window.menu_border_color;}
19972nk_panel_is_sub(
enum nk_panel_type type)
19974 return ((
int)type & (
int)NK_PANEL_SET_SUB)?1:0;
19977nk_panel_is_nonblock(
enum nk_panel_type type)
19979 return ((
int)type & (
int)NK_PANEL_SET_NONBLOCK)?1:0;
19982nk_panel_begin(
struct nk_context *ctx,
const char *title,
enum nk_panel_type panel_type)
19991 struct nk_vec2 scrollbar_size;
19992 struct nk_vec2 panel_padding;
19995 NK_ASSERT(ctx->current);
19996 NK_ASSERT(ctx->current->layout);
19997 if (!ctx || !ctx->current || !ctx->current->layout)
return 0;
19998 nk_zero(ctx->current->layout,
sizeof(*ctx->current->layout));
20000 nk_zero(ctx->current->layout,
sizeof(
struct nk_panel));
20001 ctx->current->layout->type = panel_type;
20005 style = &ctx->style;
20006 font = style->font;
20007 win = ctx->current;
20008 layout = win->layout;
20009 out = &win->buffer;
20010 in = (win->flags & NK_WINDOW_NO_INPUT) ? 0: &ctx->input;
20011#ifdef NK_INCLUDE_COMMAND_USERDATA
20012 win->buffer.userdata = ctx->userdata;
20015 scrollbar_size = style->window.scrollbar_size;
20016 panel_padding = nk_panel_get_padding(style, panel_type);
20019 if ((win->flags & NK_WINDOW_MOVABLE) && !(win->flags &
NK_WINDOW_ROM)) {
20020 nk_bool left_mouse_down;
20021 unsigned int left_mouse_clicked;
20022 int left_mouse_click_in_cursor;
20026 header.x = win->bounds.x;
20027 header.y = win->bounds.y;
20028 header.w = win->bounds.w;
20029 if (nk_panel_has_header(win->flags, title)) {
20030 header.h = font->
height + 2.0f * style->window.header.padding.y;
20031 header.h += 2.0f * style->window.header.label_padding.y;
20032 }
else header.h = panel_padding.y;
20035 left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
20036 left_mouse_clicked = in->mouse.buttons[NK_BUTTON_LEFT].clicked;
20037 left_mouse_click_in_cursor = nk_input_has_mouse_click_down_in_rect(in,
20038 NK_BUTTON_LEFT, header, nk_true);
20039 if (left_mouse_down && left_mouse_click_in_cursor && !left_mouse_clicked) {
20040 win->bounds.x = win->bounds.x + in->mouse.delta.x;
20041 win->bounds.y = win->bounds.y + in->mouse.delta.y;
20042 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x += in->mouse.delta.x;
20043 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y += in->mouse.delta.y;
20044 ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_MOVE];
20049 layout->type = panel_type;
20050 layout->flags = win->flags;
20051 layout->bounds = win->bounds;
20052 layout->bounds.x += panel_padding.x;
20053 layout->bounds.w -= 2*panel_padding.x;
20054 if (win->flags & NK_WINDOW_BORDER) {
20055 layout->border = nk_panel_get_border(style, win->flags, panel_type);
20056 layout->bounds = nk_shrink_rect(layout->bounds, layout->border);
20057 }
else layout->border = 0;
20058 layout->at_y = layout->bounds.y;
20059 layout->at_x = layout->bounds.x;
20061 layout->header_height = 0;
20062 layout->footer_height = 0;
20064 layout->row.index = 0;
20065 layout->row.columns = 0;
20066 layout->row.ratio = 0;
20067 layout->row.item_width = 0;
20068 layout->row.tree_depth = 0;
20069 layout->row.height = panel_padding.y;
20070 layout->has_scrolling = nk_true;
20071 if (!(win->flags & NK_WINDOW_NO_SCROLLBAR))
20072 layout->bounds.w -= scrollbar_size.x;
20073 if (!nk_panel_is_nonblock(panel_type)) {
20074 layout->footer_height = 0;
20075 if (!(win->flags & NK_WINDOW_NO_SCROLLBAR) || win->flags & NK_WINDOW_SCALABLE)
20076 layout->footer_height = scrollbar_size.y;
20077 layout->bounds.h -= layout->footer_height;
20081 if (nk_panel_has_header(win->flags, title))
20083 struct nk_text text;
20088 header.x = win->bounds.x;
20089 header.y = win->bounds.y;
20090 header.w = win->bounds.w;
20091 header.h = font->
height + 2.0f * style->window.header.padding.y;
20092 header.h += (2.0f * style->window.header.label_padding.y);
20095 layout->header_height = header.h;
20096 layout->bounds.y += header.h;
20097 layout->bounds.h -= header.h;
20098 layout->at_y += header.h;
20101 if (ctx->active == win) {
20102 background = &style->window.header.active;
20103 text.text = style->window.header.label_active;
20104 }
else if (nk_input_is_mouse_hovering_rect(&ctx->input, header)) {
20105 background = &style->window.header.hover;
20106 text.text = style->window.header.label_hover;
20108 background = &style->window.header.normal;
20109 text.text = style->window.header.label_normal;
20115 switch(background->type) {
20116 case NK_STYLE_ITEM_IMAGE:
20117 text.background = nk_rgba(0,0,0,0);
20118 nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
20120 case NK_STYLE_ITEM_NINE_SLICE:
20121 text.background = nk_rgba(0, 0, 0, 0);
20122 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_white);
20124 case NK_STYLE_ITEM_COLOR:
20125 text.background = background->data.color;
20132 button.y = header.y + style->window.header.padding.y;
20133 button.h = header.h - 2 * style->window.header.padding.y;
20134 button.w = button.h;
20135 if (win->flags & NK_WINDOW_CLOSABLE) {
20137 if (style->window.header.align == NK_HEADER_RIGHT) {
20138 button.x = (header.w + header.x) - (button.w + style->window.header.padding.x);
20139 header.w -= button.w + style->window.header.spacing.x + style->window.header.padding.x;
20141 button.x = header.x + style->window.header.padding.x;
20142 header.x += button.w + style->window.header.spacing.x + style->window.header.padding.x;
20145 if (nk_do_button_symbol(&ws, &win->buffer, button,
20146 style->window.header.close_symbol, NK_BUTTON_DEFAULT,
20147 &style->window.header.close_button, in, style->font) && !(win->flags &
NK_WINDOW_ROM))
20155 if (win->flags & NK_WINDOW_MINIMIZABLE) {
20157 if (style->window.header.align == NK_HEADER_RIGHT) {
20158 button.x = (header.w + header.x) - button.w;
20159 if (!(win->flags & NK_WINDOW_CLOSABLE)) {
20160 button.x -= style->window.header.padding.x;
20161 header.w -= style->window.header.padding.x;
20163 header.w -= button.w + style->window.header.spacing.x;
20165 button.x = header.x;
20166 header.x += button.w + style->window.header.spacing.x + style->window.header.padding.x;
20168 if (nk_do_button_symbol(&ws, &win->buffer, button, (layout->flags &
NK_WINDOW_MINIMIZED)?
20169 style->window.header.maximize_symbol: style->window.header.minimize_symbol,
20170 NK_BUTTON_DEFAULT, &style->window.header.minimize_button, in, style->font) && !(win->flags &
NK_WINDOW_ROM))
20177 int text_len = nk_strlen(title);
20178 struct nk_rect label = {0,0,0,0};
20179 float t = font->
width(font->userdata, font->
height, title, text_len);
20182 label.x = header.x + style->window.header.padding.x;
20183 label.x += style->window.header.label_padding.x;
20184 label.y = header.y + style->window.header.label_padding.y;
20185 label.h = font->
height + 2 * style->window.header.label_padding.y;
20186 label.w = t + 2 * style->window.header.spacing.x;
20187 label.w = NK_CLAMP(0, label.w, header.x + header.w - label.x);
20188 nk_widget_text(out, label, (
const char*)title, text_len, &text, NK_TEXT_LEFT, font);}
20194 body.x = win->bounds.x;
20195 body.w = win->bounds.w;
20196 body.y = (win->bounds.y + layout->header_height);
20197 body.h = (win->bounds.h - layout->header_height);
20199 switch(style->window.fixed_background.type) {
20200 case NK_STYLE_ITEM_IMAGE:
20201 nk_draw_image(out, body, &style->window.fixed_background.data.image, nk_white);
20203 case NK_STYLE_ITEM_NINE_SLICE:
20204 nk_draw_nine_slice(out, body, &style->window.fixed_background.data.slice, nk_white);
20206 case NK_STYLE_ITEM_COLOR:
20207 nk_fill_rect(out, body, style->window.rounding, style->window.fixed_background.data.color);
20214 layout->clip = layout->bounds;
20215 nk_unify(&clip, &win->buffer.clip, layout->clip.x, layout->clip.y,
20216 layout->clip.x + layout->clip.w, layout->clip.y + layout->clip.h);
20217 nk_push_scissor(out, clip);
20218 layout->clip = clip;}
20230 struct nk_vec2 scrollbar_size;
20231 struct nk_vec2 panel_padding;
20234 NK_ASSERT(ctx->current);
20235 NK_ASSERT(ctx->current->layout);
20236 if (!ctx || !ctx->current || !ctx->current->layout)
20239 window = ctx->current;
20240 layout = window->layout;
20241 style = &ctx->style;
20242 out = &window->buffer;
20243 in = (layout->flags &
NK_WINDOW_ROM || layout->flags & NK_WINDOW_NO_INPUT) ? 0 :&ctx->input;
20244 if (!nk_panel_is_sub(layout->type))
20245 nk_push_scissor(out, nk_null_rect);
20248 scrollbar_size = style->window.scrollbar_size;
20249 panel_padding = nk_panel_get_padding(style, layout->type);
20252 layout->at_y += layout->row.height;
20259 if (layout->at_y < (layout->bounds.y + layout->bounds.h))
20260 layout->bounds.h = layout->at_y - layout->bounds.y;
20263 empty_space.x = window->bounds.x;
20264 empty_space.y = layout->bounds.y;
20265 empty_space.h = panel_padding.y;
20266 empty_space.w = window->bounds.w;
20267 nk_fill_rect(out, empty_space, 0, style->window.background);
20270 empty_space.x = window->bounds.x;
20271 empty_space.y = layout->bounds.y;
20272 empty_space.w = panel_padding.x + layout->border;
20273 empty_space.h = layout->bounds.h;
20274 nk_fill_rect(out, empty_space, 0, style->window.background);
20277 empty_space.x = layout->bounds.x + layout->bounds.w;
20278 empty_space.y = layout->bounds.y;
20279 empty_space.w = panel_padding.x + layout->border;
20280 empty_space.h = layout->bounds.h;
20281 if (*layout->offset_y == 0 && !(layout->flags & NK_WINDOW_NO_SCROLLBAR))
20282 empty_space.w += scrollbar_size.x;
20283 nk_fill_rect(out, empty_space, 0, style->window.background);
20286 if (layout->footer_height > 0) {
20287 empty_space.x = window->bounds.x;
20288 empty_space.y = layout->bounds.y + layout->bounds.h;
20289 empty_space.w = window->bounds.w;
20290 empty_space.h = layout->footer_height;
20291 nk_fill_rect(out, empty_space, 0, style->window.background);
20296 if (!(layout->flags & NK_WINDOW_NO_SCROLLBAR) &&
20298 window->scrollbar_hiding_timer < NK_SCROLLBAR_HIDING_TIMEOUT)
20301 int scroll_has_scrolling;
20302 float scroll_target;
20303 float scroll_offset;
20308 if (nk_panel_is_sub(layout->type))
20311 struct nk_window *root_window = window;
20312 struct nk_panel *root_panel = window->layout;
20313 while (root_panel->parent)
20314 root_panel = root_panel->parent;
20315 while (root_window->parent)
20316 root_window = root_window->parent;
20319 scroll_has_scrolling = nk_false;
20320 if ((root_window == ctx->active) && layout->has_scrolling) {
20322 if (nk_input_is_mouse_hovering_rect(in, layout->bounds) &&
20323 NK_INTERSECT(layout->bounds.x, layout->bounds.y, layout->bounds.w, layout->bounds.h,
20324 root_panel->clip.x, root_panel->clip.y, root_panel->clip.w, root_panel->clip.h))
20327 root_panel = window->layout;
20328 while (root_panel->parent) {
20329 root_panel->has_scrolling = nk_false;
20330 root_panel = root_panel->parent;
20332 root_panel->has_scrolling = nk_false;
20333 scroll_has_scrolling = nk_true;
20338 scroll_has_scrolling = (window == ctx->active) && layout->has_scrolling;
20339 if (in && (in->mouse.scroll_delta.y > 0 || in->mouse.scroll_delta.x > 0) && scroll_has_scrolling)
20340 window->scrolled = nk_true;
20341 else window->scrolled = nk_false;
20346 nk_flags state = 0;
20347 scroll.x = layout->bounds.x + layout->bounds.w + panel_padding.x;
20348 scroll.y = layout->bounds.y;
20349 scroll.w = scrollbar_size.x;
20350 scroll.h = layout->bounds.h;
20352 scroll_offset = (float)*layout->offset_y;
20353 scroll_step = scroll.h * 0.10f;
20354 scroll_inc = scroll.h * 0.01f;
20355 scroll_target = (float)(
int)(layout->at_y - scroll.y);
20356 scroll_offset = nk_do_scrollbarv(&state, out, scroll, scroll_has_scrolling,
20357 scroll_offset, scroll_target, scroll_step, scroll_inc,
20358 &ctx->style.scrollv, in, style->font);
20359 *layout->offset_y = (nk_uint)scroll_offset;
20360 if (in && scroll_has_scrolling)
20361 in->mouse.scroll_delta.y = 0;
20365 nk_flags state = 0;
20366 scroll.x = layout->bounds.x;
20367 scroll.y = layout->bounds.y + layout->bounds.h;
20368 scroll.w = layout->bounds.w;
20369 scroll.h = scrollbar_size.y;
20371 scroll_offset = (float)*layout->offset_x;
20372 scroll_target = (float)(
int)(layout->max_x - scroll.x);
20373 scroll_step = layout->max_x * 0.05f;
20374 scroll_inc = layout->max_x * 0.005f;
20375 scroll_offset = nk_do_scrollbarh(&state, out, scroll, scroll_has_scrolling,
20376 scroll_offset, scroll_target, scroll_step, scroll_inc,
20377 &ctx->style.scrollh, in, style->font);
20378 *layout->offset_x = (nk_uint)scroll_offset;
20383 if (window->flags & NK_WINDOW_SCROLL_AUTO_HIDE) {
20384 int has_input = ctx->input.mouse.delta.x != 0 || ctx->input.mouse.delta.y != 0 || ctx->input.mouse.scroll_delta.y != 0;
20386 int any_item_active = (ctx->last_widget_state & NK_WIDGET_STATE_MODIFIED);
20387 if ((!has_input && is_window_hovered) || (!is_window_hovered && !any_item_active))
20388 window->scrollbar_hiding_timer += ctx->delta_time_seconds;
20389 else window->scrollbar_hiding_timer = 0;
20390 }
else window->scrollbar_hiding_timer = 0;
20393 if (layout->flags & NK_WINDOW_BORDER)
20395 struct nk_color border_color = nk_panel_get_border_color(style, layout->type);
20397 ? (style->window.border + window->bounds.y + layout->header_height)
20399 ? (layout->bounds.y + layout->bounds.h + layout->footer_height)
20400 : (window->bounds.y + window->bounds.h));
20401 struct nk_rect b = window->bounds;
20402 b.h = padding_y - window->bounds.y;
20403 nk_stroke_rect(out, b, style->window.rounding, layout->border, border_color);
20407 if ((layout->flags & NK_WINDOW_SCALABLE) && in && !(layout->flags &
NK_WINDOW_MINIMIZED))
20411 scaler.w = scrollbar_size.x;
20412 scaler.h = scrollbar_size.y;
20413 scaler.y = layout->bounds.y + layout->bounds.h;
20414 if (layout->flags & NK_WINDOW_SCALE_LEFT)
20415 scaler.x = layout->bounds.x - panel_padding.x * 0.5f;
20416 else scaler.x = layout->bounds.x + layout->bounds.w + panel_padding.x;
20417 if (layout->flags & NK_WINDOW_NO_SCROLLBAR)
20418 scaler.x -= scaler.w;
20422 if (item->type == NK_STYLE_ITEM_IMAGE)
20425 if (layout->flags & NK_WINDOW_SCALE_LEFT) {
20426 nk_fill_triangle(out, scaler.x, scaler.y, scaler.x,
20427 scaler.y + scaler.h, scaler.x + scaler.w,
20428 scaler.y + scaler.h, item->data.color);
20430 nk_fill_triangle(out, scaler.x + scaler.w, scaler.y, scaler.x + scaler.w,
20431 scaler.y + scaler.h, scaler.x, scaler.y + scaler.h, item->data.color);
20437 struct nk_vec2 window_size = style->window.min_size;
20438 int left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
20439 int left_mouse_click_in_scaler = nk_input_has_mouse_click_down_in_rect(in,
20440 NK_BUTTON_LEFT, scaler, nk_true);
20442 if (left_mouse_down && left_mouse_click_in_scaler) {
20443 float delta_x = in->mouse.delta.x;
20444 if (layout->flags & NK_WINDOW_SCALE_LEFT) {
20445 delta_x = -delta_x;
20446 window->bounds.x += in->mouse.delta.x;
20449 if (window->bounds.w + delta_x >= window_size.x) {
20450 if ((delta_x < 0) || (delta_x > 0 && in->mouse.pos.x >= scaler.x)) {
20451 window->bounds.w = window->bounds.w + delta_x;
20452 scaler.x += in->mouse.delta.x;
20457 if (window_size.y < window->bounds.h + in->mouse.delta.y) {
20458 if ((in->mouse.delta.y < 0) || (in->mouse.delta.y > 0 && in->mouse.pos.y >= scaler.y)) {
20459 window->bounds.h = window->bounds.h + in->mouse.delta.y;
20460 scaler.y += in->mouse.delta.y;
20464 ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_RESIZE_TOP_RIGHT_DOWN_LEFT];
20465 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = scaler.x + scaler.w/2.0f;
20466 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y = scaler.y + scaler.h/2.0f;
20470 if (!nk_panel_is_sub(layout->type)) {
20473 nk_command_buffer_reset(&window->buffer);
20475 else nk_finish(ctx, window);
20483 window->flags = layout->flags;
20486 if (window->property.active && window->property.old != window->property.seq &&
20487 window->property.active == window->property.prev) {
20488 nk_zero(&window->property,
sizeof(window->property));
20490 window->property.old = window->property.seq;
20491 window->property.prev = window->property.active;
20492 window->property.seq = 0;
20495 if (window->edit.active && window->edit.old != window->edit.seq &&
20496 window->edit.active == window->edit.prev) {
20497 nk_zero(&window->edit,
sizeof(window->edit));
20499 window->edit.old = window->edit.seq;
20500 window->edit.prev = window->edit.active;
20501 window->edit.seq = 0;
20504 if (window->popup.active_con && window->popup.con_old != window->popup.con_count) {
20505 window->popup.con_count = 0;
20506 window->popup.con_old = 0;
20507 window->popup.active_con = 0;
20509 window->popup.con_old = window->popup.con_count;
20510 window->popup.con_count = 0;
20512 window->popup.combo_count = 0;
20514 NK_ASSERT(!layout->row.tree_depth);
20530 elem = nk_create_page_element(ctx);
20531 if (!elem)
return 0;
20532 elem->data.win.seq = ctx->seq;
20533 return &elem->data.win;
20539 struct nk_table *it = win->tables;
20540 if (win->popup.win) {
20541 nk_free_window(ctx, win->popup.win);
20542 win->popup.win = 0;
20550 nk_remove_table(win, it);
20551 nk_free_table(ctx, it);
20552 if (it == win->tables)
20560 nk_free_page_element(ctx, pe);}
20563nk_find_window(
const struct nk_context *ctx, nk_hash hash,
const char *name)
20568 NK_ASSERT(iter != iter->next);
20569 if (iter->name == hash) {
20570 int max_len = nk_strlen(iter->name_string);
20571 if (!nk_stricmpn(iter->name_string, name, max_len))
20580 enum nk_window_insert_location loc)
20585 if (!win || !ctx)
return;
20589 NK_ASSERT(iter != iter->next);
20590 NK_ASSERT(iter != win);
20591 if (iter == win)
return;
20603 if (loc == NK_INSERT_BACK) {
20608 win->prev = ctx->end;
20611 ctx->active = ctx->end;
20615 ctx->begin->prev = win;
20616 win->next = ctx->begin;
20626 if (win == ctx->begin || win == ctx->end) {
20627 if (win == ctx->begin) {
20628 ctx->begin = win->next;
20630 win->next->prev = 0;
20632 if (win == ctx->end) {
20633 ctx->end = win->prev;
20635 win->prev->next = 0;
20639 win->next->prev = win->prev;
20641 win->prev->next = win->next;
20643 if (win == ctx->active || !ctx->active) {
20644 ctx->active = ctx->end;
20654 struct nk_rect bounds, nk_flags flags)
20660 struct nk_rect bounds, nk_flags flags)
20671 NK_ASSERT(ctx->style.font && ctx->style.font->
width &&
"if this triggers you forgot to add a font");
20672 NK_ASSERT(!ctx->current &&
"if this triggers you missed a `nk_end` call");
20673 if (!ctx || ctx->current || !title || !name)
20677 style = &ctx->style;
20678 name_len = (int)nk_strlen(name);
20679 name_hash = nk_murmur_hash(name, (
int)name_len, NK_WINDOW_TITLE);
20680 win = nk_find_window(ctx, name_hash, name);
20683 nk_size name_length = (nk_size)name_len;
20684 win = (
struct nk_window*)nk_create_window(ctx);
20686 if (!win)
return 0;
20688 if (flags & NK_WINDOW_BACKGROUND)
20689 nk_insert_window(ctx, win, NK_INSERT_FRONT);
20690 else nk_insert_window(ctx, win, NK_INSERT_BACK);
20691 nk_command_buffer_init(&win->buffer, &ctx->memory, NK_CLIPPING_ON);
20693 win->flags = flags;
20694 win->bounds = bounds;
20695 win->name = name_hash;
20696 name_length = NK_MIN(name_length, NK_WINDOW_MAX_NAME-1);
20697 NK_MEMCPY(win->name_string, name, name_length);
20698 win->name_string[name_length] = 0;
20699 win->popup.win = 0;
20700 win->widgets_disabled = nk_false;
20705 win->flags &= ~(nk_flags)(NK_WINDOW_PRIVATE-1);
20706 win->flags |= flags;
20707 if (!(win->flags & (NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE)))
20708 win->bounds = bounds;
20716 NK_ASSERT(win->seq != ctx->seq);
20717 win->seq = ctx->seq;
20724 ctx->current = win;
20727 }
else nk_start(ctx, win);
20730 if (!(win->flags &
NK_WINDOW_HIDDEN) && !(win->flags & NK_WINDOW_NO_INPUT))
20732 int inpanel, ishovered;
20734 float h = ctx->style.font->
height + 2.0f * style->window.header.padding.y +
20735 (2.0f * style->window.header.label_padding.y);
20737 win->bounds:
nk_rect(win->bounds.x, win->bounds.y, win->bounds.w, h);
20740 inpanel = nk_input_has_mouse_click_down_in_rect(&ctx->input, NK_BUTTON_LEFT, win_bounds, nk_true);
20741 inpanel = inpanel && ctx->input.mouse.buttons[NK_BUTTON_LEFT].clicked;
20742 ishovered = nk_input_is_mouse_hovering_rect(&ctx->input, win_bounds);
20743 if ((win != ctx->active) && ishovered && !ctx->input.mouse.buttons[NK_BUTTON_LEFT].down) {
20747 iter->bounds:
nk_rect(iter->bounds.x, iter->bounds.y, iter->bounds.w, h);
20748 if (NK_INTERSECT(win_bounds.x, win_bounds.y, win_bounds.w, win_bounds.h,
20749 iter_bounds.x, iter_bounds.y, iter_bounds.w, iter_bounds.h) &&
20753 if (iter->popup.win && iter->popup.active && !(iter->flags &
NK_WINDOW_HIDDEN) &&
20754 NK_INTERSECT(win->bounds.x, win_bounds.y, win_bounds.w, win_bounds.h,
20755 iter->popup.win->bounds.x, iter->popup.win->bounds.y,
20756 iter->popup.win->bounds.w, iter->popup.win->bounds.h))
20763 if (iter && inpanel && (win != ctx->end)) {
20768 iter->bounds:
nk_rect(iter->bounds.x, iter->bounds.y, iter->bounds.w, h);
20769 if (NK_INBOX(ctx->input.mouse.pos.x, ctx->input.mouse.pos.y,
20770 iter_bounds.x, iter_bounds.y, iter_bounds.w, iter_bounds.h) &&
20773 if (iter->popup.win && iter->popup.active && !(iter->flags &
NK_WINDOW_HIDDEN) &&
20774 NK_INTERSECT(win_bounds.x, win_bounds.y, win_bounds.w, win_bounds.h,
20775 iter->popup.win->bounds.x, iter->popup.win->bounds.y,
20776 iter->popup.win->bounds.w, iter->popup.win->bounds.h))
20781 if (iter && !(win->flags &
NK_WINDOW_ROM) && (win->flags & NK_WINDOW_BACKGROUND)) {
20784 ctx->active = iter;
20785 if (!(iter->flags & NK_WINDOW_BACKGROUND)) {
20788 nk_remove_window(ctx, iter);
20789 nk_insert_window(ctx, iter, NK_INSERT_BACK);
20792 if (!iter && ctx->end != win) {
20793 if (!(win->flags & NK_WINDOW_BACKGROUND)) {
20796 nk_remove_window(ctx, win);
20797 nk_insert_window(ctx, win, NK_INSERT_BACK);
20802 if (ctx->end != win && !(win->flags & NK_WINDOW_BACKGROUND))
20806 win->layout = (
struct nk_panel*)nk_create_panel(ctx);
20807 ctx->current = win;
20808 ret = nk_panel_begin(ctx, title, NK_PANEL_WINDOW);
20809 win->layout->offset_x = &win->scrollbar.x;
20810 win->layout->offset_y = &win->scrollbar.y;
20818 NK_ASSERT(ctx->current &&
"if this triggers you forgot to call `nk_begin`");
20819 if (!ctx || !ctx->current)
20822 layout = ctx->current->layout;
20823 if (!layout || (layout->type == NK_PANEL_WINDOW && (ctx->current->flags &
NK_WINDOW_HIDDEN))) {
20828 nk_free_panel(ctx, ctx->current->layout);
20835 NK_ASSERT(ctx->current);
20836 if (!ctx || !ctx->current)
return nk_rect(0,0,0,0);
20837 return ctx->current->bounds;
20843 NK_ASSERT(ctx->current);
20844 if (!ctx || !ctx->current)
return nk_vec2(0,0);
20845 return nk_vec2(ctx->current->bounds.x, ctx->current->bounds.y);
20851 NK_ASSERT(ctx->current);
20852 if (!ctx || !ctx->current)
return nk_vec2(0,0);
20853 return nk_vec2(ctx->current->bounds.w, ctx->current->bounds.h);
20859 NK_ASSERT(ctx->current);
20860 if (!ctx || !ctx->current)
return 0;
20861 return ctx->current->bounds.w;
20867 NK_ASSERT(ctx->current);
20868 if (!ctx || !ctx->current)
return 0;
20869 return ctx->current->bounds.h;
20875 NK_ASSERT(ctx->current);
20876 if (!ctx || !ctx->current)
return nk_rect(0,0,0,0);
20877 return ctx->current->layout->clip;
20883 NK_ASSERT(ctx->current);
20884 NK_ASSERT(ctx->current->layout);
20885 if (!ctx || !ctx->current)
return nk_vec2(0,0);
20886 return nk_vec2(ctx->current->layout->clip.x, ctx->current->layout->clip.y);
20892 NK_ASSERT(ctx->current);
20893 NK_ASSERT(ctx->current->layout);
20894 if (!ctx || !ctx->current)
return nk_vec2(0,0);
20895 return nk_vec2(ctx->current->layout->clip.x + ctx->current->layout->clip.w,
20896 ctx->current->layout->clip.y + ctx->current->layout->clip.h);
20902 NK_ASSERT(ctx->current);
20903 NK_ASSERT(ctx->current->layout);
20904 if (!ctx || !ctx->current)
return nk_vec2(0,0);
20905 return nk_vec2(ctx->current->layout->clip.w, ctx->current->layout->clip.h);
20911 NK_ASSERT(ctx->current);
20912 NK_ASSERT(ctx->current->layout);
20913 if (!ctx || !ctx->current)
return 0;
20914 return &ctx->current->buffer;
20920 NK_ASSERT(ctx->current);
20921 if (!ctx || !ctx->current)
return 0;
20922 return ctx->current->layout;
20929 NK_ASSERT(ctx->current);
20930 if (!ctx || !ctx->current)
20932 win = ctx->current;
20934 *offset_x = win->scrollbar.x;
20936 *offset_y = win->scrollbar.y;
20942 NK_ASSERT(ctx->current);
20943 NK_ASSERT(ctx->current->layout);
20944 if (!ctx || !ctx->current)
return 0;
20945 return ctx->current == ctx->active;
20951 NK_ASSERT(ctx->current);
20955 struct nk_rect actual_bounds = ctx->current->bounds;
20957 actual_bounds.h = ctx->current->layout->header_height;
20959 return nk_input_is_mouse_hovering_rect(&ctx->input, actual_bounds);
20967 if (!ctx)
return 0;
20973 if (iter->popup.active && iter->popup.win && nk_input_is_mouse_hovering_rect(&ctx->input, iter->popup.win->bounds))
20977 struct nk_rect header = iter->bounds;
20978 header.h = ctx->style.font->
height + 2 * ctx->style.window.header.padding.y;
20979 if (nk_input_is_mouse_hovering_rect(&ctx->input, header))
20981 }
else if (nk_input_is_mouse_hovering_rect(&ctx->input, iter->bounds)) {
20993 int any_active = (ctx->last_widget_state & NK_WIDGET_STATE_MODIFIED);
20994 return any_hovered || any_active;
21000 nk_hash title_hash;
21003 if (!ctx)
return 0;
21005 title_len = (int)nk_strlen(name);
21006 title_hash = nk_murmur_hash(name, (
int)title_len, NK_WINDOW_TITLE);
21007 win = nk_find_window(ctx, title_hash, name);
21008 if (!win)
return 0;
21015 nk_hash title_hash;
21018 if (!ctx)
return 1;
21020 title_len = (int)nk_strlen(name);
21021 title_hash = nk_murmur_hash(name, (
int)title_len, NK_WINDOW_TITLE);
21022 win = nk_find_window(ctx, title_hash, name);
21023 if (!win)
return 1;
21030 nk_hash title_hash;
21033 if (!ctx)
return 1;
21035 title_len = (int)nk_strlen(name);
21036 title_hash = nk_murmur_hash(name, (
int)title_len, NK_WINDOW_TITLE);
21037 win = nk_find_window(ctx, title_hash, name);
21038 if (!win)
return 1;
21045 nk_hash title_hash;
21048 if (!ctx)
return 0;
21050 title_len = (int)nk_strlen(name);
21051 title_hash = nk_murmur_hash(name, (
int)title_len, NK_WINDOW_TITLE);
21052 win = nk_find_window(ctx, title_hash, name);
21053 if (!win)
return 0;
21054 return win == ctx->active;
21060 nk_hash title_hash;
21061 title_len = (int)nk_strlen(name);
21062 title_hash = nk_murmur_hash(name, (
int)title_len, NK_WINDOW_TITLE);
21063 return nk_find_window(ctx, title_hash, name);
21073 NK_ASSERT(ctx->current != win &&
"You cannot close a currently active window");
21074 if (ctx->current == win)
return;
21080 const char *name,
struct nk_rect bounds)
21087 win->bounds = bounds;
21091 const char *name,
struct nk_vec2 pos)
21095 win->bounds.x = pos.x;
21096 win->bounds.y = pos.y;
21100 const char *name,
struct nk_vec2 size)
21104 win->bounds.w = size.x;
21105 win->bounds.h = size.y;
21112 NK_ASSERT(ctx->current);
21113 if (!ctx || !ctx->current)
21115 win = ctx->current;
21116 win->scrollbar.x = offset_x;
21117 win->scrollbar.y = offset_y;
21121 enum nk_collapse_states c)
21124 nk_hash title_hash;
21129 title_len = (int)nk_strlen(name);
21130 title_hash = nk_murmur_hash(name, (
int)title_len, NK_WINDOW_TITLE);
21131 win = nk_find_window(ctx, title_hash, name);
21133 if (c == NK_MINIMIZED)
21139 enum nk_collapse_states c,
int cond)
21142 if (!ctx || !cond)
return;
21149 nk_hash title_hash;
21154 title_len = (int)nk_strlen(name);
21155 title_hash = nk_murmur_hash(name, (
int)title_len, NK_WINDOW_TITLE);
21156 win = nk_find_window(ctx, title_hash, name);
21158 if (s == NK_HIDDEN) {
21164 enum nk_show_states s,
int cond)
21167 if (!ctx || !cond)
return;
21175 nk_hash title_hash;
21180 title_len = (int)nk_strlen(name);
21181 title_hash = nk_murmur_hash(name, (
int)title_len, NK_WINDOW_TITLE);
21182 win = nk_find_window(ctx, title_hash, name);
21183 if (win && ctx->end != win) {
21184 nk_remove_window(ctx, win);
21185 nk_insert_window(ctx, win, NK_INSERT_BACK);
21195 if (!state)
return;
21196 nk_fill_rect(canvas, space, rounding && space.h > 1.5f ? space.h / 2.0f : 0, color);
21208nk_popup_begin(
struct nk_context *ctx,
enum nk_popup_type type,
21209 const char *title, nk_flags flags,
struct nk_rect rect)
21216 nk_hash title_hash;
21221 NK_ASSERT(ctx->current);
21222 NK_ASSERT(ctx->current->layout);
21223 if (!ctx || !ctx->current || !ctx->current->layout)
21226 win = ctx->current;
21227 panel = win->layout;
21228 NK_ASSERT(!((
int)panel->type & (
int)NK_PANEL_SET_POPUP) &&
"popups are not allowed to have popups");
21230 title_len = (int)nk_strlen(title);
21231 title_hash = nk_murmur_hash(title, (
int)title_len, NK_PANEL_POPUP);
21233 popup = win->popup.win;
21235 popup = (
struct nk_window*)nk_create_window(ctx);
21236 popup->parent = win;
21237 win->popup.win = popup;
21238 win->popup.active = 0;
21239 win->popup.type = NK_PANEL_POPUP;
21243 if (win->popup.name != title_hash) {
21244 if (!win->popup.active) {
21245 nk_zero(popup,
sizeof(*popup));
21246 win->popup.name = title_hash;
21247 win->popup.active = 1;
21248 win->popup.type = NK_PANEL_POPUP;
21253 ctx->current = popup;
21254 rect.x += win->layout->clip.x;
21255 rect.y += win->layout->clip.y;
21258 popup->parent = win;
21259 popup->bounds = rect;
21260 popup->seq = ctx->seq;
21261 popup->layout = (
struct nk_panel*)nk_create_panel(ctx);
21262 popup->flags = flags;
21263 popup->flags |= NK_WINDOW_BORDER;
21264 if (type == NK_POPUP_DYNAMIC)
21267 popup->buffer = win->buffer;
21268 nk_start_popup(ctx, win);
21270 nk_push_scissor(&popup->buffer, nk_null_rect);
21272 if (nk_panel_begin(ctx, title, NK_PANEL_POPUP)) {
21275 root = win->layout;
21279 root = root->parent;
21281 win->popup.active = 1;
21282 popup->layout->offset_x = &popup->scrollbar.x;
21283 popup->layout->offset_y = &popup->scrollbar.y;
21284 popup->layout->parent = win->layout;
21289 root = win->layout;
21292 root = root->parent;
21294 win->popup.buf.active = 0;
21295 win->popup.active = 0;
21297 ctx->current = win;
21298 nk_free_panel(ctx, popup->layout);
21306 enum nk_panel_type panel_type)
21311 int is_active = nk_true;
21314 NK_ASSERT(ctx->current);
21315 NK_ASSERT(ctx->current->layout);
21316 if (!ctx || !ctx->current || !ctx->current->layout)
21320 win = ctx->current;
21321 panel = win->layout;
21322 NK_ASSERT(!((
int)panel->type & (
int)NK_PANEL_SET_POPUP));
21324 popup = win->popup.win;
21327 popup = (
struct nk_window*)nk_create_window(ctx);
21328 popup->parent = win;
21329 win->popup.win = popup;
21330 win->popup.type = panel_type;
21331 nk_command_buffer_init(&popup->buffer, &ctx->memory, NK_CLIPPING_ON);
21334 int pressed, in_body, in_header;
21335#ifdef NK_BUTTON_TRIGGER_ON_RELEASE
21336 pressed = nk_input_is_mouse_released(&ctx->input, NK_BUTTON_LEFT);
21338 pressed = nk_input_is_mouse_pressed(&ctx->input, NK_BUTTON_LEFT);
21340 in_body = nk_input_is_mouse_hovering_rect(&ctx->input, body);
21341 in_header = nk_input_is_mouse_hovering_rect(&ctx->input, header);
21342 if (pressed && (!in_body || in_header))
21343 is_active = nk_false;
21345 win->popup.header = header;
21349 struct nk_panel *root = win->layout;
21352 root = root->parent;
21356 popup->bounds = body;
21357 popup->parent = win;
21358 popup->layout = (
struct nk_panel*)nk_create_panel(ctx);
21359 popup->flags = flags;
21360 popup->flags |= NK_WINDOW_BORDER;
21362 popup->seq = ctx->seq;
21363 win->popup.active = 1;
21364 NK_ASSERT(popup->layout);
21366 nk_start_popup(ctx, win);
21367 popup->buffer = win->buffer;
21368 nk_push_scissor(&popup->buffer, nk_null_rect);
21369 ctx->current = popup;
21371 nk_panel_begin(ctx, 0, panel_type);
21372 win->buffer = popup->buffer;
21373 popup->layout->parent = win->layout;
21374 popup->layout->offset_x = &popup->scrollbar.x;
21375 popup->layout->offset_y = &popup->scrollbar.y;
21379 root = win->layout;
21382 root = root->parent;
21391 if (!ctx || !ctx->current)
return;
21393 popup = ctx->current;
21394 NK_ASSERT(popup->parent);
21395 NK_ASSERT((
int)popup->layout->type & (
int)NK_PANEL_SET_POPUP);
21405 NK_ASSERT(ctx->current);
21406 NK_ASSERT(ctx->current->layout);
21407 if (!ctx || !ctx->current || !ctx->current->layout)
21410 popup = ctx->current;
21411 if (!popup->parent)
return;
21412 win = popup->parent;
21415 root = win->layout;
21418 root = root->parent;
21420 win->popup.active = 0;
21422 nk_push_scissor(&popup->buffer, nk_null_rect);
21425 win->buffer = popup->buffer;
21426 nk_finish_popup(ctx, win);
21427 ctx->current = win;
21428 nk_push_scissor(&win->buffer, win->layout->clip);
21431nk_popup_get_scroll(
const struct nk_context *ctx, nk_uint *offset_x, nk_uint *offset_y)
21436 NK_ASSERT(ctx->current);
21437 NK_ASSERT(ctx->current->layout);
21438 if (!ctx || !ctx->current || !ctx->current->layout)
21441 popup = ctx->current;
21443 *offset_x = popup->scrollbar.x;
21445 *offset_y = popup->scrollbar.y;
21448nk_popup_set_scroll(
struct nk_context *ctx, nk_uint offset_x, nk_uint offset_y)
21453 NK_ASSERT(ctx->current);
21454 NK_ASSERT(ctx->current->layout);
21455 if (!ctx || !ctx->current || !ctx->current->layout)
21458 popup = ctx->current;
21459 popup->scrollbar.x = offset_x;
21460 popup->scrollbar.y = offset_y;
21472nk_contextual_begin(
struct nk_context *ctx, nk_flags flags,
struct nk_vec2 size,
21473 struct nk_rect trigger_bounds)
21480 NK_STORAGE
const struct nk_rect null_rect = {-1,-1,0,0};
21481 int is_clicked = 0;
21486 NK_ASSERT(ctx->current);
21487 NK_ASSERT(ctx->current->layout);
21488 if (!ctx || !ctx->current || !ctx->current->layout)
21491 win = ctx->current;
21492 ++win->popup.con_count;
21493 if (ctx->current != ctx->active)
21497 popup = win->popup.win;
21498 is_open = (popup && win->popup.type == NK_PANEL_CONTEXTUAL);
21499 in = win->widgets_disabled ? 0 : &ctx->input;
21501 is_clicked = nk_input_mouse_clicked(in, NK_BUTTON_RIGHT, trigger_bounds);
21502 if (win->popup.active_con && win->popup.con_count != win->popup.active_con)
21504 if (!is_open && win->popup.active_con)
21505 win->popup.active_con = 0;
21506 if ((!is_open && !is_clicked))
21510 win->popup.active_con = win->popup.con_count;
21512 body.x = in->mouse.pos.x;
21513 body.y = in->mouse.pos.y;
21515 body.x = popup->bounds.x;
21516 body.y = popup->bounds.y;
21523 ret = nk_nonblock_begin(ctx, flags | NK_WINDOW_NO_SCROLLBAR, body,
21524 null_rect, NK_PANEL_CONTEXTUAL);
21525 if (ret) win->popup.type = NK_PANEL_CONTEXTUAL;
21527 win->popup.active_con = 0;
21528 win->popup.type = NK_PANEL_NONE;
21529 if (win->popup.win)
21530 win->popup.win->flags = 0;
21536nk_contextual_item_text(
struct nk_context *ctx,
const char *text,
int len,
21537 nk_flags alignment)
21547 NK_ASSERT(ctx->current);
21548 NK_ASSERT(ctx->current->layout);
21549 if (!ctx || !ctx->current || !ctx->current->layout)
21552 win = ctx->current;
21553 style = &ctx->style;
21554 state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding);
21555 if (!state)
return nk_false;
21558 if (nk_do_button_text(&ctx->last_widget_state, &win->buffer, bounds,
21559 text, len, alignment, NK_BUTTON_DEFAULT, &style->contextual_button, in, style->font)) {
21560 nk_contextual_close(ctx);
21566nk_contextual_item_label(
struct nk_context *ctx,
const char *label, nk_flags align)
21568 return nk_contextual_item_text(ctx, label, nk_strlen(label), align);
21572 const char *text,
int len, nk_flags align)
21582 NK_ASSERT(ctx->current);
21583 NK_ASSERT(ctx->current->layout);
21584 if (!ctx || !ctx->current || !ctx->current->layout)
21587 win = ctx->current;
21588 style = &ctx->style;
21589 state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding);
21590 if (!state)
return nk_false;
21593 if (nk_do_button_text_image(&ctx->last_widget_state, &win->buffer, bounds,
21594 img, text, len, align, NK_BUTTON_DEFAULT, &style->contextual_button, style->font, in)){
21595 nk_contextual_close(ctx);
21602 const char *label, nk_flags align)
21604 return nk_contextual_item_image_text(ctx, img, label, nk_strlen(label), align);
21607nk_contextual_item_symbol_text(
struct nk_context *ctx,
enum nk_symbol_type symbol,
21608 const char *text,
int len, nk_flags align)
21618 NK_ASSERT(ctx->current);
21619 NK_ASSERT(ctx->current->layout);
21620 if (!ctx || !ctx->current || !ctx->current->layout)
21623 win = ctx->current;
21624 style = &ctx->style;
21625 state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding);
21626 if (!state)
return nk_false;
21629 if (nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, bounds,
21630 symbol, text, len, align, NK_BUTTON_DEFAULT, &style->contextual_button, style->font, in)) {
21631 nk_contextual_close(ctx);
21637nk_contextual_item_symbol_label(
struct nk_context *ctx,
enum nk_symbol_type symbol,
21638 const char *text, nk_flags align)
21640 return nk_contextual_item_symbol_text(ctx, symbol, text, nk_strlen(text), align);
21646 NK_ASSERT(ctx->current);
21647 NK_ASSERT(ctx->current->layout);
21648 if (!ctx || !ctx->current || !ctx->current->layout)
return;
21649 nk_popup_close(ctx);
21657 NK_ASSERT(ctx->current);
21658 if (!ctx || !ctx->current)
return;
21660 popup = ctx->current;
21661 panel = popup->layout;
21662 NK_ASSERT(popup->parent);
21663 NK_ASSERT((
int)panel->type & (
int)NK_PANEL_SET_POPUP);
21670 struct nk_rect body = {0,0,0,0};
21671 if (panel->at_y < (panel->bounds.y + panel->bounds.h)) {
21672 struct nk_vec2 padding = nk_panel_get_padding(&ctx->style, panel->type);
21673 body = panel->bounds;
21674 body.y = (panel->at_y + panel->footer_height + panel->border + padding.y + panel->row.height);
21675 body.h = (panel->bounds.y + panel->bounds.h) - body.y;
21677 {
int pressed = nk_input_is_mouse_pressed(&ctx->input, NK_BUTTON_LEFT);
21678 int in_body = nk_input_is_mouse_hovering_rect(&ctx->input, body);
21679 if (pressed && in_body)
21703 NK_ASSERT(ctx->current);
21704 NK_ASSERT(ctx->current->layout);
21705 if (!ctx || !ctx->current || !ctx->current->layout)
21708 layout = ctx->current->layout;
21709 NK_ASSERT(layout->at_y == layout->bounds.y);
21728 layout->menu.x = layout->at_x;
21729 layout->menu.y = layout->at_y + layout->row.height;
21730 layout->menu.w = layout->bounds.w;
21731 layout->menu.offset.x = *layout->offset_x;
21732 layout->menu.offset.y = *layout->offset_y;
21733 *layout->offset_y = 0;
21743 NK_ASSERT(ctx->current);
21744 NK_ASSERT(ctx->current->layout);
21745 if (!ctx || !ctx->current || !ctx->current->layout)
21748 win = ctx->current;
21749 out = &win->buffer;
21750 layout = win->layout;
21754 layout->menu.h = layout->at_y - layout->menu.y;
21755 layout->menu.h += layout->row.height + ctx->style.window.spacing.y;
21757 layout->bounds.y += layout->menu.h;
21758 layout->bounds.h -= layout->menu.h;
21760 *layout->offset_x = layout->menu.offset.x;
21761 *layout->offset_y = layout->menu.offset.y;
21762 layout->at_y = layout->bounds.y - layout->row.height;
21764 layout->clip.y = layout->bounds.y;
21765 layout->clip.h = layout->bounds.h;
21766 nk_push_scissor(out, layout->clip);
21770 const char *
id,
int is_clicked,
struct nk_rect header,
struct nk_vec2 size)
21776 nk_hash hash = nk_murmur_hash(
id, (
int)nk_strlen(
id), NK_PANEL_MENU);
21779 NK_ASSERT(ctx->current);
21780 NK_ASSERT(ctx->current->layout);
21781 if (!ctx || !ctx->current || !ctx->current->layout)
21786 body.y = header.y + header.h;
21789 popup = win->popup.win;
21790 is_open = popup ? nk_true : nk_false;
21791 is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_MENU);
21792 if ((is_clicked && is_open && !is_active) || (is_open && !is_active) ||
21793 (!is_open && !is_active && !is_clicked))
return 0;
21794 if (!nk_nonblock_begin(ctx, NK_WINDOW_NO_SCROLLBAR, body, header, NK_PANEL_MENU))
21797 win->popup.type = NK_PANEL_MENU;
21798 win->popup.name = hash;
21802nk_menu_begin_text(
struct nk_context *ctx,
const char *title,
int len,
21803 nk_flags align,
struct nk_vec2 size)
21808 int is_clicked = nk_false;
21812 NK_ASSERT(ctx->current);
21813 NK_ASSERT(ctx->current->layout);
21814 if (!ctx || !ctx->current || !ctx->current->layout)
21817 win = ctx->current;
21818 state = nk_widget(&header, ctx);
21819 if (!state)
return 0;
21821 if (nk_do_button_text(&ctx->last_widget_state, &win->buffer, header,
21822 title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in, ctx->style.font))
21823 is_clicked = nk_true;
21824 return nk_menu_begin(ctx, win, title, is_clicked, header, size);
21826NK_API nk_bool nk_menu_begin_label(
struct nk_context *ctx,
21827 const char *text, nk_flags align,
struct nk_vec2 size)
21829 return nk_menu_begin_text(ctx, text, nk_strlen(text), align, size);
21838 int is_clicked = nk_false;
21842 NK_ASSERT(ctx->current);
21843 NK_ASSERT(ctx->current->layout);
21844 if (!ctx || !ctx->current || !ctx->current->layout)
21847 win = ctx->current;
21848 state = nk_widget(&header, ctx);
21849 if (!state)
return 0;
21851 if (nk_do_button_image(&ctx->last_widget_state, &win->buffer, header,
21852 img, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in))
21853 is_clicked = nk_true;
21854 return nk_menu_begin(ctx, win,
id, is_clicked, header, size);
21857nk_menu_begin_symbol(
struct nk_context *ctx,
const char *
id,
21858 enum nk_symbol_type sym,
struct nk_vec2 size)
21863 int is_clicked = nk_false;
21867 NK_ASSERT(ctx->current);
21868 NK_ASSERT(ctx->current->layout);
21869 if (!ctx || !ctx->current || !ctx->current->layout)
21872 win = ctx->current;
21873 state = nk_widget(&header, ctx);
21874 if (!state)
return 0;
21876 if (nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, header,
21877 sym, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in, ctx->style.font))
21878 is_clicked = nk_true;
21879 return nk_menu_begin(ctx, win,
id, is_clicked, header, size);
21882nk_menu_begin_image_text(
struct nk_context *ctx,
const char *title,
int len,
21888 int is_clicked = nk_false;
21892 NK_ASSERT(ctx->current);
21893 NK_ASSERT(ctx->current->layout);
21894 if (!ctx || !ctx->current || !ctx->current->layout)
21897 win = ctx->current;
21898 state = nk_widget(&header, ctx);
21899 if (!state)
return 0;
21901 if (nk_do_button_text_image(&ctx->last_widget_state, &win->buffer,
21902 header, img, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button,
21903 ctx->style.font, in))
21904 is_clicked = nk_true;
21905 return nk_menu_begin(ctx, win, title, is_clicked, header, size);
21908nk_menu_begin_image_label(
struct nk_context *ctx,
21909 const char *title, nk_flags align,
struct nk_image img,
struct nk_vec2 size)
21911 return nk_menu_begin_image_text(ctx, title, nk_strlen(title), align, img, size);
21914nk_menu_begin_symbol_text(
struct nk_context *ctx,
const char *title,
int len,
21915 nk_flags align,
enum nk_symbol_type sym,
struct nk_vec2 size)
21920 int is_clicked = nk_false;
21924 NK_ASSERT(ctx->current);
21925 NK_ASSERT(ctx->current->layout);
21926 if (!ctx || !ctx->current || !ctx->current->layout)
21929 win = ctx->current;
21930 state = nk_widget(&header, ctx);
21931 if (!state)
return 0;
21934 if (nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer,
21935 header, sym, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button,
21936 ctx->style.font, in)) is_clicked = nk_true;
21937 return nk_menu_begin(ctx, win, title, is_clicked, header, size);
21940nk_menu_begin_symbol_label(
struct nk_context *ctx,
21941 const char *title, nk_flags align,
enum nk_symbol_type sym,
struct nk_vec2 size )
21943 return nk_menu_begin_symbol_text(ctx, title, nk_strlen(title), align,sym,size);
21946nk_menu_item_text(
struct nk_context *ctx,
const char *title,
int len, nk_flags align)
21948 return nk_contextual_item_text(ctx, title, len, align);
21951nk_menu_item_label(
struct nk_context *ctx,
const char *label, nk_flags align)
21953 return nk_contextual_item_label(ctx, label, align);
21957 const char *label, nk_flags align)
21959 return nk_contextual_item_image_label(ctx, img, label, align);
21963 const char *text,
int len, nk_flags align)
21965 return nk_contextual_item_image_text(ctx, img, text, len, align);
21967NK_API nk_bool nk_menu_item_symbol_text(
struct nk_context *ctx,
enum nk_symbol_type sym,
21968 const char *text,
int len, nk_flags align)
21970 return nk_contextual_item_symbol_text(ctx, sym, text, len, align);
21972NK_API nk_bool nk_menu_item_symbol_label(
struct nk_context *ctx,
enum nk_symbol_type sym,
21973 const char *label, nk_flags align)
21975 return nk_contextual_item_symbol_label(ctx, sym, label, align);
21977NK_API
void nk_menu_close(
struct nk_context *ctx)
21979 nk_contextual_close(ctx);
21984 nk_contextual_end(ctx);
22003 NK_ASSERT(ctx->current);
22004 NK_ASSERT(ctx->current->layout);
22005 if (!ctx || !ctx->current || !ctx->current->layout)
22008 win = ctx->current;
22009 layout = win->layout;
22010 layout->row.min_height = height;
22019 NK_ASSERT(ctx->current);
22020 NK_ASSERT(ctx->current->layout);
22021 if (!ctx || !ctx->current || !ctx->current->layout)
22024 win = ctx->current;
22025 layout = win->layout;
22026 layout->row.min_height = ctx->style.font->
height;
22027 layout->row.min_height += ctx->style.text.padding.y*2;
22028 layout->row.min_height += ctx->style.window.min_row_height_padding*2;
22031nk_layout_row_calculate_usable_space(
const struct nk_style *style,
enum nk_panel_type type,
22032 float total_space,
int columns)
22034 float panel_spacing;
22041 spacing = style->window.spacing;
22044 panel_spacing = (float)NK_MAX(columns - 1, 0) * spacing.x;
22045 panel_space = total_space - panel_spacing;
22046 return panel_space;
22050 float height,
int cols)
22060 NK_ASSERT(ctx->current);
22061 NK_ASSERT(ctx->current->layout);
22062 if (!ctx || !ctx->current || !ctx->current->layout)
22066 layout = win->layout;
22067 style = &ctx->style;
22068 out = &win->buffer;
22069 color = style->window.background;
22070 item_spacing = style->window.spacing;
22082 layout->row.index = 0;
22083 layout->at_y += layout->row.height;
22084 layout->row.columns = cols;
22085 if (height == 0.0f)
22086 layout->row.height = NK_MAX(height, layout->row.min_height) + item_spacing.y;
22087 else layout->row.height = height + item_spacing.y;
22089 layout->row.item_offset = 0;
22093 background.x = win->bounds.x;
22094 background.w = win->bounds.w;
22095 background.y = layout->at_y - 1.0f;
22096 background.h = layout->row.height + 1.0f;
22102 float height,
int cols,
int width)
22107 NK_ASSERT(ctx->current);
22108 NK_ASSERT(ctx->current->layout);
22109 if (!ctx || !ctx->current || !ctx->current->layout)
22112 win = ctx->current;
22113 nk_panel_layout(ctx, win, height, cols);
22114 if (fmt == NK_DYNAMIC)
22115 win->layout->row.type = NK_LAYOUT_DYNAMIC_FIXED;
22116 else win->layout->row.type = NK_LAYOUT_STATIC_FIXED;
22118 win->layout->row.ratio = 0;
22119 win->layout->row.filled = 0;
22120 win->layout->row.item_offset = 0;
22121 win->layout->row.item_width = (float)width;
22128 NK_ASSERT(pixel_width);
22129 if (!ctx || !ctx->current || !ctx->current->layout)
return 0;
22130 win = ctx->current;
22131 return NK_CLAMP(0.0f, pixel_width/win->bounds.x, 1.0f);
22145 float row_height,
int cols)
22151 NK_ASSERT(ctx->current);
22152 NK_ASSERT(ctx->current->layout);
22153 if (!ctx || !ctx->current || !ctx->current->layout)
22156 win = ctx->current;
22157 layout = win->layout;
22158 nk_panel_layout(ctx, win, row_height, cols);
22159 if (fmt == NK_DYNAMIC)
22160 layout->row.type = NK_LAYOUT_DYNAMIC_ROW;
22161 else layout->row.type = NK_LAYOUT_STATIC_ROW;
22163 layout->row.ratio = 0;
22164 layout->row.filled = 0;
22165 layout->row.item_width = 0;
22166 layout->row.item_offset = 0;
22167 layout->row.columns = cols;
22176 NK_ASSERT(ctx->current);
22177 NK_ASSERT(ctx->current->layout);
22178 if (!ctx || !ctx->current || !ctx->current->layout)
22181 win = ctx->current;
22182 layout = win->layout;
22183 NK_ASSERT(layout->row.type == NK_LAYOUT_STATIC_ROW || layout->row.type == NK_LAYOUT_DYNAMIC_ROW);
22184 if (layout->row.type != NK_LAYOUT_STATIC_ROW && layout->row.type != NK_LAYOUT_DYNAMIC_ROW)
22187 if (layout->row.type == NK_LAYOUT_DYNAMIC_ROW) {
22188 float ratio = ratio_or_width;
22189 if ((ratio + layout->row.filled) > 1.0f)
return;
22191 layout->row.item_width = NK_SATURATE(ratio);
22192 else layout->row.item_width = 1.0f - layout->row.filled;
22193 }
else layout->row.item_width = ratio_or_width;
22202 NK_ASSERT(ctx->current);
22203 NK_ASSERT(ctx->current->layout);
22204 if (!ctx || !ctx->current || !ctx->current->layout)
22207 win = ctx->current;
22208 layout = win->layout;
22209 NK_ASSERT(layout->row.type == NK_LAYOUT_STATIC_ROW || layout->row.type == NK_LAYOUT_DYNAMIC_ROW);
22210 if (layout->row.type != NK_LAYOUT_STATIC_ROW && layout->row.type != NK_LAYOUT_DYNAMIC_ROW)
22212 layout->row.item_width = 0;
22213 layout->row.item_offset = 0;
22217 float height,
int cols,
const float *ratio)
22225 NK_ASSERT(ctx->current);
22226 NK_ASSERT(ctx->current->layout);
22227 if (!ctx || !ctx->current || !ctx->current->layout)
22230 win = ctx->current;
22231 layout = win->layout;
22232 nk_panel_layout(ctx, win, height, cols);
22233 if (fmt == NK_DYNAMIC) {
22236 layout->row.ratio = ratio;
22237 for (i = 0; i < cols; ++i) {
22238 if (ratio[i] < 0.0f)
22240 else r += ratio[i];
22242 r = NK_SATURATE(1.0f - r);
22243 layout->row.type = NK_LAYOUT_DYNAMIC;
22244 layout->row.item_width = (r > 0 && n_undef > 0) ? (r / (
float)n_undef):0;
22246 layout->row.ratio = ratio;
22247 layout->row.type = NK_LAYOUT_STATIC;
22248 layout->row.item_width = 0;
22249 layout->row.item_offset = 0;
22251 layout->row.item_offset = 0;
22252 layout->row.filled = 0;
22261 NK_ASSERT(ctx->current);
22262 NK_ASSERT(ctx->current->layout);
22263 if (!ctx || !ctx->current || !ctx->current->layout)
22266 win = ctx->current;
22267 layout = win->layout;
22268 nk_panel_layout(ctx, win, height, 1);
22269 layout->row.type = NK_LAYOUT_TEMPLATE;
22270 layout->row.columns = 0;
22271 layout->row.ratio = 0;
22272 layout->row.item_width = 0;
22273 layout->row.item_height = 0;
22274 layout->row.item_offset = 0;
22275 layout->row.filled = 0;
22276 layout->row.item.x = 0;
22277 layout->row.item.y = 0;
22278 layout->row.item.w = 0;
22279 layout->row.item.h = 0;
22288 NK_ASSERT(ctx->current);
22289 NK_ASSERT(ctx->current->layout);
22290 if (!ctx || !ctx->current || !ctx->current->layout)
22293 win = ctx->current;
22294 layout = win->layout;
22295 NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
22296 NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
22297 if (layout->row.type != NK_LAYOUT_TEMPLATE)
return;
22298 if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS)
return;
22299 layout->row.templates[layout->row.columns++] = -1.0f;
22308 NK_ASSERT(ctx->current);
22309 NK_ASSERT(ctx->current->layout);
22310 if (!ctx || !ctx->current || !ctx->current->layout)
22313 win = ctx->current;
22314 layout = win->layout;
22315 NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
22316 NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
22317 if (layout->row.type != NK_LAYOUT_TEMPLATE)
return;
22318 if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS)
return;
22319 layout->row.templates[layout->row.columns++] = -min_width;
22328 NK_ASSERT(ctx->current);
22329 NK_ASSERT(ctx->current->layout);
22330 if (!ctx || !ctx->current || !ctx->current->layout)
22333 win = ctx->current;
22334 layout = win->layout;
22335 NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
22336 NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
22337 if (layout->row.type != NK_LAYOUT_TEMPLATE)
return;
22338 if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS)
return;
22339 layout->row.templates[layout->row.columns++] = width;
22348 int variable_count = 0;
22349 int min_variable_count = 0;
22350 float min_fixed_width = 0.0f;
22351 float total_fixed_width = 0.0f;
22352 float max_variable_width = 0.0f;
22355 NK_ASSERT(ctx->current);
22356 NK_ASSERT(ctx->current->layout);
22357 if (!ctx || !ctx->current || !ctx->current->layout)
22360 win = ctx->current;
22361 layout = win->layout;
22362 NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
22363 if (layout->row.type != NK_LAYOUT_TEMPLATE)
return;
22364 for (i = 0; i < layout->row.columns; ++i) {
22365 float width = layout->row.templates[i];
22366 if (width >= 0.0f) {
22367 total_fixed_width += width;
22368 min_fixed_width += width;
22369 }
else if (width < -1.0f) {
22371 total_fixed_width += width;
22372 max_variable_width = NK_MAX(max_variable_width, width);
22375 min_variable_count++;
22379 if (variable_count) {
22380 float space = nk_layout_row_calculate_usable_space(&ctx->style, layout->type,
22381 layout->bounds.w, layout->row.columns);
22382 float var_width = (NK_MAX(space-min_fixed_width,0.0f)) / (
float)variable_count;
22383 int enough_space = var_width >= max_variable_width;
22385 var_width = (NK_MAX(space-total_fixed_width,0)) / (
float)min_variable_count;
22386 for (i = 0; i < layout->row.columns; ++i) {
22387 float *width = &layout->row.templates[i];
22388 *width = (*width >= 0.0f)? *width: (*width < -1.0f && !enough_space)? -(*width): var_width;
22394 float height,
int widget_count)
22400 NK_ASSERT(ctx->current);
22401 NK_ASSERT(ctx->current->layout);
22402 if (!ctx || !ctx->current || !ctx->current->layout)
22405 win = ctx->current;
22406 layout = win->layout;
22407 nk_panel_layout(ctx, win, height, widget_count);
22408 if (fmt == NK_STATIC)
22409 layout->row.type = NK_LAYOUT_STATIC_FREE;
22410 else layout->row.type = NK_LAYOUT_DYNAMIC_FREE;
22412 layout->row.ratio = 0;
22413 layout->row.filled = 0;
22414 layout->row.item_width = 0;
22415 layout->row.item_offset = 0;
22424 NK_ASSERT(ctx->current);
22425 NK_ASSERT(ctx->current->layout);
22426 if (!ctx || !ctx->current || !ctx->current->layout)
22429 win = ctx->current;
22430 layout = win->layout;
22431 layout->row.item_width = 0;
22432 layout->row.item_height = 0;
22433 layout->row.item_offset = 0;
22434 nk_zero(&layout->row.item,
sizeof(layout->row.item));
22443 NK_ASSERT(ctx->current);
22444 NK_ASSERT(ctx->current->layout);
22445 if (!ctx || !ctx->current || !ctx->current->layout)
22448 win = ctx->current;
22449 layout = win->layout;
22450 layout->row.item = rect;
22460 NK_ASSERT(ctx->current);
22461 NK_ASSERT(ctx->current->layout);
22462 win = ctx->current;
22463 layout = win->layout;
22465 ret.x = layout->clip.x;
22466 ret.y = layout->clip.y;
22467 ret.w = layout->clip.w;
22468 ret.h = layout->row.height;
22479 NK_ASSERT(ctx->current);
22480 NK_ASSERT(ctx->current->layout);
22481 win = ctx->current;
22482 layout = win->layout;
22484 ret.x = layout->at_x;
22485 ret.y = layout->at_y;
22486 ret.w = layout->bounds.w - NK_MAX(layout->at_x - layout->bounds.x,0);
22487 ret.h = layout->row.height;
22497 NK_ASSERT(ctx->current);
22498 NK_ASSERT(ctx->current->layout);
22499 win = ctx->current;
22500 layout = win->layout;
22502 ret.x += layout->at_x - (float)*layout->offset_x;
22503 ret.y += layout->at_y - (float)*layout->offset_y;
22513 NK_ASSERT(ctx->current);
22514 NK_ASSERT(ctx->current->layout);
22515 win = ctx->current;
22516 layout = win->layout;
22518 ret.x += -layout->at_x + (float)*layout->offset_x;
22519 ret.y += -layout->at_y + (float)*layout->offset_y;
22529 NK_ASSERT(ctx->current);
22530 NK_ASSERT(ctx->current->layout);
22531 win = ctx->current;
22532 layout = win->layout;
22534 ret.x += layout->at_x - (float)*layout->offset_x;
22535 ret.y += layout->at_y - (float)*layout->offset_y;
22545 NK_ASSERT(ctx->current);
22546 NK_ASSERT(ctx->current->layout);
22547 win = ctx->current;
22548 layout = win->layout;
22550 ret.x += -layout->at_x + (float)*layout->offset_x;
22551 ret.y += -layout->at_y + (float)*layout->offset_y;
22557 struct nk_panel *layout = win->layout;
22558 struct nk_vec2 spacing = ctx->style.window.spacing;
22559 const float row_height = layout->row.height - spacing.y;
22560 nk_panel_layout(ctx, win, row_height, layout->row.columns);
22571 float item_offset = 0;
22572 float item_width = 0;
22573 float item_spacing = 0;
22574 float panel_space = 0;
22577 NK_ASSERT(ctx->current);
22578 NK_ASSERT(ctx->current->layout);
22579 if (!ctx || !ctx->current || !ctx->current->layout)
22582 win = ctx->current;
22583 layout = win->layout;
22584 style = &ctx->style;
22587 spacing = style->window.spacing;
22588 panel_space = nk_layout_row_calculate_usable_space(&ctx->style, layout->type,
22589 layout->bounds.w, layout->row.columns);
22591 #define NK_FRAC(x) (x - (float)(int)nk_roundf(x))
22593 switch (layout->row.type) {
22594 case NK_LAYOUT_DYNAMIC_FIXED: {
22596 float w = NK_MAX(1.0f,panel_space) / (float)layout->row.columns;
22597 item_offset = (float)layout->row.index * w;
22598 item_width = w + NK_FRAC(item_offset);
22599 item_spacing = (float)layout->row.index * spacing.x;
22601 case NK_LAYOUT_DYNAMIC_ROW: {
22603 float w = layout->row.item_width * panel_space;
22604 item_offset = layout->row.item_offset;
22605 item_width = w + NK_FRAC(item_offset);
22609 layout->row.item_offset += w + spacing.x;
22610 layout->row.filled += layout->row.item_width;
22611 layout->row.index = 0;
22614 case NK_LAYOUT_DYNAMIC_FREE: {
22616 bounds->x = layout->at_x + (layout->bounds.w * layout->row.item.x);
22617 bounds->x -= (float)*layout->offset_x;
22618 bounds->y = layout->at_y + (layout->row.height * layout->row.item.y);
22619 bounds->y -= (float)*layout->offset_y;
22620 bounds->w = layout->bounds.w * layout->row.item.w + NK_FRAC(bounds->x);
22621 bounds->h = layout->row.height * layout->row.item.h + NK_FRAC(bounds->y);
22624 case NK_LAYOUT_DYNAMIC: {
22627 NK_ASSERT(layout->row.ratio);
22628 ratio = (layout->row.ratio[layout->row.index] < 0) ?
22629 layout->row.item_width : layout->row.ratio[layout->row.index];
22631 w = (ratio * panel_space);
22632 item_spacing = (float)layout->row.index * spacing.x;
22633 item_offset = layout->row.item_offset;
22634 item_width = w + NK_FRAC(item_offset);
22637 layout->row.item_offset += w;
22638 layout->row.filled += ratio;
22641 case NK_LAYOUT_STATIC_FIXED: {
22643 item_width = layout->row.item_width;
22644 item_offset = (float)layout->row.index * item_width;
22645 item_spacing = (float)layout->row.index * spacing.x;
22647 case NK_LAYOUT_STATIC_ROW: {
22649 item_width = layout->row.item_width;
22650 item_offset = layout->row.item_offset;
22651 item_spacing = (float)layout->row.index * spacing.x;
22652 if (modify) layout->row.item_offset += item_width;
22654 case NK_LAYOUT_STATIC_FREE: {
22656 bounds->x = layout->at_x + layout->row.item.x;
22657 bounds->w = layout->row.item.w;
22658 if (((bounds->x + bounds->w) > layout->max_x) && modify)
22659 layout->max_x = (bounds->x + bounds->w);
22660 bounds->x -= (float)*layout->offset_x;
22661 bounds->y = layout->at_y + layout->row.item.y;
22662 bounds->y -= (float)*layout->offset_y;
22663 bounds->h = layout->row.item.h;
22666 case NK_LAYOUT_STATIC: {
22668 item_spacing = (float)layout->row.index * spacing.x;
22669 item_width = layout->row.ratio[layout->row.index];
22670 item_offset = layout->row.item_offset;
22671 if (modify) layout->row.item_offset += item_width;
22673 case NK_LAYOUT_TEMPLATE: {
22676 NK_ASSERT(layout->row.index < layout->row.columns);
22677 NK_ASSERT(layout->row.index < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
22678 w = layout->row.templates[layout->row.index];
22679 item_offset = layout->row.item_offset;
22680 item_width = w + NK_FRAC(item_offset);
22681 item_spacing = (float)layout->row.index * spacing.x;
22682 if (modify) layout->row.item_offset += w;
22685 default: NK_ASSERT(0);
break;
22689 bounds->w = item_width;
22690 bounds->h = layout->row.height - spacing.y;
22691 bounds->y = layout->at_y - (float)*layout->offset_y;
22692 bounds->x = layout->at_x + item_offset + item_spacing;
22693 if (((bounds->x + bounds->w) > layout->max_x) && modify)
22694 layout->max_x = bounds->x + bounds->w;
22695 bounds->x -= (float)*layout->offset_x;
22704 NK_ASSERT(ctx->current);
22705 NK_ASSERT(ctx->current->layout);
22706 if (!ctx || !ctx->current || !ctx->current->layout)
22710 win = ctx->current;
22711 layout = win->layout;
22712 if (layout->row.index >= layout->row.columns)
22713 nk_panel_alloc_row(ctx, win);
22716 nk_layout_widget_space(bounds, ctx, win, nk_true);
22717 layout->row.index++;
22728 NK_ASSERT(ctx->current);
22729 NK_ASSERT(ctx->current->layout);
22730 if (!ctx || !ctx->current || !ctx->current->layout) {
22735 win = ctx->current;
22736 layout = win->layout;
22738 index = layout->row.index;
22739 if (layout->row.index >= layout->row.columns) {
22740 layout->at_y += layout->row.height;
22741 layout->row.index = 0;
22743 nk_layout_widget_space(bounds, ctx, win, nk_false);
22744 if (!layout->row.index) {
22745 bounds->x -= layout->row.item_offset;
22748 layout->row.index = index;
22753 struct nk_rect dummy_rect = { 0, 0, 0, 0 };
22754 nk_panel_alloc_space( &dummy_rect, ctx );
22766nk_tree_state_base(
struct nk_context *ctx,
enum nk_tree_type type,
22767 struct nk_image *img,
const char *title,
enum nk_collapse_states *state)
22775 enum nk_symbol_type symbol;
22779 struct nk_rect header = {0,0,0,0};
22780 struct nk_rect sym = {0,0,0,0};
22781 struct nk_text text;
22787 NK_ASSERT(ctx->current);
22788 NK_ASSERT(ctx->current->layout);
22789 if (!ctx || !ctx->current || !ctx->current->layout)
22793 win = ctx->current;
22794 layout = win->layout;
22795 out = &win->buffer;
22796 style = &ctx->style;
22797 item_spacing = style->window.spacing;
22800 row_height = style->font->
height + 2 * style->tab.padding.y;
22805 widget_state = nk_widget(&header, ctx);
22806 if (type == NK_TREE_TAB) {
22807 const struct nk_style_item *background = &style->tab.background;
22809 switch(background->type) {
22810 case NK_STYLE_ITEM_IMAGE:
22811 nk_draw_image(out, header, &background->data.image, nk_rgb_factor(nk_white, style->tab.color_factor));
22813 case NK_STYLE_ITEM_NINE_SLICE:
22814 nk_draw_nine_slice(out, header, &background->data.slice, nk_rgb_factor(nk_white, style->tab.color_factor));
22816 case NK_STYLE_ITEM_COLOR:
22817 nk_fill_rect(out, header, 0, nk_rgb_factor(style->tab.border_color, style->tab.color_factor));
22818 nk_fill_rect(out, nk_shrink_rect(header, style->tab.border),
22819 style->tab.rounding, nk_rgb_factor(background->data.color, style->tab.color_factor));
22822 }
else text.background = style->window.background;
22827 if (nk_button_behavior(&ws, header, in, NK_BUTTON_DEFAULT))
22828 *state = (*state == NK_MAXIMIZED) ? NK_MINIMIZED : NK_MAXIMIZED;
22831 if (*state == NK_MAXIMIZED) {
22832 symbol = style->tab.sym_maximize;
22833 if (type == NK_TREE_TAB)
22834 button = &style->tab.tab_maximize_button;
22835 else button = &style->tab.node_maximize_button;
22837 symbol = style->tab.sym_minimize;
22838 if (type == NK_TREE_TAB)
22839 button = &style->tab.tab_minimize_button;
22840 else button = &style->tab.node_minimize_button;
22844 sym.w = sym.h = style->font->
height;
22845 sym.y = header.y + style->tab.padding.y;
22846 sym.x = header.x + style->tab.padding.x;
22847 nk_do_button_symbol(&ws, &win->buffer, sym, symbol, NK_BUTTON_DEFAULT,
22848 button, 0, style->font);
22852 sym.x = sym.x + sym.w + 4 * item_spacing.x;
22854 sym.w = style->font->
height + style->tab.spacing.x;}
22859 header.w = NK_MAX(header.w, sym.w + item_spacing.x);
22860 label.x = sym.x + sym.w + item_spacing.x;
22862 label.w = header.w - (sym.w + item_spacing.y + style->tab.indent);
22863 label.h = style->font->
height;
22864 text.text = nk_rgb_factor(style->tab.text, style->tab.color_factor);
22866 nk_widget_text(out, label, title, nk_strlen(title), &text,
22867 NK_TEXT_LEFT, style->font);}
22870 if (*state == NK_MAXIMIZED) {
22871 layout->at_x = header.x + (float)*layout->offset_x + style->tab.indent;
22872 layout->bounds.w = NK_MAX(layout->bounds.w, style->tab.indent);
22873 layout->bounds.w -= (style->tab.indent + style->window.padding.x);
22874 layout->row.tree_depth++;
22876 }
else return nk_false;
22879nk_tree_base(
struct nk_context *ctx,
enum nk_tree_type type,
22880 struct nk_image *img,
const char *title,
enum nk_collapse_states initial_state,
22881 const char *hash,
int len,
int line)
22885 nk_hash tree_hash = 0;
22886 nk_uint *state = 0;
22890 title_len = (int)nk_strlen(title);
22891 tree_hash = nk_murmur_hash(title, (
int)title_len, (nk_hash)line);
22892 }
else tree_hash = nk_murmur_hash(hash, len, (nk_hash)line);
22893 state = nk_find_value(win, tree_hash);
22895 state = nk_add_value(ctx, win, tree_hash, 0);
22896 *state = initial_state;
22898 return nk_tree_state_base(ctx, type, img, title, (
enum nk_collapse_states*)state);
22902 const char *title,
enum nk_collapse_states *state)
22904 return nk_tree_state_base(ctx, type, 0, title, state);
22908 struct nk_image img,
const char *title,
enum nk_collapse_states *state)
22910 return nk_tree_state_base(ctx, type, &img, title, state);
22919 NK_ASSERT(ctx->current);
22920 NK_ASSERT(ctx->current->layout);
22921 if (!ctx || !ctx->current || !ctx->current->layout)
22924 win = ctx->current;
22925 layout = win->layout;
22926 layout->at_x -= ctx->style.tab.indent + (float)*layout->offset_x;
22927 layout->bounds.w += ctx->style.tab.indent + ctx->style.window.padding.x;
22928 NK_ASSERT(layout->row.tree_depth);
22929 layout->row.tree_depth--;
22933 const char *title,
enum nk_collapse_states initial_state,
22934 const char *hash,
int len,
int line)
22936 return nk_tree_base(ctx, type, 0, title, initial_state, hash, len, line);
22940 struct nk_image img,
const char *title,
enum nk_collapse_states initial_state,
22941 const char *hash,
int len,
int seed)
22943 return nk_tree_base(ctx, type, &img, title, initial_state, hash, len, seed);
22951nk_tree_element_image_push_hashed_base(
struct nk_context *ctx,
enum nk_tree_type type,
22952 struct nk_image *img,
const char *title,
int title_len,
22953 enum nk_collapse_states *state, nk_bool *selected)
22961 enum nk_symbol_type symbol;
22969 struct nk_rect header = {0,0,0,0};
22970 struct nk_rect sym = {0,0,0,0};
22976 NK_ASSERT(ctx->current);
22977 NK_ASSERT(ctx->current->layout);
22978 if (!ctx || !ctx->current || !ctx->current->layout)
22982 win = ctx->current;
22983 layout = win->layout;
22984 out = &win->buffer;
22985 style = &ctx->style;
22986 item_spacing = style->window.spacing;
22987 padding = style->selectable.padding;
22990 row_height = style->font->
height + 2 * style->tab.padding.y;
22995 widget_state = nk_widget(&header, ctx);
22996 if (type == NK_TREE_TAB) {
22997 const struct nk_style_item *background = &style->tab.background;
22999 switch (background->type) {
23000 case NK_STYLE_ITEM_IMAGE:
23001 nk_draw_image(out, header, &background->data.image, nk_rgb_factor(nk_white, style->tab.color_factor));
23003 case NK_STYLE_ITEM_NINE_SLICE:
23004 nk_draw_nine_slice(out, header, &background->data.slice, nk_rgb_factor(nk_white, style->tab.color_factor));
23006 case NK_STYLE_ITEM_COLOR:
23007 nk_fill_rect(out, header, 0, nk_rgb_factor(style->tab.border_color, style->tab.color_factor));
23008 nk_fill_rect(out, nk_shrink_rect(header, style->tab.border),
23009 style->tab.rounding, nk_rgb_factor(background->data.color, style->tab.color_factor));
23019 if (*state == NK_MAXIMIZED) {
23020 symbol = style->tab.sym_maximize;
23021 if (type == NK_TREE_TAB)
23022 button = &style->tab.tab_maximize_button;
23023 else button = &style->tab.node_maximize_button;
23025 symbol = style->tab.sym_minimize;
23026 if (type == NK_TREE_TAB)
23027 button = &style->tab.tab_minimize_button;
23028 else button = &style->tab.node_minimize_button;
23031 sym.w = sym.h = style->font->
height;
23032 sym.y = header.y + style->tab.padding.y;
23033 sym.x = header.x + style->tab.padding.x;
23034 if (nk_do_button_symbol(&ws, &win->buffer, sym, symbol, NK_BUTTON_DEFAULT, button, in, style->font))
23035 *state = (*state == NK_MAXIMIZED) ? NK_MINIMIZED : NK_MAXIMIZED;}
23038 {nk_flags dummy = 0;
23041 text_len = nk_strlen(title);
23042 text_width = style->font->
width(style->font->userdata, style->font->
height, title, text_len);
23043 text_width += (4 * padding.x);
23045 header.w = NK_MAX(header.w, sym.w + item_spacing.x);
23046 label.x = sym.x + sym.w + item_spacing.x;
23048 label.w = NK_MIN(header.w - (sym.w + item_spacing.y + style->tab.indent), text_width);
23049 label.h = style->font->
height;
23052 nk_do_selectable_image(&dummy, &win->buffer, label, title, title_len, NK_TEXT_LEFT,
23053 selected, img, &style->selectable, in, style->font);
23054 }
else nk_do_selectable(&dummy, &win->buffer, label, title, title_len, NK_TEXT_LEFT,
23055 selected, &style->selectable, in, style->font);
23058 if (*state == NK_MAXIMIZED) {
23059 layout->at_x = header.x + (float)*layout->offset_x + style->tab.indent;
23060 layout->bounds.w = NK_MAX(layout->bounds.w, style->tab.indent);
23061 layout->bounds.w -= (style->tab.indent + style->window.padding.x);
23062 layout->row.tree_depth++;
23064 }
else return nk_false;
23067nk_tree_element_base(
struct nk_context *ctx,
enum nk_tree_type type,
23068 struct nk_image *img,
const char *title,
enum nk_collapse_states initial_state,
23069 nk_bool *selected,
const char *hash,
int len,
int line)
23073 nk_hash tree_hash = 0;
23074 nk_uint *state = 0;
23078 title_len = (int)nk_strlen(title);
23079 tree_hash = nk_murmur_hash(title, (
int)title_len, (nk_hash)line);
23080 }
else tree_hash = nk_murmur_hash(hash, len, (nk_hash)line);
23081 state = nk_find_value(win, tree_hash);
23083 state = nk_add_value(ctx, win, tree_hash, 0);
23084 *state = initial_state;
23085 }
return nk_tree_element_image_push_hashed_base(ctx, type, img, title,
23086 nk_strlen(title), (
enum nk_collapse_states*)state, selected);
23089nk_tree_element_push_hashed(
struct nk_context *ctx,
enum nk_tree_type type,
23090 const char *title,
enum nk_collapse_states initial_state,
23091 nk_bool *selected,
const char *hash,
int len,
int seed)
23093 return nk_tree_element_base(ctx, type, 0, title, initial_state, selected, hash, len, seed);
23096nk_tree_element_image_push_hashed(
struct nk_context *ctx,
enum nk_tree_type type,
23097 struct nk_image img,
const char *title,
enum nk_collapse_states initial_state,
23098 nk_bool *selected,
const char *hash,
int len,
int seed)
23100 return nk_tree_element_base(ctx, type, &img, title, initial_state, selected, hash, len, seed);
23119 nk_uint *x_offset, nk_uint *y_offset,
const char *title, nk_flags flags)
23125 win = ctx->current;
23126 nk_panel_alloc_space(&bounds, ctx);
23127 {
const struct nk_rect *c = &win->layout->clip;
23128 if (!NK_INTERSECT(c->x, c->y, c->w, c->h, bounds.x, bounds.y, bounds.w, bounds.h) &&
23129 !(flags & NK_WINDOW_MOVABLE)) {
23136 nk_zero(&panel,
sizeof(panel));
23137 panel.bounds = bounds;
23138 panel.flags = flags;
23139 panel.scrollbar.x = *x_offset;
23140 panel.scrollbar.y = *y_offset;
23141 panel.buffer = win->buffer;
23142 panel.layout = (
struct nk_panel*)nk_create_panel(ctx);
23143 ctx->current = &panel;
23144 nk_panel_begin(ctx, (flags & NK_WINDOW_TITLE) ? title: 0, NK_PANEL_GROUP);
23146 win->buffer = panel.buffer;
23147 win->buffer.clip = panel.layout->clip;
23148 panel.layout->offset_x = x_offset;
23149 panel.layout->offset_y = y_offset;
23150 panel.layout->parent = win->layout;
23151 win->layout = panel.layout;
23153 ctx->current = win;
23157 nk_flags f = panel.layout->flags;
23175 struct nk_vec2 panel_padding;
23178 NK_ASSERT(ctx->current);
23179 if (!ctx || !ctx->current)
23183 NK_ASSERT(ctx->current);
23184 win = ctx->current;
23185 NK_ASSERT(win->layout);
23187 NK_ASSERT(g->parent);
23188 parent = g->parent;
23191 nk_zero_struct(pan);
23192 panel_padding = nk_panel_get_padding(&ctx->style, NK_PANEL_GROUP);
23193 pan.bounds.y = g->bounds.y - (g->header_height + g->menu.h);
23194 pan.bounds.x = g->bounds.x - panel_padding.x;
23195 pan.bounds.w = g->bounds.w + 2 * panel_padding.x;
23196 pan.bounds.h = g->bounds.h + g->header_height + g->menu.h;
23197 if (g->flags & NK_WINDOW_BORDER) {
23198 pan.bounds.x -= g->border;
23199 pan.bounds.y -= g->border;
23200 pan.bounds.w += 2*g->border;
23201 pan.bounds.h += 2*g->border;
23203 if (!(g->flags & NK_WINDOW_NO_SCROLLBAR)) {
23204 pan.bounds.w += ctx->style.window.scrollbar_size.x;
23205 pan.bounds.h += ctx->style.window.scrollbar_size.y;
23207 pan.scrollbar.x = *g->offset_x;
23208 pan.scrollbar.y = *g->offset_y;
23209 pan.flags = g->flags;
23210 pan.buffer = win->buffer;
23213 ctx->current = &pan;
23216 nk_unify(&clip, &parent->clip, pan.bounds.x, pan.bounds.y,
23217 pan.bounds.x + pan.bounds.w, pan.bounds.y + pan.bounds.h + panel_padding.x);
23218 nk_push_scissor(&pan.buffer, clip);
23221 win->buffer = pan.buffer;
23222 nk_push_scissor(&win->buffer, parent->clip);
23223 ctx->current = win;
23224 win->layout = parent;
23225 g->bounds = pan.bounds;
23230 struct nk_scroll *scroll,
const char *title, nk_flags flags)
23236 const char *title, nk_flags flags)
23246 NK_ASSERT(ctx->current);
23247 NK_ASSERT(ctx->current->layout);
23248 if (!ctx || !ctx->current || !ctx->current->layout || !
id)
23252 win = ctx->current;
23253 id_len = (int)nk_strlen(
id);
23254 id_hash = nk_murmur_hash(
id, (
int)id_len, NK_PANEL_GROUP);
23255 x_offset = nk_find_value(win, id_hash);
23257 x_offset = nk_add_value(ctx, win, id_hash, 0);
23258 y_offset = nk_add_value(ctx, win, id_hash+1, 0);
23260 NK_ASSERT(x_offset);
23261 NK_ASSERT(y_offset);
23262 if (!x_offset || !y_offset)
return 0;
23263 *x_offset = *y_offset = 0;
23264 }
else y_offset = nk_find_value(win, id_hash+1);
23283 nk_uint *x_offset_ptr;
23284 nk_uint *y_offset_ptr;
23288 NK_ASSERT(ctx->current);
23289 NK_ASSERT(ctx->current->layout);
23290 if (!ctx || !ctx->current || !ctx->current->layout || !
id)
23294 win = ctx->current;
23295 id_len = (int)nk_strlen(
id);
23296 id_hash = nk_murmur_hash(
id, (
int)id_len, NK_PANEL_GROUP);
23297 x_offset_ptr = nk_find_value(win, id_hash);
23298 if (!x_offset_ptr) {
23299 x_offset_ptr = nk_add_value(ctx, win, id_hash, 0);
23300 y_offset_ptr = nk_add_value(ctx, win, id_hash+1, 0);
23302 NK_ASSERT(x_offset_ptr);
23303 NK_ASSERT(y_offset_ptr);
23304 if (!x_offset_ptr || !y_offset_ptr)
return;
23305 *x_offset_ptr = *y_offset_ptr = 0;
23306 }
else y_offset_ptr = nk_find_value(win, id_hash+1);
23308 *x_offset = *x_offset_ptr;
23310 *y_offset = *y_offset_ptr;
23318 nk_uint *x_offset_ptr;
23319 nk_uint *y_offset_ptr;
23323 NK_ASSERT(ctx->current);
23324 NK_ASSERT(ctx->current->layout);
23325 if (!ctx || !ctx->current || !ctx->current->layout || !
id)
23329 win = ctx->current;
23330 id_len = (int)nk_strlen(
id);
23331 id_hash = nk_murmur_hash(
id, (
int)id_len, NK_PANEL_GROUP);
23332 x_offset_ptr = nk_find_value(win, id_hash);
23333 if (!x_offset_ptr) {
23334 x_offset_ptr = nk_add_value(ctx, win, id_hash, 0);
23335 y_offset_ptr = nk_add_value(ctx, win, id_hash+1, 0);
23337 NK_ASSERT(x_offset_ptr);
23338 NK_ASSERT(y_offset_ptr);
23339 if (!x_offset_ptr || !y_offset_ptr)
return;
23340 *x_offset_ptr = *y_offset_ptr = 0;
23341 }
else y_offset_ptr = nk_find_value(win, id_hash+1);
23342 *x_offset_ptr = x_offset;
23343 *y_offset_ptr = y_offset;
23356 const char *title, nk_flags flags,
int row_height,
int row_count)
23359 nk_hash title_hash;
23372 if (!ctx || !view || !title)
return 0;
23374 win = ctx->current;
23375 style = &ctx->style;
23376 item_spacing = style->window.spacing;
23377 row_height += NK_MAX(0, (
int)item_spacing.y);
23380 title_len = (int)nk_strlen(title);
23381 title_hash = nk_murmur_hash(title, (
int)title_len, NK_PANEL_GROUP);
23382 x_offset = nk_find_value(win, title_hash);
23384 x_offset = nk_add_value(ctx, win, title_hash, 0);
23385 y_offset = nk_add_value(ctx, win, title_hash+1, 0);
23387 NK_ASSERT(x_offset);
23388 NK_ASSERT(y_offset);
23389 if (!x_offset || !y_offset)
return 0;
23390 *x_offset = *y_offset = 0;
23391 }
else y_offset = nk_find_value(win, title_hash+1);
23392 view->scroll_value = *y_offset;
23393 view->scroll_pointer = y_offset;
23397 win = ctx->current;
23398 layout = win->layout;
23400 view->total_height = row_height * NK_MAX(row_count,1);
23401 view->begin = (int)NK_MAX(((
float)view->scroll_value / (
float)row_height), 0.0f);
23402 view->count = (int)NK_MAX(nk_iceilf((layout->clip.h)/(float)row_height),0);
23403 view->count = NK_MIN(view->count, row_count - view->begin);
23404 view->end = view->begin + view->count;
23416 NK_ASSERT(view->ctx);
23417 NK_ASSERT(view->scroll_pointer);
23418 if (!view || !view->ctx)
return;
23421 win = ctx->current;
23422 layout = win->layout;
23423 layout->at_y = layout->bounds.y + (float)view->total_height;
23424 *view->scroll_pointer = *view->scroll_pointer + view->scroll_value;
23438nk_widget_bounds(const struct
nk_context *ctx)
23442 NK_ASSERT(ctx->current);
23443 if (!ctx || !ctx->current)
23445 nk_layout_peek(&bounds, ctx);
23449nk_widget_position(const struct
nk_context *ctx)
23453 NK_ASSERT(ctx->current);
23454 if (!ctx || !ctx->current)
23457 nk_layout_peek(&bounds, ctx);
23458 return nk_vec2(bounds.x, bounds.y);
23465 NK_ASSERT(ctx->current);
23466 if (!ctx || !ctx->current)
23469 nk_layout_peek(&bounds, ctx);
23470 return nk_vec2(bounds.w, bounds.h);
23473nk_widget_width(
const struct nk_context *ctx)
23477 NK_ASSERT(ctx->current);
23478 if (!ctx || !ctx->current)
23481 nk_layout_peek(&bounds, ctx);
23485nk_widget_height(
const struct nk_context *ctx)
23489 NK_ASSERT(ctx->current);
23490 if (!ctx || !ctx->current)
23493 nk_layout_peek(&bounds, ctx);
23497nk_widget_is_hovered(
const struct nk_context *ctx)
23502 NK_ASSERT(ctx->current);
23503 if (!ctx || !ctx->current || ctx->active != ctx->current)
23506 c = ctx->current->layout->clip;
23507 c.x = (float)((
int)c.x);
23508 c.y = (float)((
int)c.y);
23509 c.w = (float)((
int)c.w);
23510 c.h = (float)((
int)c.h);
23512 nk_layout_peek(&bounds, ctx);
23513 nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
23514 if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
23516 return nk_input_is_mouse_hovering_rect(&ctx->input, bounds);
23519nk_widget_is_mouse_clicked(
const struct nk_context *ctx,
enum nk_buttons btn)
23524 NK_ASSERT(ctx->current);
23525 if (!ctx || !ctx->current || ctx->active != ctx->current)
23528 c = ctx->current->layout->clip;
23529 c.x = (float)((
int)c.x);
23530 c.y = (float)((
int)c.y);
23531 c.w = (float)((
int)c.w);
23532 c.h = (float)((
int)c.h);
23534 nk_layout_peek(&bounds, ctx);
23535 nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
23536 if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
23538 return nk_input_mouse_clicked(&ctx->input, btn, bounds);
23541nk_widget_has_mouse_click_down(
const struct nk_context *ctx,
enum nk_buttons btn, nk_bool down)
23546 NK_ASSERT(ctx->current);
23547 if (!ctx || !ctx->current || ctx->active != ctx->current)
23550 c = ctx->current->layout->clip;
23551 c.x = (float)((
int)c.x);
23552 c.y = (float)((
int)c.y);
23553 c.w = (float)((
int)c.w);
23554 c.h = (float)((
int)c.h);
23556 nk_layout_peek(&bounds, ctx);
23557 nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
23558 if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
23560 return nk_input_has_mouse_click_down_in_rect(&ctx->input, btn, bounds, down);
23571 NK_ASSERT(ctx->current);
23572 NK_ASSERT(ctx->current->layout);
23573 if (!ctx || !ctx->current || !ctx->current->layout)
23577 nk_panel_alloc_space(bounds, ctx);
23578 win = ctx->current;
23579 layout = win->layout;
23593 bounds->x = (float)((
int)bounds->x);
23594 bounds->y = (float)((
int)bounds->y);
23595 bounds->w = (float)((
int)bounds->w);
23596 bounds->h = (float)((
int)bounds->h);
23598 c.x = (float)((
int)c.x);
23599 c.y = (float)((
int)c.y);
23600 c.w = (float)((
int)c.w);
23601 c.h = (float)((
int)c.h);
23603 nk_unify(&v, &c, bounds->x, bounds->y, bounds->x + bounds->w, bounds->y + bounds->h);
23604 if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds->x, bounds->y, bounds->w, bounds->h))
23606 if (win->widgets_disabled)
23608 if (!NK_INBOX(in->mouse.pos.x, in->mouse.pos.y, v.x, v.y, v.w, v.h))
23618 NK_UNUSED(item_padding);
23621 NK_ASSERT(ctx->current);
23622 NK_ASSERT(ctx->current->layout);
23623 if (!ctx || !ctx->current || !ctx->current->layout)
23626 state = nk_widget(bounds, ctx);
23635 int i, index, rows;
23638 NK_ASSERT(ctx->current);
23639 NK_ASSERT(ctx->current->layout);
23640 if (!ctx || !ctx->current || !ctx->current->layout)
23644 win = ctx->current;
23645 layout = win->layout;
23646 index = (layout->row.index + cols) % layout->row.columns;
23647 rows = (layout->row.index + cols) / layout->row.columns;
23649 for (i = 0; i < rows; ++i)
23650 nk_panel_alloc_row(ctx, win);
23654 if (layout->row.type != NK_LAYOUT_DYNAMIC_FIXED &&
23655 layout->row.type != NK_LAYOUT_STATIC_FIXED) {
23656 for (i = 0; i < cols; ++i)
23657 nk_panel_alloc_space(&none, ctx);
23658 } layout->row.index = index;
23661nk_widget_disable_begin(
struct nk_context* ctx)
23667 NK_ASSERT(ctx->current);
23669 if (!ctx || !ctx->current)
23672 win = ctx->current;
23673 style = &ctx->style;
23675 win->widgets_disabled = nk_true;
23677 style->button.color_factor_text = style->button.disabled_factor;
23678 style->button.color_factor_background = style->button.disabled_factor;
23679 style->chart.color_factor = style->chart.disabled_factor;
23680 style->checkbox.color_factor = style->checkbox.disabled_factor;
23681 style->combo.color_factor = style->combo.disabled_factor;
23682 style->combo.button.color_factor_text = style->combo.button.disabled_factor;
23683 style->combo.button.color_factor_background = style->combo.button.disabled_factor;
23684 style->contextual_button.color_factor_text = style->contextual_button.disabled_factor;
23685 style->contextual_button.color_factor_background = style->contextual_button.disabled_factor;
23686 style->edit.color_factor = style->edit.disabled_factor;
23687 style->edit.scrollbar.color_factor = style->edit.scrollbar.disabled_factor;
23688 style->menu_button.color_factor_text = style->menu_button.disabled_factor;
23689 style->menu_button.color_factor_background = style->menu_button.disabled_factor;
23690 style->option.color_factor = style->option.disabled_factor;
23691 style->progress.color_factor = style->progress.disabled_factor;
23692 style->property.color_factor = style->property.disabled_factor;
23693 style->property.inc_button.color_factor_text = style->property.inc_button.disabled_factor;
23694 style->property.inc_button.color_factor_background = style->property.inc_button.disabled_factor;
23695 style->property.dec_button.color_factor_text = style->property.dec_button.disabled_factor;
23696 style->property.dec_button.color_factor_background = style->property.dec_button.disabled_factor;
23697 style->property.edit.color_factor = style->property.edit.disabled_factor;
23698 style->scrollh.color_factor = style->scrollh.disabled_factor;
23699 style->scrollh.inc_button.color_factor_text = style->scrollh.inc_button.disabled_factor;
23700 style->scrollh.inc_button.color_factor_background = style->scrollh.inc_button.disabled_factor;
23701 style->scrollh.dec_button.color_factor_text = style->scrollh.dec_button.disabled_factor;
23702 style->scrollh.dec_button.color_factor_background = style->scrollh.dec_button.disabled_factor;
23703 style->scrollv.color_factor = style->scrollv.disabled_factor;
23704 style->scrollv.inc_button.color_factor_text = style->scrollv.inc_button.disabled_factor;
23705 style->scrollv.inc_button.color_factor_background = style->scrollv.inc_button.disabled_factor;
23706 style->scrollv.dec_button.color_factor_text = style->scrollv.dec_button.disabled_factor;
23707 style->scrollv.dec_button.color_factor_background = style->scrollv.dec_button.disabled_factor;
23708 style->selectable.color_factor = style->selectable.disabled_factor;
23709 style->slider.color_factor = style->slider.disabled_factor;
23710 style->slider.inc_button.color_factor_text = style->slider.inc_button.disabled_factor;
23711 style->slider.inc_button.color_factor_background = style->slider.inc_button.disabled_factor;
23712 style->slider.dec_button.color_factor_text = style->slider.dec_button.disabled_factor;
23713 style->slider.dec_button.color_factor_background = style->slider.dec_button.disabled_factor;
23714 style->tab.color_factor = style->tab.disabled_factor;
23715 style->tab.node_maximize_button.color_factor_text = style->tab.node_maximize_button.disabled_factor;
23716 style->tab.node_minimize_button.color_factor_text = style->tab.node_minimize_button.disabled_factor;
23717 style->tab.tab_maximize_button.color_factor_text = style->tab.tab_maximize_button.disabled_factor;
23718 style->tab.tab_maximize_button.color_factor_background = style->tab.tab_maximize_button.disabled_factor;
23719 style->tab.tab_minimize_button.color_factor_text = style->tab.tab_minimize_button.disabled_factor;
23720 style->tab.tab_minimize_button.color_factor_background = style->tab.tab_minimize_button.disabled_factor;
23721 style->text.color_factor = style->text.disabled_factor;
23724nk_widget_disable_end(
struct nk_context* ctx)
23730 NK_ASSERT(ctx->current);
23732 if (!ctx || !ctx->current)
23735 win = ctx->current;
23736 style = &ctx->style;
23738 win->widgets_disabled = nk_false;
23740 style->button.color_factor_text = 1.0f;
23741 style->button.color_factor_background = 1.0f;
23742 style->chart.color_factor = 1.0f;
23743 style->checkbox.color_factor = 1.0f;
23744 style->combo.color_factor = 1.0f;
23745 style->combo.button.color_factor_text = 1.0f;
23746 style->combo.button.color_factor_background = 1.0f;
23747 style->contextual_button.color_factor_text = 1.0f;
23748 style->contextual_button.color_factor_background = 1.0f;
23749 style->edit.color_factor = 1.0f;
23750 style->edit.scrollbar.color_factor = 1.0f;
23751 style->menu_button.color_factor_text = 1.0f;
23752 style->menu_button.color_factor_background = 1.0f;
23753 style->option.color_factor = 1.0f;
23754 style->progress.color_factor = 1.0f;
23755 style->property.color_factor = 1.0f;
23756 style->property.inc_button.color_factor_text = 1.0f;
23757 style->property.inc_button.color_factor_background = 1.0f;
23758 style->property.dec_button.color_factor_text = 1.0f;
23759 style->property.dec_button.color_factor_background = 1.0f;
23760 style->property.edit.color_factor = 1.0f;
23761 style->scrollh.color_factor = 1.0f;
23762 style->scrollh.inc_button.color_factor_text = 1.0f;
23763 style->scrollh.inc_button.color_factor_background = 1.0f;
23764 style->scrollh.dec_button.color_factor_text = 1.0f;
23765 style->scrollh.dec_button.color_factor_background = 1.0f;
23766 style->scrollv.color_factor = 1.0f;
23767 style->scrollv.inc_button.color_factor_text = 1.0f;
23768 style->scrollv.inc_button.color_factor_background = 1.0f;
23769 style->scrollv.dec_button.color_factor_text = 1.0f;
23770 style->scrollv.dec_button.color_factor_background = 1.0f;
23771 style->selectable.color_factor = 1.0f;
23772 style->slider.color_factor = 1.0f;
23773 style->slider.inc_button.color_factor_text = 1.0f;
23774 style->slider.inc_button.color_factor_background = 1.0f;
23775 style->slider.dec_button.color_factor_text = 1.0f;
23776 style->slider.dec_button.color_factor_background = 1.0f;
23777 style->tab.color_factor = 1.0f;
23778 style->tab.node_maximize_button.color_factor_text = 1.0f;
23779 style->tab.node_minimize_button.color_factor_text = 1.0f;
23780 style->tab.tab_maximize_button.color_factor_text = 1.0f;
23781 style->tab.tab_maximize_button.color_factor_background = 1.0f;
23782 style->tab.tab_minimize_button.color_factor_text = 1.0f;
23783 style->tab.tab_minimize_button.color_factor_background = 1.0f;
23784 style->text.color_factor = 1.0f;
23797 const char *
string,
int len,
const struct nk_text *t,
23805 if (!o || !t)
return;
23807 b.h = NK_MAX(b.h, 2 * t->padding.y);
23808 label.x = 0; label.w = 0;
23809 label.y = b.y + t->padding.y;
23810 label.h = NK_MIN(f->
height, b.h - 2 * t->padding.y);
23812 text_width = f->
width(f->userdata, f->
height, (
const char*)
string, len);
23813 text_width += (2.0f * t->padding.x);
23816 if (a & NK_TEXT_ALIGN_LEFT) {
23817 label.x = b.x + t->padding.x;
23818 label.w = NK_MAX(0, b.w - 2 * t->padding.x);
23819 }
else if (a & NK_TEXT_ALIGN_CENTERED) {
23820 label.w = NK_MAX(1, 2 * t->padding.x + (
float)text_width);
23821 label.x = (b.x + t->padding.x + ((b.w - 2 * t->padding.x) - label.w) / 2);
23822 label.x = NK_MAX(b.x + t->padding.x, label.x);
23823 label.w = NK_MIN(b.x + b.w, label.x + label.w);
23824 if (label.w >= label.x) label.w -= label.x;
23825 }
else if (a & NK_TEXT_ALIGN_RIGHT) {
23826 label.x = NK_MAX(b.x + t->padding.x, (b.x + b.w) - (2 * t->padding.x + (
float)text_width));
23827 label.w = (float)text_width + 2 * t->padding.x;
23831 if (a & NK_TEXT_ALIGN_MIDDLE) {
23832 label.y = b.y + b.h/2.0f - (float)f->
height/2.0f;
23833 label.h = NK_MAX(b.h/2.0f, b.h - (b.h/2.0f + f->
height/2.0f));
23834 }
else if (a & NK_TEXT_ALIGN_BOTTOM) {
23835 label.y = b.y + b.h - f->
height;
23838 nk_draw_text(o, label, (
const char*)
string, len, f, t->background, t->text);
23842 const char *
string,
int len,
const struct nk_text *t,
23850 struct nk_text text;
23851 NK_INTERN nk_rune seperator[] = {
' '};
23855 if (!o || !t)
return;
23858 text.background = t->background;
23859 text.text = t->text;
23861 b.w = NK_MAX(b.w, 2 * t->padding.x);
23862 b.h = NK_MAX(b.h, 2 * t->padding.y);
23863 b.h = b.h - 2 * t->padding.y;
23865 line.x = b.x + t->padding.x;
23866 line.y = b.y + t->padding.y;
23867 line.w = b.w - 2 * t->padding.x;
23868 line.h = 2 * t->padding.y + f->
height;
23870 fitting = nk_text_clamp(f,
string, len, line.w, &glyphs, &width, seperator,NK_LEN(seperator));
23871 while (done < len) {
23872 if (!fitting || line.y + line.h >= (b.y + b.h))
break;
23873 nk_widget_text(o, line, &
string[done], fitting, &text, NK_TEXT_LEFT, f);
23875 line.y += f->
height + 2 * t->padding.y;
23876 fitting = nk_text_clamp(f, &
string[done], len - done, line.w, &glyphs, &width, seperator,NK_LEN(seperator));
23880nk_text_colored(
struct nk_context *ctx,
const char *str,
int len,
23881 nk_flags alignment,
struct nk_color color)
23888 struct nk_text text;
23891 NK_ASSERT(ctx->current);
23892 NK_ASSERT(ctx->current->layout);
23893 if (!ctx || !ctx->current || !ctx->current->layout)
return;
23895 win = ctx->current;
23896 style = &ctx->style;
23897 nk_panel_alloc_space(&bounds, ctx);
23898 item_padding = style->text.padding;
23900 text.padding.x = item_padding.x;
23901 text.padding.y = item_padding.y;
23902 text.background = style->window.background;
23903 text.text = nk_rgb_factor(color, style->text.color_factor);
23904 nk_widget_text(&win->buffer, bounds, str, len, &text, alignment, style->font);
23907nk_text_wrap_colored(
struct nk_context *ctx,
const char *str,
23915 struct nk_text text;
23918 NK_ASSERT(ctx->current);
23919 NK_ASSERT(ctx->current->layout);
23920 if (!ctx || !ctx->current || !ctx->current->layout)
return;
23922 win = ctx->current;
23923 style = &ctx->style;
23924 nk_panel_alloc_space(&bounds, ctx);
23925 item_padding = style->text.padding;
23927 text.padding.x = item_padding.x;
23928 text.padding.y = item_padding.y;
23929 text.background = style->window.background;
23930 text.text = nk_rgb_factor(color, style->text.color_factor);
23931 nk_widget_text_wrap(&win->buffer, bounds, str, len, &text, style->font);
23933#ifdef NK_INCLUDE_STANDARD_VARARGS
23935nk_labelf_colored(
struct nk_context *ctx, nk_flags flags,
23936 struct nk_color color,
const char *fmt, ...)
23939 va_start(args, fmt);
23940 nk_labelfv_colored(ctx, flags, color, fmt, args);
23945 const char *fmt, ...)
23948 va_start(args, fmt);
23949 nk_labelfv_colored_wrap(ctx, color, fmt, args);
23953nk_labelf(
struct nk_context *ctx, nk_flags flags,
const char *fmt, ...)
23956 va_start(args, fmt);
23957 nk_labelfv(ctx, flags, fmt, args);
23961nk_labelf_wrap(
struct nk_context *ctx,
const char *fmt,...)
23964 va_start(args, fmt);
23965 nk_labelfv_wrap(ctx, fmt, args);
23969nk_labelfv_colored(
struct nk_context *ctx, nk_flags flags,
23970 struct nk_color color,
const char *fmt, va_list args)
23973 nk_strfmt(buf, NK_LEN(buf), fmt, args);
23974 nk_label_colored(ctx, buf, flags, color);
23979 const char *fmt, va_list args)
23982 nk_strfmt(buf, NK_LEN(buf), fmt, args);
23983 nk_label_colored_wrap(ctx, buf, color);
23987nk_labelfv(
struct nk_context *ctx, nk_flags flags,
const char *fmt, va_list args)
23990 nk_strfmt(buf, NK_LEN(buf), fmt, args);
23991 nk_label(ctx, buf, flags);
23995nk_labelfv_wrap(
struct nk_context *ctx,
const char *fmt, va_list args)
23998 nk_strfmt(buf, NK_LEN(buf), fmt, args);
23999 nk_label_wrap(ctx, buf);
24003nk_value_bool(
struct nk_context *ctx,
const char *prefix,
int value)
24005 nk_labelf(ctx, NK_TEXT_LEFT,
"%s: %s", prefix, ((value) ?
"true":
"false"));
24008nk_value_int(
struct nk_context *ctx,
const char *prefix,
int value)
24010 nk_labelf(ctx, NK_TEXT_LEFT,
"%s: %d", prefix, value);
24013nk_value_uint(
struct nk_context *ctx,
const char *prefix,
unsigned int value)
24015 nk_labelf(ctx, NK_TEXT_LEFT,
"%s: %u", prefix, value);
24018nk_value_float(
struct nk_context *ctx,
const char *prefix,
float value)
24020 double double_value = (double)value;
24021 nk_labelf(ctx, NK_TEXT_LEFT,
"%s: %.3f", prefix, double_value);
24026 nk_labelf(ctx, NK_TEXT_LEFT,
"%s: (%d, %d, %d, %d)", p, c.r, c.g, c.b, c.a);
24031 double c[4]; nk_color_dv(c, color);
24032 nk_labelf(ctx, NK_TEXT_LEFT,
"%s: (%.2f, %.2f, %.2f, %.2f)",
24033 p, c[0], c[1], c[2], c[3]);
24036nk_value_color_hex(
struct nk_context *ctx,
const char *prefix,
struct nk_color color)
24039 nk_color_hex_rgba(hex, color);
24040 nk_labelf(ctx, NK_TEXT_LEFT,
"%s: %s", prefix, hex);
24044nk_text(
struct nk_context *ctx,
const char *str,
int len, nk_flags alignment)
24048 nk_text_colored(ctx, str, len, alignment, ctx->style.text.color);
24051nk_text_wrap(
struct nk_context *ctx,
const char *str,
int len)
24055 nk_text_wrap_colored(ctx, str, len, ctx->style.text.color);
24058nk_label(
struct nk_context *ctx,
const char *str, nk_flags alignment)
24060 nk_text(ctx, str, nk_strlen(str), alignment);
24063nk_label_colored(
struct nk_context *ctx,
const char *str, nk_flags align,
24066 nk_text_colored(ctx, str, nk_strlen(str), align, color);
24069nk_label_wrap(
struct nk_context *ctx,
const char *str)
24071 nk_text_wrap(ctx, str, nk_strlen(str));
24074nk_label_colored_wrap(
struct nk_context *ctx,
const char *str,
struct nk_color color)
24076 nk_text_wrap_colored(ctx, str, nk_strlen(str), color);
24089nk_handle_ptr(
void *ptr)
24096nk_handle_id(
int id)
24099 nk_zero_struct(handle);
24104nk_subimage_ptr(void *ptr, nk_ushort w, nk_ushort h,
struct nk_rect r)
24107 nk_zero(&s,
sizeof(s));
24108 s.handle.ptr = ptr;
24110 s.region[0] = (nk_ushort)r.x;
24111 s.region[1] = (nk_ushort)r.y;
24112 s.region[2] = (nk_ushort)r.w;
24113 s.region[3] = (nk_ushort)r.h;
24117nk_subimage_id(int id, nk_ushort w, nk_ushort h, struct
nk_rect r)
24120 nk_zero(&s,
sizeof(s));
24123 s.region[0] = (nk_ushort)r.x;
24124 s.region[1] = (nk_ushort)r.y;
24125 s.region[2] = (nk_ushort)r.w;
24126 s.region[3] = (nk_ushort)r.h;
24130nk_subimage_handle(
nk_handle handle, nk_ushort w, nk_ushort h, struct
nk_rect r)
24133 nk_zero(&s,
sizeof(s));
24136 s.region[0] = (nk_ushort)r.x;
24137 s.region[1] = (nk_ushort)r.y;
24138 s.region[2] = (nk_ushort)r.w;
24139 s.region[3] = (nk_ushort)r.h;
24146 nk_zero(&s,
sizeof(s));
24156nk_image_ptr(void *ptr)
24159 nk_zero(&s,
sizeof(s));
24161 s.handle.ptr = ptr;
24173 nk_zero(&s,
sizeof(s));
24183nk_image_is_subimage(
const struct nk_image* img)
24186 return !(img->w == 0 && img->h == 0);
24195 NK_ASSERT(ctx->current);
24196 NK_ASSERT(ctx->current->layout);
24197 if (!ctx || !ctx->current || !ctx->current->layout)
return;
24199 win = ctx->current;
24200 if (!nk_widget(&bounds, ctx))
return;
24210 NK_ASSERT(ctx->current);
24211 NK_ASSERT(ctx->current->layout);
24212 if (!ctx || !ctx->current || !ctx->current->layout)
return;
24214 win = ctx->current;
24215 if (!nk_widget(&bounds, ctx))
return;
24229nk_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)
24233 nk_zero(&s,
sizeof(s));
24234 i->handle.ptr = ptr;
24235 i->w = w; i->h = h;
24236 i->region[0] = (nk_ushort)rgn.x;
24237 i->region[1] = (nk_ushort)rgn.y;
24238 i->region[2] = (nk_ushort)rgn.w;
24239 i->region[3] = (nk_ushort)rgn.h;
24240 s.l = l; s.t = t; s.r = r; s.b = b;
24244nk_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)
24248 nk_zero(&s,
sizeof(s));
24250 i->w = w; i->h = h;
24251 i->region[0] = (nk_ushort)rgn.x;
24252 i->region[1] = (nk_ushort)rgn.y;
24253 i->region[2] = (nk_ushort)rgn.w;
24254 i->region[3] = (nk_ushort)rgn.h;
24255 s.l = l; s.t = t; s.r = r; s.b = b;
24259nk_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)
24263 nk_zero(&s,
sizeof(s));
24264 i->handle = handle;
24265 i->w = w; i->h = h;
24266 i->region[0] = (nk_ushort)rgn.x;
24267 i->region[1] = (nk_ushort)rgn.y;
24268 i->region[2] = (nk_ushort)rgn.w;
24269 i->region[3] = (nk_ushort)rgn.h;
24270 s.l = l; s.t = t; s.r = r; s.b = b;
24274nk_nine_slice_handle(
nk_handle handle, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b)
24278 nk_zero(&s,
sizeof(s));
24279 i->handle = handle;
24280 i->w = 0; i->h = 0;
24285 s.l = l; s.t = t; s.r = r; s.b = b;
24289nk_nine_slice_ptr(void *ptr, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b)
24293 nk_zero(&s,
sizeof(s));
24295 i->handle.ptr = ptr;
24296 i->w = 0; i->h = 0;
24301 s.l = l; s.t = t; s.r = r; s.b = b;
24305nk_nine_slice_id(int id, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b)
24309 nk_zero(&s,
sizeof(s));
24311 i->w = 0; i->h = 0;
24316 s.l = l; s.t = t; s.r = r; s.b = b;
24320nk_nine_slice_is_sub9slice(
const struct nk_nine_slice* slice)
24323 return !(slice->img.w == 0 && slice->img.h == 0);
24342 case NK_SYMBOL_UNDERSCORE:
24343 case NK_SYMBOL_PLUS:
24344 case NK_SYMBOL_MINUS: {
24346 const char *X = (type == NK_SYMBOL_X) ?
"x":
24347 (type == NK_SYMBOL_UNDERSCORE) ?
"_":
24348 (type == NK_SYMBOL_PLUS) ?
"+":
"-";
24349 struct nk_text text;
24351 text.background = background;
24352 text.text = foreground;
24353 nk_widget_text(out, content, X, 1, &text, NK_TEXT_CENTERED, font);
24355 case NK_SYMBOL_CIRCLE_SOLID:
24356 case NK_SYMBOL_CIRCLE_OUTLINE:
24357 case NK_SYMBOL_RECT_SOLID:
24358 case NK_SYMBOL_RECT_OUTLINE: {
24360 if (type == NK_SYMBOL_RECT_SOLID || type == NK_SYMBOL_RECT_OUTLINE) {
24362 if (type == NK_SYMBOL_RECT_OUTLINE)
24363 nk_fill_rect(out, nk_shrink_rect(content, border_width), 0, background);
24365 nk_fill_circle(out, content, foreground);
24366 if (type == NK_SYMBOL_CIRCLE_OUTLINE)
24367 nk_fill_circle(out, nk_shrink_rect(content, 1), background);
24370 case NK_SYMBOL_TRIANGLE_UP:
24371 case NK_SYMBOL_TRIANGLE_DOWN:
24372 case NK_SYMBOL_TRIANGLE_LEFT:
24373 case NK_SYMBOL_TRIANGLE_RIGHT: {
24374 enum nk_heading heading;
24376 heading = (type == NK_SYMBOL_TRIANGLE_RIGHT) ? NK_RIGHT :
24377 (type == NK_SYMBOL_TRIANGLE_LEFT) ? NK_LEFT:
24378 (type == NK_SYMBOL_TRIANGLE_UP) ? NK_UP: NK_DOWN;
24379 nk_triangle_from_direction(points, content, 0, 0, heading);
24380 nk_fill_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y,
24381 points[2].x, points[2].y, foreground);
24383 case NK_SYMBOL_TRIANGLE_UP_OUTLINE:
24384 case NK_SYMBOL_TRIANGLE_DOWN_OUTLINE:
24385 case NK_SYMBOL_TRIANGLE_LEFT_OUTLINE:
24386 case NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE: {
24387 enum nk_heading heading;
24389 heading = (type == NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE) ? NK_RIGHT :
24390 (type == NK_SYMBOL_TRIANGLE_LEFT_OUTLINE) ? NK_LEFT:
24391 (type == NK_SYMBOL_TRIANGLE_UP_OUTLINE) ? NK_UP: NK_DOWN;
24392 nk_triangle_from_direction(points, content, 0, 0, heading);
24393 nk_stroke_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y,
24394 points[2].x, points[2].y, border_width, foreground);
24397 case NK_SYMBOL_NONE:
24398 case NK_SYMBOL_MAX:
break;
24402nk_button_behavior(nk_flags *state,
struct nk_rect r,
24403 const struct nk_input *i,
enum nk_button_behavior behavior)
24406 nk_widget_state_reset(state);
24408 if (nk_input_is_mouse_hovering_rect(i, r)) {
24410 if (nk_input_is_mouse_down(i, NK_BUTTON_LEFT))
24412 if (nk_input_has_mouse_click_in_button_rect(i, NK_BUTTON_LEFT, r)) {
24413 ret = (behavior != NK_BUTTON_DEFAULT) ?
24414 nk_input_is_mouse_down(i, NK_BUTTON_LEFT):
24415#ifdef NK_BUTTON_TRIGGER_ON_RELEASE
24416 nk_input_is_mouse_released(i, NK_BUTTON_LEFT);
24418 nk_input_is_mouse_pressed(i, NK_BUTTON_LEFT);
24424 else if (nk_input_is_mouse_prev_hovering_rect(i, r))
24430 const struct nk_rect *bounds, nk_flags state,
24435 background = &style->hover;
24437 background = &style->active;
24438 else background = &style->normal;
24440 switch (background->type) {
24441 case NK_STYLE_ITEM_IMAGE:
24442 nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor_background));
24444 case NK_STYLE_ITEM_NINE_SLICE:
24445 nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor_background));
24447 case NK_STYLE_ITEM_COLOR:
24448 nk_fill_rect(out, *bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor_background));
24449 nk_stroke_rect(out, *bounds, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor_background));
24457 enum nk_button_behavior behavior,
struct nk_rect *content)
24463 if (!out || !style)
24467 content->x = r.x + style->padding.x + style->border + style->rounding;
24468 content->y = r.y + style->padding.y + style->border + style->rounding;
24469 content->w = r.w - (2 * (style->padding.x + style->border + style->rounding));
24470 content->h = r.h - (2 * (style->padding.y + style->border + style->rounding));
24473 bounds.x = r.x - style->touch_padding.x;
24474 bounds.y = r.y - style->touch_padding.y;
24475 bounds.w = r.w + 2 * style->touch_padding.x;
24476 bounds.h = r.h + 2 * style->touch_padding.y;
24477 return nk_button_behavior(state, bounds, in, behavior);
24481 const struct nk_rect *bounds,
const struct nk_rect *content, nk_flags state,
24483 nk_flags text_alignment,
const struct nk_user_font *font)
24485 struct nk_text text;
24487 background = nk_draw_button(out, bounds, state, style);
24490 if (background->type == NK_STYLE_ITEM_COLOR)
24491 text.background = background->data.color;
24492 else text.background = style->text_background;
24494 text.text = style->text_hover;
24496 text.text = style->text_active;
24497 else text.text = style->text_normal;
24499 text.text = nk_rgb_factor(text.text, style->color_factor_text);
24502 nk_widget_text(out, *content, txt, len, &text, text_alignment, font);
24505nk_do_button_text(nk_flags *state,
24507 const char *
string,
int len, nk_flags align,
enum nk_button_behavior behavior,
24512 int ret = nk_false;
24519 if (!out || !style || !font || !
string)
24522 ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
24523 if (style->draw_begin) style->draw_begin(out, style->userdata);
24524 nk_draw_button_text(out, &bounds, &content, *state, style,
string, len, align, font);
24525 if (style->draw_end) style->draw_end(out, style->userdata);
24532 enum nk_symbol_type type,
const struct nk_user_font *font)
24538 background = nk_draw_button(out, bounds, state, style);
24539 if (background->type == NK_STYLE_ITEM_COLOR)
24540 bg = background->data.color;
24541 else bg = style->text_background;
24544 sym = style->text_hover;
24546 sym = style->text_active;
24547 else sym = style->text_normal;
24549 sym = nk_rgb_factor(sym, style->color_factor_text);
24550 nk_draw_symbol(out, type, *content, bg, sym, 1, font);
24553nk_do_button_symbol(nk_flags *state,
24555 enum nk_symbol_type symbol,
enum nk_button_behavior behavior,
24566 if (!out || !style || !font || !state)
24569 ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
24570 if (style->draw_begin) style->draw_begin(out, style->userdata);
24571 nk_draw_button_symbol(out, &bounds, &content, *state, style, symbol, font);
24572 if (style->draw_end) style->draw_end(out, style->userdata);
24580 nk_draw_button(out, bounds, state, style);
24581 nk_draw_image(out, *content, img, nk_rgb_factor(nk_white, style->color_factor_background));
24584nk_do_button_image(nk_flags *state,
24586 struct nk_image img,
enum nk_button_behavior b,
24595 if (!out || !style || !state)
24598 ret = nk_do_button(state, out, bounds, style, in, b, &content);
24599 content.x += style->image_padding.x;
24600 content.y += style->image_padding.y;
24601 content.w -= 2 * style->image_padding.x;
24602 content.h -= 2 * style->image_padding.y;
24604 if (style->draw_begin) style->draw_begin(out, style->userdata);
24605 nk_draw_button_image(out, &bounds, &content, *state, style, &img);
24606 if (style->draw_end) style->draw_end(out, style->userdata);
24613 const char *str,
int len,
enum nk_symbol_type type,
24617 struct nk_text text;
24621 background = nk_draw_button(out, bounds, state, style);
24622 if (background->type == NK_STYLE_ITEM_COLOR)
24623 text.background = background->data.color;
24624 else text.background = style->text_background;
24628 sym = style->text_hover;
24629 text.text = style->text_hover;
24631 sym = style->text_active;
24632 text.text = style->text_active;
24634 sym = style->text_normal;
24635 text.text = style->text_normal;
24638 sym = nk_rgb_factor(sym, style->color_factor_text);
24639 text.text = nk_rgb_factor(text.text, style->color_factor_text);
24641 nk_draw_symbol(out, type, *symbol, style->text_background, sym, 0, font);
24642 nk_widget_text(out, *label, str, len, &text, NK_TEXT_CENTERED, font);
24645nk_do_button_text_symbol(nk_flags *state,
24647 enum nk_symbol_type symbol,
const char *str,
int len, nk_flags align,
24648 enum nk_button_behavior behavior,
const struct nk_style_button *style,
24652 struct nk_rect tri = {0,0,0,0};
24658 if (!out || !style || !font)
24661 ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
24662 tri.y = content.y + (content.h/2) - font->
height/2;
24664 if (align & NK_TEXT_ALIGN_LEFT) {
24665 tri.x = (content.x + content.w) - (2 * style->padding.x + tri.w);
24666 tri.x = NK_MAX(tri.x, 0);
24667 }
else tri.x = content.x + 2 * style->padding.x;
24670 if (style->draw_begin) style->draw_begin(out, style->userdata);
24671 nk_draw_button_text_symbol(out, &bounds, &content, &tri,
24672 *state, style, str, len, symbol, font);
24673 if (style->draw_end) style->draw_end(out, style->userdata);
24680 const char *str,
int len,
const struct nk_user_font *font,
24683 struct nk_text text;
24685 background = nk_draw_button(out, bounds, state, style);
24688 if (background->type == NK_STYLE_ITEM_COLOR)
24689 text.background = background->data.color;
24690 else text.background = style->text_background;
24692 text.text = style->text_hover;
24694 text.text = style->text_active;
24695 else text.text = style->text_normal;
24697 text.text = nk_rgb_factor(text.text, style->color_factor_text);
24698 text.padding =
nk_vec2(0, 0);
24699 nk_widget_text(out, *label, str, len, &text, NK_TEXT_CENTERED, font);
24700 nk_draw_image(out, *image, img, nk_rgb_factor(nk_white, style->color_factor_background));
24703nk_do_button_text_image(nk_flags *state,
24705 struct nk_image img,
const char* str,
int len, nk_flags align,
24706 enum nk_button_behavior behavior,
const struct nk_style_button *style,
24717 if (!out || !font || !style || !str)
24720 ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
24721 icon.y = bounds.y + style->padding.y;
24722 icon.w = icon.h = bounds.h - 2 * style->padding.y;
24723 if (align & NK_TEXT_ALIGN_LEFT) {
24724 icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w);
24725 icon.x = NK_MAX(icon.x, 0);
24726 }
else icon.x = bounds.x + 2 * style->padding.x;
24728 icon.x += style->image_padding.x;
24729 icon.y += style->image_padding.y;
24730 icon.w -= 2 * style->image_padding.x;
24731 icon.h -= 2 * style->image_padding.y;
24733 if (style->draw_begin) style->draw_begin(out, style->userdata);
24734 nk_draw_button_text_image(out, &bounds, &content, &icon, *state, style, str, len, font, &img);
24735 if (style->draw_end) style->draw_end(out, style->userdata);
24739nk_button_set_behavior(
struct nk_context *ctx,
enum nk_button_behavior behavior)
24743 ctx->button_behavior = behavior;
24746nk_button_push_behavior(
struct nk_context *ctx,
enum nk_button_behavior behavior)
24748 struct nk_config_stack_button_behavior *button_stack;
24749 struct nk_config_stack_button_behavior_element *element;
24752 if (!ctx)
return 0;
24754 button_stack = &ctx->stacks.button_behaviors;
24755 NK_ASSERT(button_stack->head < (
int)NK_LEN(button_stack->elements));
24756 if (button_stack->head >= (
int)NK_LEN(button_stack->elements))
24759 element = &button_stack->elements[button_stack->head++];
24760 element->address = &ctx->button_behavior;
24761 element->old_value = ctx->button_behavior;
24762 ctx->button_behavior = behavior;
24766nk_button_pop_behavior(
struct nk_context *ctx)
24768 struct nk_config_stack_button_behavior *button_stack;
24769 struct nk_config_stack_button_behavior_element *element;
24772 if (!ctx)
return 0;
24774 button_stack = &ctx->stacks.button_behaviors;
24775 NK_ASSERT(button_stack->head > 0);
24776 if (button_stack->head < 1)
24779 element = &button_stack->elements[--button_stack->head];
24780 *element->address = element->old_value;
24784nk_button_text_styled(
struct nk_context *ctx,
24796 NK_ASSERT(ctx->current);
24797 NK_ASSERT(ctx->current->layout);
24798 if (!style || !ctx || !ctx->current || !ctx->current->layout)
return 0;
24800 win = ctx->current;
24801 layout = win->layout;
24802 state = nk_widget(&bounds, ctx);
24804 if (!state)
return 0;
24806 return nk_do_button_text(&ctx->last_widget_state, &win->buffer, bounds,
24807 title, len, style->text_alignment, ctx->button_behavior,
24808 style, in, ctx->style.font);
24811nk_button_text(
struct nk_context *ctx,
const char *title,
int len)
24814 if (!ctx)
return 0;
24815 return nk_button_text_styled(ctx, &ctx->style.button, title, len);
24817NK_API nk_bool nk_button_label_styled(
struct nk_context *ctx,
24820 return nk_button_text_styled(ctx, style, title, nk_strlen(title));
24822NK_API nk_bool nk_button_label(
struct nk_context *ctx,
const char *title)
24824 return nk_button_text(ctx, title, nk_strlen(title));
24840 NK_ASSERT(ctx->current);
24841 NK_ASSERT(ctx->current->layout);
24842 if (!ctx || !ctx->current || !ctx->current->layout)
24845 win = ctx->current;
24846 layout = win->layout;
24848 state = nk_widget(&bounds, ctx);
24849 if (!state)
return 0;
24852 button = ctx->style.button;
24853 button.normal = nk_style_item_color(color);
24854 button.hover = nk_style_item_color(color);
24855 button.active = nk_style_item_color(color);
24856 ret = nk_do_button(&ctx->last_widget_state, &win->buffer, bounds,
24857 &button, in, ctx->button_behavior, &content);
24858 nk_draw_button(&win->buffer, &bounds, ctx->last_widget_state, &button);
24862nk_button_symbol_styled(
struct nk_context *ctx,
24873 NK_ASSERT(ctx->current);
24874 NK_ASSERT(ctx->current->layout);
24875 if (!ctx || !ctx->current || !ctx->current->layout)
24878 win = ctx->current;
24879 layout = win->layout;
24880 state = nk_widget(&bounds, ctx);
24881 if (!state)
return 0;
24883 return nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, bounds,
24884 symbol, ctx->button_behavior, style, in, ctx->style.font);
24887nk_button_symbol(
struct nk_context *ctx,
enum nk_symbol_type symbol)
24890 if (!ctx)
return 0;
24891 return nk_button_symbol_styled(ctx, &ctx->style.button, symbol);
24905 NK_ASSERT(ctx->current);
24906 NK_ASSERT(ctx->current->layout);
24907 if (!ctx || !ctx->current || !ctx->current->layout)
24910 win = ctx->current;
24911 layout = win->layout;
24913 state = nk_widget(&bounds, ctx);
24914 if (!state)
return 0;
24916 return nk_do_button_image(&ctx->last_widget_state, &win->buffer, bounds,
24917 img, ctx->button_behavior, style, in);
24923 if (!ctx)
return 0;
24924 return nk_button_image_styled(ctx, &ctx->style.button, img);
24927nk_button_symbol_text_styled(
struct nk_context *ctx,
24929 const char *text,
int len, nk_flags align)
24939 NK_ASSERT(ctx->current);
24940 NK_ASSERT(ctx->current->layout);
24941 if (!ctx || !ctx->current || !ctx->current->layout)
24944 win = ctx->current;
24945 layout = win->layout;
24947 state = nk_widget(&bounds, ctx);
24948 if (!state)
return 0;
24950 return nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, bounds,
24951 symbol, text, len, align, ctx->button_behavior,
24952 style, ctx->style.font, in);
24955nk_button_symbol_text(
struct nk_context *ctx,
enum nk_symbol_type symbol,
24956 const char* text,
int len, nk_flags align)
24959 if (!ctx)
return 0;
24960 return nk_button_symbol_text_styled(ctx, &ctx->style.button, symbol, text, len, align);
24962NK_API nk_bool nk_button_symbol_label(
struct nk_context *ctx,
enum nk_symbol_type symbol,
24963 const char *label, nk_flags align)
24965 return nk_button_symbol_text(ctx, symbol, label, nk_strlen(label), align);
24967NK_API nk_bool nk_button_symbol_label_styled(
struct nk_context *ctx,
24969 const char *title, nk_flags align)
24971 return nk_button_symbol_text_styled(ctx, style, symbol, title, nk_strlen(title), align);
24974nk_button_image_text_styled(
struct nk_context *ctx,
24976 int len, nk_flags align)
24986 NK_ASSERT(ctx->current);
24987 NK_ASSERT(ctx->current->layout);
24988 if (!ctx || !ctx->current || !ctx->current->layout)
24991 win = ctx->current;
24992 layout = win->layout;
24994 state = nk_widget(&bounds, ctx);
24995 if (!state)
return 0;
24997 return nk_do_button_text_image(&ctx->last_widget_state, &win->buffer,
24998 bounds, img, text, len, align, ctx->button_behavior,
24999 style, ctx->style.font, in);
25003 const char *text,
int len, nk_flags align)
25005 return nk_button_image_text_styled(ctx, &ctx->style.button,img, text, len, align);
25008 const char *label, nk_flags align)
25010 return nk_button_image_text(ctx, img, label, nk_strlen(label), align);
25012NK_API nk_bool nk_button_image_label_styled(
struct nk_context *ctx,
25014 const char *label, nk_flags text_alignment)
25016 return nk_button_image_text_styled(ctx, style, img, label, nk_strlen(label), text_alignment);
25030 nk_flags *state, nk_bool active)
25032 nk_widget_state_reset(state);
25033 if (nk_button_behavior(state, select, in, NK_BUTTON_DEFAULT)) {
25039 else if (nk_input_is_mouse_prev_hovering_rect(in, select))
25047 const struct nk_rect *cursors,
const char *
string,
int len,
25048 const struct nk_user_font *font, nk_flags text_alignment)
25052 struct nk_text text;
25056 background = &style->hover;
25057 cursor = &style->cursor_hover;
25058 text.text = style->text_hover;
25060 background = &style->hover;
25061 cursor = &style->cursor_hover;
25062 text.text = style->text_active;
25064 background = &style->normal;
25065 cursor = &style->cursor_normal;
25066 text.text = style->text_normal;
25069 text.text = nk_rgb_factor(text.text, style->color_factor);
25070 text.padding.x = 0;
25071 text.padding.y = 0;
25072 text.background = style->text_background;
25073 nk_widget_text(out, *label,
string, len, &text, text_alignment, font);
25076 if (background->type == NK_STYLE_ITEM_COLOR) {
25077 nk_fill_rect(out, *selector, 0, nk_rgb_factor(style->border_color, style->color_factor));
25078 nk_fill_rect(out, nk_shrink_rect(*selector, style->border), 0, nk_rgb_factor(background->data.color, style->color_factor));
25079 }
else nk_draw_image(out, *selector, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
25081 if (cursor->type == NK_STYLE_ITEM_IMAGE)
25082 nk_draw_image(out, *cursors, &cursor->data.image, nk_rgb_factor(nk_white, style->color_factor));
25083 else nk_fill_rect(out, *cursors, 0, cursor->data.color);
25090 const struct nk_rect *cursors,
const char *
string,
int len,
25091 const struct nk_user_font *font, nk_flags text_alignment)
25095 struct nk_text text;
25099 background = &style->hover;
25100 cursor = &style->cursor_hover;
25101 text.text = style->text_hover;
25103 background = &style->hover;
25104 cursor = &style->cursor_hover;
25105 text.text = style->text_active;
25107 background = &style->normal;
25108 cursor = &style->cursor_normal;
25109 text.text = style->text_normal;
25112 text.text = nk_rgb_factor(text.text, style->color_factor);
25113 text.padding.x = 0;
25114 text.padding.y = 0;
25115 text.background = style->text_background;
25116 nk_widget_text(out, *label,
string, len, &text, text_alignment, font);
25119 if (background->type == NK_STYLE_ITEM_COLOR) {
25120 nk_fill_circle(out, *selector, nk_rgb_factor(style->border_color, style->color_factor));
25121 nk_fill_circle(out, nk_shrink_rect(*selector, style->border), nk_rgb_factor(background->data.color, style->color_factor));
25122 }
else nk_draw_image(out, *selector, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
25124 if (cursor->type == NK_STYLE_ITEM_IMAGE)
25125 nk_draw_image(out, *cursors, &cursor->data.image, nk_rgb_factor(nk_white, style->color_factor));
25126 else nk_fill_circle(out, *cursors, cursor->data.color);
25130nk_do_toggle(nk_flags *state,
25132 nk_bool *active,
const char *str,
int len,
enum nk_toggle_type type,
25134 const struct nk_user_font *font, nk_flags widget_alignment, nk_flags text_alignment)
25145 if (!out || !style || !font || !active)
25148 r.w = NK_MAX(r.w, font->
height + 2 * style->padding.x);
25149 r.h = NK_MAX(r.h, font->
height + 2 * style->padding.y);
25152 bounds.x = r.x - style->touch_padding.x;
25153 bounds.y = r.y - style->touch_padding.y;
25154 bounds.w = r.w + 2 * style->touch_padding.x;
25155 bounds.h = r.h + 2 * style->touch_padding.y;
25158 select.w = font->
height;
25159 select.h = select.w;
25161 if (widget_alignment & NK_WIDGET_ALIGN_RIGHT) {
25162 select.x = r.x + r.w - font->
height;
25166 label.w = r.w - select.w - style->spacing * 2;
25167 }
else if (widget_alignment & NK_WIDGET_ALIGN_CENTERED) {
25168 select.x = r.x + (r.w - select.w) / 2;
25172 label.w = (r.w - select.w - style->spacing * 2) / 2;
25177 label.x = select.x + select.w + style->spacing;
25178 label.w = NK_MAX(r.x + r.w, label.x) - label.x;
25181 if (widget_alignment & NK_WIDGET_ALIGN_TOP) {
25183 }
else if (widget_alignment & NK_WIDGET_ALIGN_BOTTOM) {
25184 select.y = r.y + r.h - select.h - 2 * style->padding.y;
25186 select.y = r.y + r.h/2.0f - select.h/2.0f;
25189 label.y = select.y;
25190 label.h = select.w;
25193 cursor.x = select.x + style->padding.x + style->border;
25194 cursor.y = select.y + style->padding.y + style->border;
25195 cursor.w = select.w - (2 * style->padding.x + 2 * style->border);
25196 cursor.h = select.h - (2 * style->padding.y + 2 * style->border);
25199 was_active = *active;
25200 *active = nk_toggle_behavior(in, bounds, state, *active);
25203 if (style->draw_begin)
25204 style->draw_begin(out, style->userdata);
25205 if (type == NK_TOGGLE_CHECK) {
25206 nk_draw_checkbox(out, *state, style, *active, &label, &select, &cursor, str, len, font, text_alignment);
25208 nk_draw_option(out, *state, style, *active, &label, &select, &cursor, str, len, font, text_alignment);
25210 if (style->draw_end)
25211 style->draw_end(out, style->userdata);
25212 return (was_active != *active);
25220nk_check_text(
struct nk_context *ctx,
const char *text,
int len, nk_bool active)
25231 NK_ASSERT(ctx->current);
25232 NK_ASSERT(ctx->current->layout);
25233 if (!ctx || !ctx->current || !ctx->current->layout)
25236 win = ctx->current;
25237 style = &ctx->style;
25238 layout = win->layout;
25240 state = nk_widget(&bounds, ctx);
25241 if (!state)
return active;
25243 nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &active,
25244 text, len, NK_TOGGLE_CHECK, &style->checkbox, in, style->font, NK_WIDGET_LEFT, NK_TEXT_LEFT);
25248nk_check_text_align(
struct nk_context *ctx,
const char *text,
int len, nk_bool active, nk_flags widget_alignment, nk_flags text_alignment)
25259 NK_ASSERT(ctx->current);
25260 NK_ASSERT(ctx->current->layout);
25261 if (!ctx || !ctx->current || !ctx->current->layout)
25264 win = ctx->current;
25265 style = &ctx->style;
25266 layout = win->layout;
25268 state = nk_widget(&bounds, ctx);
25269 if (!state)
return active;
25271 nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &active,
25272 text, len, NK_TOGGLE_CHECK, &style->checkbox, in, style->font, widget_alignment, text_alignment);
25276nk_check_flags_text(
struct nk_context *ctx,
const char *text,
int len,
25277 unsigned int flags,
unsigned int value)
25282 if (!ctx || !text)
return flags;
25283 old_active = (int)((flags & value) & value);
25284 if (nk_check_text(ctx, text, len, old_active))
25286 else flags &= ~value;
25290nk_checkbox_text(
struct nk_context *ctx,
const char *text,
int len, nk_bool *active)
25296 if (!ctx || !text || !active)
return 0;
25298 *active = nk_check_text(ctx, text, len, *active);
25299 return old_val != *active;
25302nk_checkbox_text_align(
struct nk_context *ctx,
const char *text,
int len, nk_bool *active, nk_flags widget_alignment, nk_flags text_alignment)
25308 if (!ctx || !text || !active)
return 0;
25310 *active = nk_check_text_align(ctx, text, len, *active, widget_alignment, text_alignment);
25311 return old_val != *active;
25314nk_checkbox_flags_text(
struct nk_context *ctx,
const char *text,
int len,
25315 unsigned int *flags,
unsigned int value)
25321 if (!ctx || !text || !flags)
return 0;
25323 active = (int)((*flags & value) & value);
25324 if (nk_checkbox_text(ctx, text, len, &active)) {
25325 if (active) *flags |= value;
25326 else *flags &= ~value;
25331NK_API nk_bool nk_check_label(
struct nk_context *ctx,
const char *label, nk_bool active)
25333 return nk_check_text(ctx, label, nk_strlen(label), active);
25335NK_API
unsigned int nk_check_flags_label(
struct nk_context *ctx,
const char *label,
25336 unsigned int flags,
unsigned int value)
25338 return nk_check_flags_text(ctx, label, nk_strlen(label), flags, value);
25340NK_API nk_bool nk_checkbox_label(
struct nk_context *ctx,
const char *label, nk_bool *active)
25342 return nk_checkbox_text(ctx, label, nk_strlen(label), active);
25344NK_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)
25346 return nk_checkbox_text_align(ctx, label, nk_strlen(label), active, widget_alignment, text_alignment);
25348NK_API nk_bool nk_checkbox_flags_label(
struct nk_context *ctx,
const char *label,
25349 unsigned int *flags,
unsigned int value)
25351 return nk_checkbox_flags_text(ctx, label, nk_strlen(label), flags, value);
25359nk_option_text(
struct nk_context *ctx,
const char *text,
int len, nk_bool is_active)
25370 NK_ASSERT(ctx->current);
25371 NK_ASSERT(ctx->current->layout);
25372 if (!ctx || !ctx->current || !ctx->current->layout)
25375 win = ctx->current;
25376 style = &ctx->style;
25377 layout = win->layout;
25379 state = nk_widget(&bounds, ctx);
25380 if (!state)
return (
int)state;
25382 nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &is_active,
25383 text, len, NK_TOGGLE_OPTION, &style->option, in, style->font, NK_WIDGET_LEFT, NK_TEXT_LEFT);
25387nk_option_text_align(
struct nk_context *ctx,
const char *text,
int len, nk_bool is_active, nk_flags widget_alignment, nk_flags text_alignment)
25398 NK_ASSERT(ctx->current);
25399 NK_ASSERT(ctx->current->layout);
25400 if (!ctx || !ctx->current || !ctx->current->layout)
25403 win = ctx->current;
25404 style = &ctx->style;
25405 layout = win->layout;
25407 state = nk_widget(&bounds, ctx);
25408 if (!state)
return (
int)state;
25410 nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &is_active,
25411 text, len, NK_TOGGLE_OPTION, &style->option, in, style->font, widget_alignment, text_alignment);
25415nk_radio_text(
struct nk_context *ctx,
const char *text,
int len, nk_bool *active)
25421 if (!ctx || !text || !active)
return 0;
25422 old_value = *active;
25423 *active = nk_option_text(ctx, text, len, old_value);
25424 return old_value != *active;
25427nk_radio_text_align(
struct nk_context *ctx,
const char *text,
int len, nk_bool *active, nk_flags widget_alignment, nk_flags text_alignment)
25433 if (!ctx || !text || !active)
return 0;
25434 old_value = *active;
25435 *active = nk_option_text_align(ctx, text, len, old_value, widget_alignment, text_alignment);
25436 return old_value != *active;
25439nk_option_label(
struct nk_context *ctx,
const char *label, nk_bool active)
25441 return nk_option_text(ctx, label, nk_strlen(label), active);
25444nk_option_label_align(
struct nk_context *ctx,
const char *label, nk_bool active, nk_flags widget_alignment, nk_flags text_alignment)
25446 return nk_option_text_align(ctx, label, nk_strlen(label), active, widget_alignment, text_alignment);
25449nk_radio_label(
struct nk_context *ctx,
const char *label, nk_bool *active)
25451 return nk_radio_text(ctx, label, nk_strlen(label), active);
25454nk_radio_label_align(
struct nk_context *ctx,
const char *label, nk_bool *active, nk_flags widget_alignment, nk_flags text_alignment)
25456 return nk_radio_text_align(ctx, label, nk_strlen(label), active, widget_alignment, text_alignment);
25471 const struct nk_rect *bounds,
25472 const struct nk_rect *icon,
const struct nk_image *img,
enum nk_symbol_type sym,
25473 const char *
string,
int len, nk_flags align,
const struct nk_user_font *font)
25476 struct nk_text text;
25477 text.padding = style->padding;
25482 background = &style->pressed;
25483 text.text = style->text_pressed;
25485 background = &style->hover;
25486 text.text = style->text_hover;
25488 background = &style->normal;
25489 text.text = style->text_normal;
25493 background = &style->pressed_active;
25494 text.text = style->text_pressed_active;
25496 background = &style->hover_active;
25497 text.text = style->text_hover_active;
25499 background = &style->normal_active;
25500 text.text = style->text_normal_active;
25504 text.text = nk_rgb_factor(text.text, style->color_factor);
25507 switch (background->type) {
25508 case NK_STYLE_ITEM_IMAGE:
25509 text.background = nk_rgba(0, 0, 0, 0);
25510 nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
25512 case NK_STYLE_ITEM_NINE_SLICE:
25513 text.background = nk_rgba(0, 0, 0, 0);
25514 nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor));
25516 case NK_STYLE_ITEM_COLOR:
25517 text.background = background->data.color;
25518 nk_fill_rect(out, *bounds, style->rounding, background->data.color);
25522 if (img)
nk_draw_image(out, *icon, img, nk_rgb_factor(nk_white, style->color_factor));
25523 else nk_draw_symbol(out, sym, *icon, text.background, text.text, 1, font);
25525 nk_widget_text(out, *bounds,
string, len, &text, align, font);
25529 struct nk_rect bounds,
const char *str,
int len, nk_flags align, nk_bool *value,
25544 if (!state || !out || !str || !len || !value || !style || !font)
return 0;
25545 old_value = *value;
25548 touch.x = bounds.x - style->touch_padding.x;
25549 touch.y = bounds.y - style->touch_padding.y;
25550 touch.w = bounds.w + style->touch_padding.x * 2;
25551 touch.h = bounds.h + style->touch_padding.y * 2;
25554 if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT))
25555 *value = !(*value);
25558 if (style->draw_begin) style->draw_begin(out, style->userdata);
25559 nk_draw_selectable(out, *state, style, *value, &bounds, 0,0,NK_SYMBOL_NONE, str, len, align, font);
25560 if (style->draw_end) style->draw_end(out, style->userdata);
25561 return old_value != *value;
25565 struct nk_rect bounds,
const char *str,
int len, nk_flags align, nk_bool *value,
25581 if (!state || !out || !str || !len || !value || !style || !font)
return 0;
25582 old_value = *value;
25585 touch.x = bounds.x - style->touch_padding.x;
25586 touch.y = bounds.y - style->touch_padding.y;
25587 touch.w = bounds.w + style->touch_padding.x * 2;
25588 touch.h = bounds.h + style->touch_padding.y * 2;
25589 if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT))
25590 *value = !(*value);
25592 icon.y = bounds.y + style->padding.y;
25593 icon.w = icon.h = bounds.h - 2 * style->padding.y;
25594 if (align & NK_TEXT_ALIGN_LEFT) {
25595 icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w);
25596 icon.x = NK_MAX(icon.x, 0);
25597 }
else icon.x = bounds.x + 2 * style->padding.x;
25599 icon.x += style->image_padding.x;
25600 icon.y += style->image_padding.y;
25601 icon.w -= 2 * style->image_padding.x;
25602 icon.h -= 2 * style->image_padding.y;
25605 if (style->draw_begin) style->draw_begin(out, style->userdata);
25606 nk_draw_selectable(out, *state, style, *value, &bounds, &icon, img, NK_SYMBOL_NONE, str, len, align, font);
25607 if (style->draw_end) style->draw_end(out, style->userdata);
25608 return old_value != *value;
25612 struct nk_rect bounds,
const char *str,
int len, nk_flags align, nk_bool *value,
25628 if (!state || !out || !str || !len || !value || !style || !font)
return 0;
25629 old_value = *value;
25632 touch.x = bounds.x - style->touch_padding.x;
25633 touch.y = bounds.y - style->touch_padding.y;
25634 touch.w = bounds.w + style->touch_padding.x * 2;
25635 touch.h = bounds.h + style->touch_padding.y * 2;
25636 if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT))
25637 *value = !(*value);
25639 icon.y = bounds.y + style->padding.y;
25640 icon.w = icon.h = bounds.h - 2 * style->padding.y;
25641 if (align & NK_TEXT_ALIGN_LEFT) {
25642 icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w);
25643 icon.x = NK_MAX(icon.x, 0);
25644 }
else icon.x = bounds.x + 2 * style->padding.x;
25646 icon.x += style->image_padding.x;
25647 icon.y += style->image_padding.y;
25648 icon.w -= 2 * style->image_padding.x;
25649 icon.h -= 2 * style->image_padding.y;
25652 if (style->draw_begin) style->draw_begin(out, style->userdata);
25653 nk_draw_selectable(out, *state, style, *value, &bounds, &icon, 0, sym, str, len, align, font);
25654 if (style->draw_end) style->draw_end(out, style->userdata);
25655 return old_value != *value;
25659nk_selectable_text(
struct nk_context *ctx,
const char *str,
int len,
25660 nk_flags align, nk_bool *value)
25672 NK_ASSERT(ctx->current);
25673 NK_ASSERT(ctx->current->layout);
25674 if (!ctx || !ctx->current || !ctx->current->layout || !value)
25677 win = ctx->current;
25678 layout = win->layout;
25679 style = &ctx->style;
25681 state = nk_widget(&bounds, ctx);
25682 if (!state)
return 0;
25684 return nk_do_selectable(&ctx->last_widget_state, &win->buffer, bounds,
25685 str, len, align, value, &style->selectable, in, style->font);
25689 const char *str,
int len, nk_flags align, nk_bool *value)
25701 NK_ASSERT(ctx->current);
25702 NK_ASSERT(ctx->current->layout);
25703 if (!ctx || !ctx->current || !ctx->current->layout || !value)
25706 win = ctx->current;
25707 layout = win->layout;
25708 style = &ctx->style;
25710 state = nk_widget(&bounds, ctx);
25711 if (!state)
return 0;
25713 return nk_do_selectable_image(&ctx->last_widget_state, &win->buffer, bounds,
25714 str, len, align, value, &img, &style->selectable, in, style->font);
25717nk_selectable_symbol_text(
struct nk_context *ctx,
enum nk_symbol_type sym,
25718 const char *str,
int len, nk_flags align, nk_bool *value)
25730 NK_ASSERT(ctx->current);
25731 NK_ASSERT(ctx->current->layout);
25732 if (!ctx || !ctx->current || !ctx->current->layout || !value)
25735 win = ctx->current;
25736 layout = win->layout;
25737 style = &ctx->style;
25739 state = nk_widget(&bounds, ctx);
25740 if (!state)
return 0;
25742 return nk_do_selectable_symbol(&ctx->last_widget_state, &win->buffer, bounds,
25743 str, len, align, value, sym, &style->selectable, in, style->font);
25746nk_selectable_symbol_label(
struct nk_context *ctx,
enum nk_symbol_type sym,
25747 const char *title, nk_flags align, nk_bool *value)
25749 return nk_selectable_symbol_text(ctx, sym, title, nk_strlen(title), align, value);
25751NK_API nk_bool nk_select_text(
struct nk_context *ctx,
const char *str,
int len,
25752 nk_flags align, nk_bool value)
25754 nk_selectable_text(ctx, str, len, align, &value);
return value;
25756NK_API nk_bool nk_selectable_label(
struct nk_context *ctx,
const char *str, nk_flags align, nk_bool *value)
25758 return nk_selectable_text(ctx, str, nk_strlen(str), align, value);
25761 const char *str, nk_flags align, nk_bool *value)
25763 return nk_selectable_image_text(ctx, img, str, nk_strlen(str), align, value);
25765NK_API nk_bool nk_select_label(
struct nk_context *ctx,
const char *str, nk_flags align, nk_bool value)
25767 nk_selectable_text(ctx, str, nk_strlen(str), align, &value);
return value;
25770 const char *str, nk_flags align, nk_bool value)
25772 nk_selectable_image_text(ctx, img, str, nk_strlen(str), align, &value);
return value;
25775 const char *str,
int len, nk_flags align, nk_bool value)
25777 nk_selectable_image_text(ctx, img, str, len, align, &value);
return value;
25780nk_select_symbol_text(
struct nk_context *ctx,
enum nk_symbol_type sym,
25781 const char *title,
int title_len, nk_flags align, nk_bool value)
25783 nk_selectable_symbol_text(ctx, sym, title, title_len, align, &value);
return value;
25786nk_select_symbol_label(
struct nk_context *ctx,
enum nk_symbol_type sym,
25787 const char *title, nk_flags align, nk_bool value)
25789 return nk_select_symbol_text(ctx, sym, title, nk_strlen(title), align, value);
25802nk_slider_behavior(nk_flags *state,
struct nk_rect *logical_cursor,
25804 struct nk_rect bounds,
float slider_min,
float slider_max,
float slider_value,
25805 float slider_step,
float slider_steps)
25807 int left_mouse_down;
25808 int left_mouse_click_in_cursor;
25811 nk_widget_state_reset(state);
25812 left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
25813 left_mouse_click_in_cursor = in && nk_input_has_mouse_click_down_in_rect(in,
25814 NK_BUTTON_LEFT, *visual_cursor, nk_true);
25816 if (left_mouse_down && left_mouse_click_in_cursor) {
25818 const float d = in->mouse.pos.x - (visual_cursor->x+visual_cursor->w*0.5f);
25819 const float pxstep = bounds.w / slider_steps;
25823 if (NK_ABS(d) >= pxstep) {
25824 const float steps = (float)((
int)(NK_ABS(d) / pxstep));
25825 slider_value += (d > 0) ? (slider_step*steps) : -(slider_step*steps);
25826 slider_value = NK_CLAMP(slider_min, slider_value, slider_max);
25827 ratio = (slider_value - slider_min)/slider_step;
25828 logical_cursor->x = bounds.x + (logical_cursor->w * ratio);
25829 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = logical_cursor->x;
25834 if (nk_input_is_mouse_hovering_rect(in, bounds))
25837 !nk_input_is_mouse_prev_hovering_rect(in, bounds))
25839 else if (nk_input_is_mouse_prev_hovering_rect(in, bounds))
25841 return slider_value;
25846 const struct nk_rect *visual_cursor,
float min,
float value,
float max)
25861 background = &style->active;
25862 bar_color = style->bar_active;
25863 cursor = &style->cursor_active;
25865 background = &style->hover;
25866 bar_color = style->bar_hover;
25867 cursor = &style->cursor_hover;
25869 background = &style->normal;
25870 bar_color = style->bar_normal;
25871 cursor = &style->cursor_normal;
25876 bar.y = (visual_cursor->y + visual_cursor->h/2) - bounds->h/12;
25878 bar.h = bounds->h/6;
25881 fill.w = (visual_cursor->x + (visual_cursor->w/2.0f)) - bar.x;
25887 switch(background->type) {
25888 case NK_STYLE_ITEM_IMAGE:
25889 nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
25891 case NK_STYLE_ITEM_NINE_SLICE:
25892 nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor));
25894 case NK_STYLE_ITEM_COLOR:
25895 nk_fill_rect(out, *bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor));
25896 nk_stroke_rect(out, *bounds, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor));
25901 nk_fill_rect(out, bar, style->rounding, nk_rgb_factor(bar_color, style->color_factor));
25902 nk_fill_rect(out, fill, style->rounding, nk_rgb_factor(style->bar_filled, style->color_factor));
25905 if (cursor->type == NK_STYLE_ITEM_IMAGE)
25906 nk_draw_image(out, *visual_cursor, &cursor->data.image, nk_rgb_factor(nk_white, style->color_factor));
25908 nk_fill_circle(out, *visual_cursor, nk_rgb_factor(cursor->data.color, style->color_factor));
25911nk_do_slider(nk_flags *state,
25913 float min,
float val,
float max,
float step,
25917 float slider_range;
25920 float slider_value;
25921 float slider_steps;
25922 float cursor_offset;
25924 struct nk_rect visual_cursor;
25925 struct nk_rect logical_cursor;
25929 if (!out || !style)
25933 bounds.x = bounds.x + style->padding.x;
25934 bounds.y = bounds.y + style->padding.y;
25935 bounds.h = NK_MAX(bounds.h, 2*style->padding.y);
25936 bounds.w = NK_MAX(bounds.w, 2*style->padding.x + style->cursor_size.x);
25937 bounds.w -= 2 * style->padding.x;
25938 bounds.h -= 2 * style->padding.y;
25941 if (style->show_buttons) {
25944 button.y = bounds.y;
25945 button.w = bounds.h;
25946 button.h = bounds.h;
25949 button.x = bounds.x;
25950 if (nk_do_button_symbol(&ws, out, button, style->dec_symbol, NK_BUTTON_DEFAULT,
25951 &style->dec_button, in, font))
25955 button.x = (bounds.x + bounds.w) - button.w;
25956 if (nk_do_button_symbol(&ws, out, button, style->inc_symbol, NK_BUTTON_DEFAULT,
25957 &style->inc_button, in, font))
25960 bounds.x = bounds.x + button.w + style->spacing.x;
25961 bounds.w = bounds.w - (2*button.w + 2*style->spacing.x);
25965 bounds.x += style->cursor_size.x*0.5f;
25966 bounds.w -= style->cursor_size.x;
25969 slider_max = NK_MAX(min, max);
25970 slider_min = NK_MIN(min, max);
25971 slider_value = NK_CLAMP(slider_min, val, slider_max);
25972 slider_range = slider_max - slider_min;
25973 slider_steps = slider_range / step;
25974 cursor_offset = (slider_value - slider_min) / step;
25979 logical_cursor.h = bounds.h;
25980 logical_cursor.w = bounds.w / slider_steps;
25981 logical_cursor.x = bounds.x + (logical_cursor.w * cursor_offset);
25982 logical_cursor.y = bounds.y;
25984 visual_cursor.h = style->cursor_size.y;
25985 visual_cursor.w = style->cursor_size.x;
25986 visual_cursor.y = (bounds.y + bounds.h*0.5f) - visual_cursor.h*0.5f;
25987 visual_cursor.x = logical_cursor.x - visual_cursor.w*0.5f;
25989 slider_value = nk_slider_behavior(state, &logical_cursor, &visual_cursor,
25990 in, bounds, slider_min, slider_max, slider_value, step, slider_steps);
25991 visual_cursor.x = logical_cursor.x - visual_cursor.w*0.5f;
25994 if (style->draw_begin) style->draw_begin(out, style->userdata);
25995 nk_draw_slider(out, *state, style, &bounds, &visual_cursor, slider_min, slider_value, slider_max);
25996 if (style->draw_end) style->draw_end(out, style->userdata);
25997 return slider_value;
26000nk_slider_float(
struct nk_context *ctx,
float min_value,
float *value,
float max_value,
26014 NK_ASSERT(ctx->current);
26015 NK_ASSERT(ctx->current->layout);
26017 if (!ctx || !ctx->current || !ctx->current->layout || !value)
26020 win = ctx->current;
26021 style = &ctx->style;
26022 layout = win->layout;
26024 state = nk_widget(&bounds, ctx);
26025 if (!state)
return ret;
26028 old_value = *value;
26029 *value = nk_do_slider(&ctx->last_widget_state, &win->buffer, bounds, min_value,
26030 old_value, max_value, value_step, &style->slider, in, style->font);
26031 return (old_value > *value || old_value < *value);
26034nk_slide_float(
struct nk_context *ctx,
float min,
float val,
float max,
float step)
26036 nk_slider_float(ctx, min, &val, max, step);
return val;
26039nk_slide_int(
struct nk_context *ctx,
int min,
int val,
int max,
int step)
26041 float value = (float)val;
26042 nk_slider_float(ctx, (
float)min, &value, (
float)max, (
float)step);
26046nk_slider_int(
struct nk_context *ctx,
int min,
int *val,
int max,
int step)
26049 float value = (float)*val;
26050 ret = nk_slider_float(ctx, (
float)min, &value, (
float)max, (
float)step);
26066nk_knob_behavior(nk_flags *state,
struct nk_input *in,
26067 struct nk_rect bounds,
float knob_min,
float knob_max,
float knob_value,
26068 float knob_step,
float knob_steps,
26069 enum nk_heading zero_direction,
float dead_zone_percent)
26072 float angle = 0.0f;
26073 origin.x = bounds.x + (bounds.w / 2);
26074 origin.y = bounds.y + (bounds.h / 2);
26076 nk_widget_state_reset(state);
26080 in->mouse.buttons[NK_BUTTON_LEFT].down &&
26081 nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, bounds, nk_true)){
26083 const float direction_rads[4] = {
26091 angle = NK_ATAN2(in->mouse.pos.y - origin.y, in->mouse.pos.x - origin.x) + direction_rads[zero_direction];
26092 angle -= (angle > NK_PI * 2) ? NK_PI * 3 : NK_PI;
26095 angle *= 1.0f / (1.0f - dead_zone_percent);
26096 angle = NK_CLAMP(-NK_PI, angle, NK_PI);
26099 angle = (angle + NK_PI) / (NK_PI * 2);
26102 knob_value = knob_min + ( (int)(angle * knob_steps + (knob_step / 2)) ) * knob_step;
26103 knob_value = NK_CLAMP(knob_min, knob_value, knob_max);
26107 if (nk_input_is_mouse_hovering_rect(in, bounds)){
26110 if (in->mouse.scroll_delta.y > 0 ||
26111 (in->keyboard.keys[NK_KEY_UP].down && in->keyboard.keys[NK_KEY_UP].clicked)) {
26112 knob_value += knob_step;
26115 if (in->mouse.scroll_delta.y < 0 ||
26116 (in->keyboard.keys[NK_KEY_DOWN].down && in->keyboard.keys[NK_KEY_DOWN].clicked)) {
26117 knob_value -= knob_step;
26120 in->mouse.scroll_delta.y = 0;
26121 knob_value = NK_CLAMP(knob_min, knob_value, knob_max);
26124 !nk_input_is_mouse_prev_hovering_rect(in, bounds))
26126 else if (nk_input_is_mouse_prev_hovering_rect(in, bounds))
26133 const struct nk_style_knob *style,
const struct nk_rect *bounds,
float min,
float value,
float max,
26134 enum nk_heading zero_direction,
float dead_zone_percent)
26137 struct nk_color knob_color, cursor;
26144 background = &style->active;
26145 knob_color = style->knob_active;
26146 cursor = style->cursor_active;
26148 background = &style->hover;
26149 knob_color = style->knob_hover;
26150 cursor = style->cursor_hover;
26152 background = &style->normal;
26153 knob_color = style->knob_normal;
26154 cursor = style->cursor_normal;
26158 switch(background->type) {
26159 case NK_STYLE_ITEM_IMAGE:
26160 nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
26162 case NK_STYLE_ITEM_NINE_SLICE:
26163 nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor));
26165 case NK_STYLE_ITEM_COLOR:
26166 nk_fill_rect(out, *bounds, 0, nk_rgb_factor(background->data.color, style->color_factor));
26167 nk_stroke_rect(out, *bounds, 0, style->border, nk_rgb_factor(style->border_color, style->color_factor));
26172 nk_fill_circle(out, *bounds, nk_rgb_factor(knob_color, style->color_factor));
26173 if(style->knob_border > 0){
26174 struct nk_rect border_bounds = *bounds;
26175 border_bounds.x += style->knob_border / 2;
26176 border_bounds.y += style->knob_border / 2;
26177 border_bounds.w -= style->knob_border;
26178 border_bounds.h -= style->knob_border;
26179 nk_stroke_circle(out, border_bounds, style->knob_border, nk_rgb_factor(style->knob_border_color, style->color_factor));
26182 float half_circle_size = (bounds->w / 2);
26183 float angle = (value - min) / (max - min);
26184 float alive_zone = 1.0f - dead_zone_percent;
26185 struct nk_vec2 cursor_start, cursor_end;
26186 const float direction_rads[4] = {
26193 angle = (angle * alive_zone) + (dead_zone_percent / 2);
26196 angle *= NK_PI * 2;
26199 angle += direction_rads[zero_direction];
26200 if(angle > NK_PI * 2)
26201 angle -= NK_PI * 2;
26203 cursor_start.x = bounds->x + half_circle_size + (angle > NK_PI);
26204 cursor_start.y = bounds->y + half_circle_size + (angle < NK_PI_HALF || angle > (NK_PI * 1.5f));
26206 cursor_end.x = cursor_start.x + (half_circle_size * NK_COS(angle));
26207 cursor_end.y = cursor_start.y + (half_circle_size * NK_SIN(angle));
26210 cursor_start.x = (cursor_start.x + cursor_end.x) / 2;
26211 cursor_start.y = (cursor_start.y + cursor_end.y) / 2;
26214 nk_stroke_line(out, cursor_start.x, cursor_start.y, cursor_end.x, cursor_end.y, 2, nk_rgb_factor(cursor, style->color_factor));
26218nk_do_knob(nk_flags *state,
26220 float min,
float val,
float max,
float step,
26221 enum nk_heading zero_direction,
float dead_zone_percent,
26232 if (!out || !style)
26236 bounds.y = bounds.y + style->padding.y;
26237 bounds.x = bounds.x + style->padding.x;
26238 bounds.h = NK_MAX(bounds.h, 2*style->padding.y);
26239 bounds.w = NK_MAX(bounds.w, 2*style->padding.x);
26240 bounds.w -= 2 * style->padding.x;
26241 bounds.h -= 2 * style->padding.y;
26242 if(bounds.h < bounds.w){
26243 bounds.x += (bounds.w - bounds.h) / 2;
26244 bounds.w = bounds.h;
26248 knob_max = NK_MAX(min, max);
26249 knob_min = NK_MIN(min, max);
26250 knob_value = NK_CLAMP(knob_min, val, knob_max);
26251 knob_range = knob_max - knob_min;
26252 knob_steps = knob_range / step;
26254 knob_value = nk_knob_behavior(state, in, bounds, knob_min, knob_max, knob_value, step, knob_steps, zero_direction, dead_zone_percent);
26257 if (style->draw_begin) style->draw_begin(out, style->userdata);
26258 nk_draw_knob(out, *state, style, &bounds, knob_min, knob_value, knob_max, zero_direction, dead_zone_percent);
26259 if (style->draw_end) style->draw_end(out, style->userdata);
26263nk_knob_float(
struct nk_context *ctx,
float min_value,
float *value,
float max_value,
26264 float value_step,
enum nk_heading zero_direction,
float dead_zone_degrees)
26277 NK_ASSERT(ctx->current);
26278 NK_ASSERT(ctx->current->layout);
26280 NK_ASSERT(NK_BETWEEN(dead_zone_degrees, 0.0f, 360.0f));
26281 if (!ctx || !ctx->current || !ctx->current->layout || !value)
26284 win = ctx->current;
26285 style = &ctx->style;
26286 layout = win->layout;
26288 state = nk_widget(&bounds, ctx);
26289 if (!state)
return ret;
26292 old_value = *value;
26293 *value = nk_do_knob(&ctx->last_widget_state, &win->buffer, bounds, min_value,
26294 old_value, max_value, value_step, zero_direction, dead_zone_degrees / 360.0f, &style->knob, in);
26296 return (old_value > *value || old_value < *value);
26299nk_knob_int(
struct nk_context *ctx,
int min,
int *val,
int max,
int step,
26300 enum nk_heading zero_direction,
float dead_zone_degrees)
26303 float value = (float)*val;
26304 ret = nk_knob_float(ctx, (
float)min, &value, (
float)max, (
float)step, zero_direction, dead_zone_degrees);
26318nk_progress_behavior(nk_flags *state,
struct nk_input *in,
26319 struct nk_rect r,
struct nk_rect cursor, nk_size max, nk_size value, nk_bool modifiable)
26321 int left_mouse_down = 0;
26322 int left_mouse_click_in_cursor = 0;
26324 nk_widget_state_reset(state);
26325 if (!in || !modifiable)
return value;
26326 left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
26327 left_mouse_click_in_cursor = in && nk_input_has_mouse_click_down_in_rect(in,
26328 NK_BUTTON_LEFT, cursor, nk_true);
26329 if (nk_input_is_mouse_hovering_rect(in, r))
26332 if (in && left_mouse_down && left_mouse_click_in_cursor) {
26333 if (left_mouse_down && left_mouse_click_in_cursor) {
26334 float ratio = NK_MAX(0, (
float)(in->mouse.pos.x - cursor.x)) / (float)cursor.w;
26335 value = (nk_size)NK_CLAMP(0, (
float)max * ratio, (float)max);
26336 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = cursor.x + cursor.w/2.0f;
26343 else if (nk_input_is_mouse_prev_hovering_rect(in, r))
26350 const struct nk_rect *scursor, nk_size value, nk_size max)
26360 background = &style->active;
26361 cursor = &style->cursor_active;
26363 background = &style->hover;
26364 cursor = &style->cursor_hover;
26366 background = &style->normal;
26367 cursor = &style->cursor_normal;
26371 switch(background->type) {
26372 case NK_STYLE_ITEM_IMAGE:
26373 nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
26375 case NK_STYLE_ITEM_NINE_SLICE:
26376 nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor));
26378 case NK_STYLE_ITEM_COLOR:
26379 nk_fill_rect(out, *bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor));
26380 nk_stroke_rect(out, *bounds, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor));
26385 switch(cursor->type) {
26386 case NK_STYLE_ITEM_IMAGE:
26387 nk_draw_image(out, *scursor, &cursor->data.image, nk_rgb_factor(nk_white, style->color_factor));
26389 case NK_STYLE_ITEM_NINE_SLICE:
26390 nk_draw_nine_slice(out, *scursor, &cursor->data.slice, nk_rgb_factor(nk_white, style->color_factor));
26392 case NK_STYLE_ITEM_COLOR:
26393 nk_fill_rect(out, *scursor, style->rounding, nk_rgb_factor(cursor->data.color, style->color_factor));
26394 nk_stroke_rect(out, *scursor, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor));
26399nk_do_progress(nk_flags *state,
26401 nk_size value, nk_size max, nk_bool modifiable,
26405 nk_size prog_value;
26410 if (!out || !style)
return 0;
26413 cursor.w = NK_MAX(bounds.w, 2 * style->padding.x + 2 * style->border);
26414 cursor.h = NK_MAX(bounds.h, 2 * style->padding.y + 2 * style->border);
26415 cursor = nk_pad_rect(bounds,
nk_vec2(style->padding.x + style->border, style->padding.y + style->border));
26416 prog_scale = (float)value / (
float)max;
26419 prog_value = NK_MIN(value, max);
26420 prog_value = nk_progress_behavior(state, in, bounds, cursor,max, prog_value, modifiable);
26421 cursor.w = cursor.w * prog_scale;
26424 if (style->draw_begin) style->draw_begin(out, style->userdata);
26425 nk_draw_progress(out, *state, style, &bounds, &cursor, value, max);
26426 if (style->draw_end) style->draw_end(out, style->userdata);
26430nk_progress(
struct nk_context *ctx, nk_size *cur, nk_size max, nk_bool is_modifyable)
26443 NK_ASSERT(ctx->current);
26444 NK_ASSERT(ctx->current->layout);
26445 if (!ctx || !ctx->current || !ctx->current->layout || !cur)
26448 win = ctx->current;
26449 style = &ctx->style;
26450 layout = win->layout;
26451 state = nk_widget(&bounds, ctx);
26452 if (!state)
return 0;
26456 *cur = nk_do_progress(&ctx->last_widget_state, &win->buffer, bounds,
26457 *cur, max, is_modifyable, &style->progress, in);
26458 return (*cur != old_value);
26461nk_prog(
struct nk_context *ctx, nk_size cur, nk_size max, nk_bool modifyable)
26463 nk_progress(ctx, &cur, max, modifyable);
26477nk_scrollbar_behavior(nk_flags *state,
struct nk_input *in,
26478 int has_scrolling,
const struct nk_rect *scroll,
26480 const struct nk_rect *empty1,
float scroll_offset,
26481 float target,
float scroll_step,
enum nk_orientation o)
26484 int left_mouse_down;
26485 unsigned int left_mouse_clicked;
26486 int left_mouse_click_in_cursor;
26487 float scroll_delta;
26489 nk_widget_state_reset(state);
26490 if (!in)
return scroll_offset;
26492 left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
26493 left_mouse_clicked = in->mouse.buttons[NK_BUTTON_LEFT].clicked;
26494 left_mouse_click_in_cursor = nk_input_has_mouse_click_down_in_rect(in,
26495 NK_BUTTON_LEFT, *cursor, nk_true);
26496 if (nk_input_is_mouse_hovering_rect(in, *scroll))
26499 scroll_delta = (o == NK_VERTICAL) ? in->mouse.scroll_delta.y: in->mouse.scroll_delta.x;
26500 if (left_mouse_down && left_mouse_click_in_cursor && !left_mouse_clicked) {
26502 float pixel, delta;
26504 if (o == NK_VERTICAL) {
26506 pixel = in->mouse.delta.y;
26507 delta = (pixel / scroll->h) * target;
26508 scroll_offset = NK_CLAMP(0, scroll_offset + delta, target - scroll->h);
26509 cursor_y = scroll->y + ((scroll_offset/target) * scroll->h);
26510 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y = cursor_y + cursor->h/2.0f;
26513 pixel = in->mouse.delta.x;
26514 delta = (pixel / scroll->w) * target;
26515 scroll_offset = NK_CLAMP(0, scroll_offset + delta, target - scroll->w);
26516 cursor_x = scroll->x + ((scroll_offset/target) * scroll->w);
26517 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = cursor_x + cursor->w/2.0f;
26519 }
else if ((nk_input_is_key_pressed(in, NK_KEY_SCROLL_UP) && o == NK_VERTICAL && has_scrolling)||
26520 nk_button_behavior(&ws, *empty0, in, NK_BUTTON_DEFAULT)) {
26522 if (o == NK_VERTICAL)
26523 scroll_offset = NK_MAX(0, scroll_offset - scroll->h);
26524 else scroll_offset = NK_MAX(0, scroll_offset - scroll->w);
26525 }
else if ((nk_input_is_key_pressed(in, NK_KEY_SCROLL_DOWN) && o == NK_VERTICAL && has_scrolling) ||
26526 nk_button_behavior(&ws, *empty1, in, NK_BUTTON_DEFAULT)) {
26528 if (o == NK_VERTICAL)
26529 scroll_offset = NK_MIN(scroll_offset + scroll->h, target - scroll->h);
26530 else scroll_offset = NK_MIN(scroll_offset + scroll->w, target - scroll->w);
26531 }
else if (has_scrolling) {
26532 if ((scroll_delta < 0 || (scroll_delta > 0))) {
26534 scroll_offset = scroll_offset + scroll_step * (-scroll_delta);
26535 if (o == NK_VERTICAL)
26536 scroll_offset = NK_CLAMP(0, scroll_offset, target - scroll->h);
26537 else scroll_offset = NK_CLAMP(0, scroll_offset, target - scroll->w);
26538 }
else if (nk_input_is_key_pressed(in, NK_KEY_SCROLL_START)) {
26540 if (o == NK_VERTICAL) scroll_offset = 0;
26541 }
else if (nk_input_is_key_pressed(in, NK_KEY_SCROLL_END)) {
26543 if (o == NK_VERTICAL) scroll_offset = target - scroll->h;
26548 else if (nk_input_is_mouse_prev_hovering_rect(in, *scroll))
26550 return scroll_offset;
26555 const struct nk_rect *scroll)
26562 background = &style->active;
26563 cursor = &style->cursor_active;
26565 background = &style->hover;
26566 cursor = &style->cursor_hover;
26568 background = &style->normal;
26569 cursor = &style->cursor_normal;
26573 switch (background->type) {
26574 case NK_STYLE_ITEM_IMAGE:
26575 nk_draw_image(out, *bounds, &background->data.image, nk_white);
26577 case NK_STYLE_ITEM_NINE_SLICE:
26578 nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_white);
26580 case NK_STYLE_ITEM_COLOR:
26581 nk_fill_rect(out, *bounds, style->rounding, background->data.color);
26582 nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color);
26587 switch (cursor->type) {
26588 case NK_STYLE_ITEM_IMAGE:
26589 nk_draw_image(out, *scroll, &cursor->data.image, nk_white);
26591 case NK_STYLE_ITEM_NINE_SLICE:
26592 nk_draw_nine_slice(out, *scroll, &cursor->data.slice, nk_white);
26594 case NK_STYLE_ITEM_COLOR:
26595 nk_fill_rect(out, *scroll, style->rounding_cursor, cursor->data.color);
26596 nk_stroke_rect(out, *scroll, style->rounding_cursor, style->border_cursor, style->cursor_border_color);
26601nk_do_scrollbarv(nk_flags *state,
26603 float offset,
float target,
float step,
float button_pixel_inc,
26612 float scroll_offset;
26614 float scroll_ratio;
26619 if (!out || !style)
return 0;
26621 scroll.w = NK_MAX(scroll.w, 1);
26622 scroll.h = NK_MAX(scroll.h, 0);
26623 if (target <= scroll.h)
return 0;
26626 if (style->show_buttons) {
26631 button.x = scroll.x;
26632 button.w = scroll.w;
26633 button.h = scroll.w;
26635 scroll_h = NK_MAX(scroll.h - 2 * button.h,0);
26636 scroll_step = NK_MIN(step, button_pixel_inc);
26639 button.y = scroll.y;
26640 if (nk_do_button_symbol(&ws, out, button, style->dec_symbol,
26641 NK_BUTTON_REPEATER, &style->dec_button, in, font))
26642 offset = offset - scroll_step;
26645 button.y = scroll.y + scroll.h - button.h;
26646 if (nk_do_button_symbol(&ws, out, button, style->inc_symbol,
26647 NK_BUTTON_REPEATER, &style->inc_button, in, font))
26648 offset = offset + scroll_step;
26650 scroll.y = scroll.y + button.h;
26651 scroll.h = scroll_h;
26655 scroll_step = NK_MIN(step, scroll.h);
26656 scroll_offset = NK_CLAMP(0, offset, target - scroll.h);
26657 scroll_ratio = scroll.h / target;
26658 scroll_off = scroll_offset / target;
26661 cursor.h = NK_MAX((scroll_ratio * scroll.h) - (2*style->border + 2*style->padding.y), 0);
26662 cursor.y = scroll.y + (scroll_off * scroll.h) + style->border + style->padding.y;
26663 cursor.w = scroll.w - (2 * style->border + 2 * style->padding.x);
26664 cursor.x = scroll.x + style->border + style->padding.x;
26667 empty_north.x = scroll.x;
26668 empty_north.y = scroll.y;
26669 empty_north.w = scroll.w;
26670 empty_north.h = NK_MAX(cursor.y - scroll.y, 0);
26672 empty_south.x = scroll.x;
26673 empty_south.y = cursor.y + cursor.h;
26674 empty_south.w = scroll.w;
26675 empty_south.h = NK_MAX((scroll.y + scroll.h) - (cursor.y + cursor.h), 0);
26678 scroll_offset = nk_scrollbar_behavior(state, in, has_scrolling, &scroll, &cursor,
26679 &empty_north, &empty_south, scroll_offset, target, scroll_step, NK_VERTICAL);
26680 scroll_off = scroll_offset / target;
26681 cursor.y = scroll.y + (scroll_off * scroll.h) + style->border_cursor + style->padding.y;
26684 if (style->draw_begin) style->draw_begin(out, style->userdata);
26685 nk_draw_scrollbar(out, *state, style, &scroll, &cursor);
26686 if (style->draw_end) style->draw_end(out, style->userdata);
26687 return scroll_offset;
26690nk_do_scrollbarh(nk_flags *state,
26692 float offset,
float target,
float step,
float button_pixel_inc,
26701 float scroll_offset;
26703 float scroll_ratio;
26707 if (!out || !style)
return 0;
26710 scroll.h = NK_MAX(scroll.h, 1);
26711 scroll.w = NK_MAX(scroll.w, 2 * scroll.h);
26712 if (target <= scroll.w)
return 0;
26715 if (style->show_buttons) {
26719 button.y = scroll.y;
26720 button.w = scroll.h;
26721 button.h = scroll.h;
26723 scroll_w = scroll.w - 2 * button.w;
26724 scroll_step = NK_MIN(step, button_pixel_inc);
26727 button.x = scroll.x;
26728 if (nk_do_button_symbol(&ws, out, button, style->dec_symbol,
26729 NK_BUTTON_REPEATER, &style->dec_button, in, font))
26730 offset = offset - scroll_step;
26733 button.x = scroll.x + scroll.w - button.w;
26734 if (nk_do_button_symbol(&ws, out, button, style->inc_symbol,
26735 NK_BUTTON_REPEATER, &style->inc_button, in, font))
26736 offset = offset + scroll_step;
26738 scroll.x = scroll.x + button.w;
26739 scroll.w = scroll_w;
26743 scroll_step = NK_MIN(step, scroll.w);
26744 scroll_offset = NK_CLAMP(0, offset, target - scroll.w);
26745 scroll_ratio = scroll.w / target;
26746 scroll_off = scroll_offset / target;
26749 cursor.w = (scroll_ratio * scroll.w) - (2*style->border + 2*style->padding.x);
26750 cursor.x = scroll.x + (scroll_off * scroll.w) + style->border + style->padding.x;
26751 cursor.h = scroll.h - (2 * style->border + 2 * style->padding.y);
26752 cursor.y = scroll.y + style->border + style->padding.y;
26755 empty_west.x = scroll.x;
26756 empty_west.y = scroll.y;
26757 empty_west.w = cursor.x - scroll.x;
26758 empty_west.h = scroll.h;
26760 empty_east.x = cursor.x + cursor.w;
26761 empty_east.y = scroll.y;
26762 empty_east.w = (scroll.x + scroll.w) - (cursor.x + cursor.w);
26763 empty_east.h = scroll.h;
26766 scroll_offset = nk_scrollbar_behavior(state, in, has_scrolling, &scroll, &cursor,
26767 &empty_west, &empty_east, scroll_offset, target, scroll_step, NK_HORIZONTAL);
26768 scroll_off = scroll_offset / target;
26769 cursor.x = scroll.x + (scroll_off * scroll.w);
26772 if (style->draw_begin) style->draw_begin(out, style->userdata);
26773 nk_draw_scrollbar(out, *state, style, &scroll, &cursor);
26774 if (style->draw_end) style->draw_end(out, style->userdata);
26775 return scroll_offset;
26788struct nk_text_find {
26791 int first_char, length;
26795struct nk_text_edit_row {
26798 float baseline_y_delta;
26806NK_INTERN
void nk_textedit_makeundo_delete(
struct nk_text_edit*,
int,
int);
26807NK_INTERN
void nk_textedit_makeundo_insert(
struct nk_text_edit*,
int,
int);
26808NK_INTERN
void nk_textedit_makeundo_replace(
struct nk_text_edit*,
int,
int,
int);
26809#define NK_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
26812nk_textedit_get_width(
const struct nk_text_edit *edit,
int line_start,
int char_id,
26816 nk_rune unicode = 0;
26817 const char *str = nk_str_at_const(&edit->string, line_start + char_id, &unicode, &len);
26818 return font->
width(font->userdata, font->
height, str, len);
26821nk_textedit_layout_row(
struct nk_text_edit_row *r,
struct nk_text_edit *edit,
26822 int line_start_id,
float row_height,
const struct nk_user_font *font)
26827 const char *remaining;
26828 int len = nk_str_len_char(&edit->string);
26829 const char *end = nk_str_get_const(&edit->string) + len;
26830 const char *text = nk_str_at_const(&edit->string, line_start_id, &unicode, &l);
26831 const struct nk_vec2 size = nk_text_calculate_text_bounds(font,
26832 text, (
int)(end - text), row_height, &remaining, 0, &glyphs, NK_STOP_ON_NEW_LINE);
26836 r->baseline_y_delta = size.y;
26839 r->num_chars = glyphs;
26842nk_textedit_locate_coord(
struct nk_text_edit *edit,
float x,
float y,
26845 struct nk_text_edit_row r;
26846 int n = edit->string.len;
26847 float base_y = 0, prev_x;
26851 r.ymin = r.ymax = 0;
26856 nk_textedit_layout_row(&r, edit, i, row_height, font);
26857 if (r.num_chars <= 0)
26860 if (i==0 && y < base_y + r.ymin)
26863 if (y < base_y + r.ymax)
26867 base_y += r.baseline_y_delta;
26883 for (i=0; i < r.num_chars; ++i) {
26884 float w = nk_textedit_get_width(edit, k, i, font);
26885 if (x < prev_x+w) {
26886 if (x < prev_x+w/2)
26897 if (nk_str_rune_at(&edit->string, i+r.num_chars-1) ==
'\n')
26898 return i+r.num_chars-1;
26899 else return i+r.num_chars;
26902nk_textedit_click(
struct nk_text_edit *state,
float x,
float y,
26907 state->cursor = nk_textedit_locate_coord(state, x, y, font, row_height);
26908 state->select_start = state->cursor;
26909 state->select_end = state->cursor;
26910 state->has_preferred_x = 0;
26913nk_textedit_drag(
struct nk_text_edit *state,
float x,
float y,
26918 int p = nk_textedit_locate_coord(state, x, y, font, row_height);
26919 if (state->select_start == state->select_end)
26920 state->select_start = state->cursor;
26921 state->cursor = state->select_end = p;
26924nk_textedit_find_charpos(
struct nk_text_find *find,
struct nk_text_edit *state,
26925 int n,
int single_line,
const struct nk_user_font *font,
float row_height)
26929 struct nk_text_edit_row r;
26930 int prev_start = 0;
26931 int z = state->string.len;
26938 nk_textedit_layout_row(&r, state, 0, row_height, font);
26940 find->first_char = 0;
26946 nk_textedit_layout_row(&r, state, i, row_height, font);
26949 find->first_char = i;
26950 find->length = r.num_chars;
26954 find->height = r.ymax - r.ymin;
26955 find->prev_first = prev_start;
26963 nk_textedit_layout_row(&r, state, i, row_height, font);
26964 if (n < i + r.num_chars)
break;
26967 find->y += r.baseline_y_delta;
26970 find->first_char = first = i;
26971 find->length = r.num_chars;
26972 find->height = r.ymax - r.ymin;
26973 find->prev_first = prev_start;
26977 for (i=0; first+i < n; ++i)
26978 find->x += nk_textedit_get_width(state, first, i, font);
26984 int n = state->string.len;
26985 if (NK_TEXT_HAS_SELECTION(state)) {
26986 if (state->select_start > n) state->select_start = n;
26987 if (state->select_end > n) state->select_end = n;
26989 if (state->select_start == state->select_end)
26990 state->cursor = state->select_start;
26992 if (state->cursor > n) state->cursor = n;
26995nk_textedit_delete(
struct nk_text_edit *state,
int where,
int len)
26998 nk_textedit_makeundo_delete(state, where, len);
26999 nk_str_delete_runes(&state->string, where, len);
27000 state->has_preferred_x = 0;
27003nk_textedit_delete_selection(
struct nk_text_edit *state)
27006 nk_textedit_clamp(state);
27007 if (NK_TEXT_HAS_SELECTION(state)) {
27008 if (state->select_start < state->select_end) {
27009 nk_textedit_delete(state, state->select_start,
27010 state->select_end - state->select_start);
27011 state->select_end = state->cursor = state->select_start;
27013 nk_textedit_delete(state, state->select_end,
27014 state->select_start - state->select_end);
27015 state->select_start = state->cursor = state->select_end;
27017 state->has_preferred_x = 0;
27024 if (state->select_end < state->select_start) {
27025 int temp = state->select_end;
27026 state->select_end = state->select_start;
27027 state->select_start = temp;
27034 if (NK_TEXT_HAS_SELECTION(state)) {
27035 nk_textedit_sortselection(state);
27036 state->cursor = state->select_start;
27037 state->select_end = state->select_start;
27038 state->has_preferred_x = 0;
27045 if (NK_TEXT_HAS_SELECTION(state)) {
27046 nk_textedit_sortselection(state);
27047 nk_textedit_clamp(state);
27048 state->cursor = state->select_end;
27049 state->select_start = state->select_end;
27050 state->has_preferred_x = 0;
27054nk_is_word_boundary(
struct nk_text_edit *state,
int idx)
27058 if (idx < 0)
return 1;
27059 if (!nk_str_at_rune(&state->string, idx, &c, &len))
return 1;
27060#ifndef NK_IS_WORD_BOUNDARY
27061 return (c ==
' ' || c ==
'\t' || c ==
'\n' || c ==
'\r' || c ==
'\f' ||
27062 c ==
'\v' || c == 0x3000);
27064 return NK_IS_WORD_BOUNDARY(c);
27068nk_textedit_move_to_word_previous(
struct nk_text_edit *state)
27070 int c = state->cursor - 1;
27072 if (nk_is_word_boundary(state, c)) {
27073 while (c > 0 && nk_is_word_boundary(state, --c));
27075 while (!nk_is_word_boundary(state, --c));
27084nk_textedit_move_to_word_next(
struct nk_text_edit *state)
27086 const int len = state->string.len;
27087 int c = state->cursor;
27089 if (!nk_is_word_boundary(state, c)) {
27090 while (c < len && !nk_is_word_boundary(state, ++c));
27092 while (c < len && nk_is_word_boundary(state, ++c));
27100nk_textedit_prep_selection_at_cursor(
struct nk_text_edit *state)
27103 if (!NK_TEXT_HAS_SELECTION(state))
27104 state->select_start = state->select_end = state->cursor;
27105 else state->cursor = state->select_end;
27111 if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
27113 if (NK_TEXT_HAS_SELECTION(state)) {
27114 nk_textedit_delete_selection(state);
27115 state->has_preferred_x = 0;
27121nk_textedit_paste(
struct nk_text_edit *state,
char const *ctext,
int len)
27125 const char *text = (
const char *) ctext;
27126 if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
return 0;
27129 nk_textedit_clamp(state);
27130 nk_textedit_delete_selection(state);
27133 glyphs = nk_utf_len(ctext, len);
27134 if (nk_str_insert_text_char(&state->string, state->cursor, text, len)) {
27135 nk_textedit_makeundo_insert(state, state->cursor, glyphs);
27136 state->cursor += len;
27137 state->has_preferred_x = 0;
27141 if (state->undo.undo_point)
27142 --state->undo.undo_point;
27146nk_textedit_text(
struct nk_text_edit *state,
const char *text,
int total_len)
27154 if (!text || !total_len || state->mode == NK_TEXT_EDIT_MODE_VIEW)
return;
27156 glyph_len = nk_utf_decode(text, &unicode, total_len);
27157 while ((text_len < total_len) && glyph_len)
27160 if (unicode == 127)
goto next;
27162 if (unicode ==
'\n' && state->single_line)
goto next;
27164 if (state->filter && !state->filter(state, unicode))
goto next;
27166 if (!NK_TEXT_HAS_SELECTION(state) &&
27167 state->cursor < state->string.len)
27169 if (state->mode == NK_TEXT_EDIT_MODE_REPLACE) {
27170 nk_textedit_makeundo_replace(state, state->cursor, 1, 1);
27171 nk_str_delete_runes(&state->string, state->cursor, 1);
27173 if (nk_str_insert_text_utf8(&state->string, state->cursor,
27177 state->has_preferred_x = 0;
27180 nk_textedit_delete_selection(state);
27181 if (nk_str_insert_text_utf8(&state->string, state->cursor,
27184 nk_textedit_makeundo_insert(state, state->cursor, 1);
27185 state->cursor = NK_MIN(state->cursor + 1, state->string.len);
27186 state->has_preferred_x = 0;
27190 text_len += glyph_len;
27191 glyph_len = nk_utf_decode(text + text_len, &unicode, total_len-text_len);
27195nk_textedit_key(
struct nk_text_edit *state,
enum nk_keys key,
int shift_mod,
27211 case NK_KEY_TEXT_UNDO:
27212 nk_textedit_undo(state);
27213 state->has_preferred_x = 0;
27216 case NK_KEY_TEXT_REDO:
27217 nk_textedit_redo(state);
27218 state->has_preferred_x = 0;
27221 case NK_KEY_TEXT_SELECT_ALL:
27222 nk_textedit_select_all(state);
27223 state->has_preferred_x = 0;
27226 case NK_KEY_TEXT_INSERT_MODE:
27227 if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
27228 state->mode = NK_TEXT_EDIT_MODE_INSERT;
27230 case NK_KEY_TEXT_REPLACE_MODE:
27231 if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
27232 state->mode = NK_TEXT_EDIT_MODE_REPLACE;
27234 case NK_KEY_TEXT_RESET_MODE:
27235 if (state->mode == NK_TEXT_EDIT_MODE_INSERT ||
27236 state->mode == NK_TEXT_EDIT_MODE_REPLACE)
27237 state->mode = NK_TEXT_EDIT_MODE_VIEW;
27242 nk_textedit_clamp(state);
27243 nk_textedit_prep_selection_at_cursor(state);
27245 if (state->select_end > 0)
27246 --state->select_end;
27247 state->cursor = state->select_end;
27248 state->has_preferred_x = 0;
27252 if (NK_TEXT_HAS_SELECTION(state))
27253 nk_textedit_move_to_first(state);
27254 else if (state->cursor > 0)
27256 state->has_preferred_x = 0;
27261 nk_textedit_prep_selection_at_cursor(state);
27263 ++state->select_end;
27264 nk_textedit_clamp(state);
27265 state->cursor = state->select_end;
27266 state->has_preferred_x = 0;
27270 if (NK_TEXT_HAS_SELECTION(state))
27271 nk_textedit_move_to_last(state);
27272 else ++state->cursor;
27273 nk_textedit_clamp(state);
27274 state->has_preferred_x = 0;
27277 case NK_KEY_TEXT_WORD_LEFT:
27279 if( !NK_TEXT_HAS_SELECTION( state ) )
27280 nk_textedit_prep_selection_at_cursor(state);
27281 state->cursor = nk_textedit_move_to_word_previous(state);
27282 state->select_end = state->cursor;
27283 nk_textedit_clamp(state );
27285 if (NK_TEXT_HAS_SELECTION(state))
27286 nk_textedit_move_to_first(state);
27288 state->cursor = nk_textedit_move_to_word_previous(state);
27289 nk_textedit_clamp(state );
27293 case NK_KEY_TEXT_WORD_RIGHT:
27295 if( !NK_TEXT_HAS_SELECTION( state ) )
27296 nk_textedit_prep_selection_at_cursor(state);
27297 state->cursor = nk_textedit_move_to_word_next(state);
27298 state->select_end = state->cursor;
27299 nk_textedit_clamp(state);
27301 if (NK_TEXT_HAS_SELECTION(state))
27302 nk_textedit_move_to_last(state);
27304 state->cursor = nk_textedit_move_to_word_next(state);
27305 nk_textedit_clamp(state );
27309 case NK_KEY_DOWN: {
27310 struct nk_text_find find;
27311 struct nk_text_edit_row row;
27312 int i, sel = shift_mod;
27314 if (state->single_line) {
27316 key = NK_KEY_RIGHT;
27321 nk_textedit_prep_selection_at_cursor(state);
27322 else if (NK_TEXT_HAS_SELECTION(state))
27323 nk_textedit_move_to_last(state);
27326 nk_textedit_clamp(state);
27327 nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
27334 float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
27335 int start = find.first_char + find.length;
27337 state->cursor = start;
27338 nk_textedit_layout_row(&row, state, state->cursor, row_height, font);
27341 for (i=0; i < row.num_chars && x < row.x1; ++i) {
27342 float dx = nk_textedit_get_width(state, start, i, font);
27348 nk_textedit_clamp(state);
27350 state->has_preferred_x = 1;
27351 state->preferred_x = goal_x;
27353 state->select_end = state->cursor;
27358 struct nk_text_find find;
27359 struct nk_text_edit_row row;
27360 int i, sel = shift_mod;
27362 if (state->single_line) {
27369 nk_textedit_prep_selection_at_cursor(state);
27370 else if (NK_TEXT_HAS_SELECTION(state))
27371 nk_textedit_move_to_first(state);
27374 nk_textedit_clamp(state);
27375 nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
27379 if (find.prev_first != find.first_char) {
27382 float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
27384 state->cursor = find.prev_first;
27385 nk_textedit_layout_row(&row, state, state->cursor, row_height, font);
27388 for (i=0; i < row.num_chars && x < row.x1; ++i) {
27389 float dx = nk_textedit_get_width(state, find.prev_first, i, font);
27395 nk_textedit_clamp(state);
27397 state->has_preferred_x = 1;
27398 state->preferred_x = goal_x;
27399 if (sel) state->select_end = state->cursor;
27404 if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
27406 if (NK_TEXT_HAS_SELECTION(state))
27407 nk_textedit_delete_selection(state);
27409 int n = state->string.len;
27410 if (state->cursor < n)
27411 nk_textedit_delete(state, state->cursor, 1);
27413 state->has_preferred_x = 0;
27416 case NK_KEY_BACKSPACE:
27417 if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
27419 if (NK_TEXT_HAS_SELECTION(state))
27420 nk_textedit_delete_selection(state);
27422 nk_textedit_clamp(state);
27423 if (state->cursor > 0) {
27424 nk_textedit_delete(state, state->cursor-1, 1);
27428 state->has_preferred_x = 0;
27431 case NK_KEY_TEXT_START:
27433 nk_textedit_prep_selection_at_cursor(state);
27434 state->cursor = state->select_end = 0;
27435 state->has_preferred_x = 0;
27437 state->cursor = state->select_start = state->select_end = 0;
27438 state->has_preferred_x = 0;
27442 case NK_KEY_TEXT_END:
27444 nk_textedit_prep_selection_at_cursor(state);
27445 state->cursor = state->select_end = state->string.len;
27446 state->has_preferred_x = 0;
27448 state->cursor = state->string.len;
27449 state->select_start = state->select_end = 0;
27450 state->has_preferred_x = 0;
27454 case NK_KEY_TEXT_LINE_START: {
27456 struct nk_text_find find;
27457 nk_textedit_clamp(state);
27458 nk_textedit_prep_selection_at_cursor(state);
27459 if (state->string.len && state->cursor == state->string.len)
27461 nk_textedit_find_charpos(&find, state,state->cursor, state->single_line,
27463 state->cursor = state->select_end = find.first_char;
27464 state->has_preferred_x = 0;
27466 struct nk_text_find find;
27467 if (state->string.len && state->cursor == state->string.len)
27469 nk_textedit_clamp(state);
27470 nk_textedit_move_to_first(state);
27471 nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
27473 state->cursor = find.first_char;
27474 state->has_preferred_x = 0;
27478 case NK_KEY_TEXT_LINE_END: {
27480 struct nk_text_find find;
27481 nk_textedit_clamp(state);
27482 nk_textedit_prep_selection_at_cursor(state);
27483 nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
27485 state->has_preferred_x = 0;
27486 state->cursor = find.first_char + find.length;
27487 if (find.length > 0 && nk_str_rune_at(&state->string, state->cursor-1) ==
'\n')
27489 state->select_end = state->cursor;
27491 struct nk_text_find find;
27492 nk_textedit_clamp(state);
27493 nk_textedit_move_to_first(state);
27494 nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
27497 state->has_preferred_x = 0;
27498 state->cursor = find.first_char + find.length;
27499 if (find.length > 0 && nk_str_rune_at(&state->string, state->cursor-1) ==
'\n')
27507 state->redo_point = NK_TEXTEDIT_UNDOSTATECOUNT;
27508 state->redo_char_point = NK_TEXTEDIT_UNDOCHARCOUNT;
27514 if (state->undo_point > 0) {
27516 if (state->undo_rec[0].char_storage >= 0) {
27517 int n = state->undo_rec[0].insert_length, i;
27519 state->undo_char_point = (short)(state->undo_char_point - n);
27520 NK_MEMCPY(state->undo_char, state->undo_char + n,
27521 (nk_size)state->undo_char_point*
sizeof(nk_rune));
27522 for (i=0; i < state->undo_point; ++i) {
27523 if (state->undo_rec[i].char_storage >= 0)
27524 state->undo_rec[i].char_storage = (short)
27525 (state->undo_rec[i].char_storage - n);
27528 --state->undo_point;
27529 NK_MEMCPY(state->undo_rec, state->undo_rec+1,
27530 (nk_size)((nk_size)state->undo_point *
sizeof(state->undo_rec[0])));
27541 int k = NK_TEXTEDIT_UNDOSTATECOUNT-1;
27542 if (state->redo_point <= k) {
27544 if (state->undo_rec[k].char_storage >= 0) {
27545 int n = state->undo_rec[k].insert_length, i;
27547 state->redo_char_point = (short)(state->redo_char_point + n);
27548 num = (nk_size)(NK_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point);
27549 NK_MEMCPY(state->undo_char + state->redo_char_point,
27550 state->undo_char + state->redo_char_point-n, num *
sizeof(
char));
27551 for (i = state->redo_point; i < k; ++i) {
27552 if (state->undo_rec[i].char_storage >= 0) {
27553 state->undo_rec[i].char_storage = (short)
27554 (state->undo_rec[i].char_storage + n);
27558 ++state->redo_point;
27559 num = (nk_size)(NK_TEXTEDIT_UNDOSTATECOUNT - state->redo_point);
27560 if (num) NK_MEMCPY(state->undo_rec + state->redo_point-1,
27561 state->undo_rec + state->redo_point, num *
sizeof(state->undo_rec[0]));
27568 nk_textedit_flush_redo(state);
27572 if (state->undo_point == NK_TEXTEDIT_UNDOSTATECOUNT)
27573 nk_textedit_discard_undo(state);
27577 if (numchars > NK_TEXTEDIT_UNDOCHARCOUNT) {
27578 state->undo_point = 0;
27579 state->undo_char_point = 0;
27585 while (state->undo_char_point + numchars > NK_TEXTEDIT_UNDOCHARCOUNT)
27586 nk_textedit_discard_undo(state);
27587 return &state->undo_rec[state->undo_point++];
27591 int insert_len,
int delete_len)
27598 r->insert_length = (short) insert_len;
27599 r->delete_length = (short) delete_len;
27601 if (insert_len == 0) {
27602 r->char_storage = -1;
27605 r->char_storage = state->undo_char_point;
27606 state->undo_char_point = (short)(state->undo_char_point + insert_len);
27607 return &state->undo_char[r->char_storage];
27615 if (s->undo_point == 0)
27619 u = s->undo_rec[s->undo_point-1];
27620 r = &s->undo_rec[s->redo_point-1];
27621 r->char_storage = -1;
27623 r->insert_length = u.delete_length;
27624 r->delete_length = u.insert_length;
27625 r->where = u.where;
27627 if (u.delete_length)
27637 if (s->undo_char_point + u.delete_length >= NK_TEXTEDIT_UNDOCHARCOUNT) {
27640 r->insert_length = 0;
27644 while (s->undo_char_point + u.delete_length > s->redo_char_point) {
27646 nk_textedit_discard_redo(s);
27648 if (s->redo_point == NK_TEXTEDIT_UNDOSTATECOUNT)
27652 r = &s->undo_rec[s->redo_point-1];
27653 r->char_storage = (short)(s->redo_char_point - u.delete_length);
27654 s->redo_char_point = (short)(s->redo_char_point - u.delete_length);
27657 for (i=0; i < u.delete_length; ++i)
27658 s->undo_char[r->char_storage + i] =
27659 nk_str_rune_at(&state->string, u.where + i);
27662 nk_str_delete_runes(&state->string, u.where, u.delete_length);
27666 if (u.insert_length) {
27668 nk_str_insert_text_runes(&state->string, u.where,
27669 &s->undo_char[u.char_storage], u.insert_length);
27670 s->undo_char_point = (short)(s->undo_char_point - u.insert_length);
27672 state->cursor = (short)(u.where + u.insert_length);
27682 if (s->redo_point == NK_TEXTEDIT_UNDOSTATECOUNT)
27686 u = &s->undo_rec[s->undo_point];
27687 r = s->undo_rec[s->redo_point];
27691 u->delete_length = r.insert_length;
27692 u->insert_length = r.delete_length;
27693 u->where = r.where;
27694 u->char_storage = -1;
27696 if (r.delete_length) {
27699 if (s->undo_char_point + u->insert_length > s->redo_char_point) {
27700 u->insert_length = 0;
27701 u->delete_length = 0;
27704 u->char_storage = s->undo_char_point;
27705 s->undo_char_point = (short)(s->undo_char_point + u->insert_length);
27708 for (i=0; i < u->insert_length; ++i) {
27709 s->undo_char[u->char_storage + i] =
27710 nk_str_rune_at(&state->string, u->where + i);
27713 nk_str_delete_runes(&state->string, r.where, r.delete_length);
27716 if (r.insert_length) {
27718 nk_str_insert_text_runes(&state->string, r.where,
27719 &s->undo_char[r.char_storage], r.insert_length);
27721 state->cursor = r.where + r.insert_length;
27727nk_textedit_makeundo_insert(
struct nk_text_edit *state,
int where,
int length)
27729 nk_textedit_createundo(&state->undo, where, 0, length);
27732nk_textedit_makeundo_delete(
struct nk_text_edit *state,
int where,
int length)
27735 nk_rune *p = nk_textedit_createundo(&state->undo, where, length, 0);
27737 for (i=0; i < length; ++i)
27738 p[i] = nk_str_rune_at(&state->string, where+i);
27742nk_textedit_makeundo_replace(
struct nk_text_edit *state,
int where,
27743 int old_length,
int new_length)
27746 nk_rune *p = nk_textedit_createundo(&state->undo, where, old_length, new_length);
27748 for (i=0; i < old_length; ++i)
27749 p[i] = nk_str_rune_at(&state->string, where+i);
27753nk_textedit_clear_state(
struct nk_text_edit *state,
enum nk_text_edit_type type,
27754 nk_plugin_filter filter)
27757 state->undo.undo_point = 0;
27758 state->undo.undo_char_point = 0;
27759 state->undo.redo_point = NK_TEXTEDIT_UNDOSTATECOUNT;
27760 state->undo.redo_char_point = NK_TEXTEDIT_UNDOCHARCOUNT;
27761 state->select_end = state->select_start = 0;
27763 state->has_preferred_x = 0;
27764 state->preferred_x = 0;
27765 state->cursor_at_end_of_line = 0;
27766 state->initialized = 1;
27767 state->single_line = (
unsigned char)(type == NK_TEXT_EDIT_SINGLE_LINE);
27768 state->mode = NK_TEXT_EDIT_MODE_VIEW;
27769 state->filter = filter;
27770 state->scrollbar =
nk_vec2(0,0);
27773nk_textedit_init_fixed(
struct nk_text_edit *state,
void *memory, nk_size size)
27777 if (!state || !memory || !size)
return;
27779 nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0);
27780 nk_str_init_fixed(&state->string, memory, size);
27787 if (!state || !alloc)
return;
27789 nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0);
27790 nk_str_init(&state->string, alloc, size);
27792#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
27797 if (!state)
return;
27799 nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0);
27800 nk_str_init_default(&state->string);
27807 state->select_start = 0;
27808 state->select_end = state->string.len;
27814 if (!state)
return;
27815 nk_str_free(&state->string);
27830 NK_UNUSED(unicode);
27835nk_filter_ascii(
const struct nk_text_edit *box, nk_rune unicode)
27838 if (unicode > 128)
return nk_false;
27839 else return nk_true;
27842nk_filter_float(
const struct nk_text_edit *box, nk_rune unicode)
27845 if ((unicode <
'0' || unicode >
'9') && unicode !=
'.' && unicode !=
'-')
27847 else return nk_true;
27850nk_filter_decimal(
const struct nk_text_edit *box, nk_rune unicode)
27853 if ((unicode <
'0' || unicode >
'9') && unicode !=
'-')
27855 else return nk_true;
27858nk_filter_hex(
const struct nk_text_edit *box, nk_rune unicode)
27861 if ((unicode <
'0' || unicode >
'9') &&
27862 (unicode <
'a' || unicode >
'f') &&
27863 (unicode <
'A' || unicode >
'F'))
27865 else return nk_true;
27868nk_filter_oct(
const struct nk_text_edit *box, nk_rune unicode)
27871 if (unicode <
'0' || unicode >
'7')
27873 else return nk_true;
27876nk_filter_binary(
const struct nk_text_edit *box, nk_rune unicode)
27879 if (unicode !=
'0' && unicode !=
'1')
27881 else return nk_true;
27891 const struct nk_style_edit *style,
float pos_x,
float pos_y,
27892 float x_offset,
const char *text,
int byte_len,
float row_height,
27894 struct nk_color foreground, nk_bool is_selected)
27899 if (!text || !byte_len || !out || !style)
return;
27901 {
int glyph_len = 0;
27902 nk_rune unicode = 0;
27904 float line_width = 0;
27906 const char *line = text;
27907 float line_offset = 0;
27908 int line_count = 0;
27910 struct nk_text txt;
27912 txt.background = background;
27913 txt.text = foreground;
27915 foreground = nk_rgb_factor(foreground, style->color_factor);
27916 background = nk_rgb_factor(background, style->color_factor);
27918 glyph_len = nk_utf_decode(text+text_len, &unicode, byte_len-text_len);
27919 if (!glyph_len)
return;
27920 while ((text_len < byte_len) && glyph_len)
27922 if (unicode ==
'\n') {
27925 label.y = pos_y + line_offset;
27926 label.h = row_height;
27927 label.w = line_width;
27930 label.x += x_offset;
27934 nk_widget_text(out, label, line, (
int)((text + text_len) - line),
27935 &txt, NK_TEXT_CENTERED, font);
27940 line = text + text_len;
27941 line_offset += row_height;
27942 glyph_len = nk_utf_decode(text + text_len, &unicode, (
int)(byte_len-text_len));
27945 if (unicode ==
'\r') {
27947 glyph_len = nk_utf_decode(text + text_len, &unicode, byte_len-text_len);
27950 glyph_width = font->
width(font->userdata, font->
height, text+text_len, glyph_len);
27951 line_width += (float)glyph_width;
27952 text_len += glyph_len;
27953 glyph_len = nk_utf_decode(text + text_len, &unicode, byte_len-text_len);
27956 if (line_width > 0) {
27959 label.y = pos_y + line_offset;
27960 label.h = row_height;
27961 label.w = line_width;
27964 label.x += x_offset;
27968 nk_widget_text(out, label, line, (
int)((text + text_len) - line),
27969 &txt, NK_TEXT_LEFT, font);
27974 struct nk_rect bounds, nk_flags flags, nk_plugin_filter filter,
27981 char prev_state = 0;
27982 char is_hovered = 0;
27983 char select_all = 0;
27984 char cursor_follow = 0;
27991 if (!state || !out || !style)
27995 area.x = bounds.x + style->padding.x + style->border;
27996 area.y = bounds.y + style->padding.y + style->border;
27997 area.w = bounds.w - (2.0f * style->padding.x + 2 * style->border);
27998 area.h = bounds.h - (2.0f * style->padding.y + 2 * style->border);
27999 if (flags & NK_EDIT_MULTILINE)
28000 area.w = NK_MAX(0, area.w - style->scrollbar_size.x);
28001 row_height = (flags & NK_EDIT_MULTILINE)? font->
height + style->row_padding: area.h;
28004 old_clip = out->clip;
28005 nk_unify(&clip, &old_clip, area.x, area.y, area.x + area.w, area.y + area.h);
28008 prev_state = (char)edit->active;
28009 if (in && in->mouse.buttons[NK_BUTTON_LEFT].clicked && in->mouse.buttons[NK_BUTTON_LEFT].down) {
28010 edit->active = NK_INBOX(in->mouse.pos.x, in->mouse.pos.y,
28011 bounds.x, bounds.y, bounds.w, bounds.h);
28015 if (!prev_state && edit->active) {
28016 const enum nk_text_edit_type type = (flags & NK_EDIT_MULTILINE) ?
28017 NK_TEXT_EDIT_MULTI_LINE: NK_TEXT_EDIT_SINGLE_LINE;
28019 struct nk_vec2 oldscrollbar = edit->scrollbar;
28020 nk_textedit_clear_state(edit, type, filter);
28021 edit->scrollbar = oldscrollbar;
28022 if (flags & NK_EDIT_AUTO_SELECT)
28023 select_all = nk_true;
28024 if (flags & NK_EDIT_GOTO_END_ON_ACTIVATE) {
28025 edit->cursor = edit->string.len;
28028 }
else if (!edit->active) edit->mode = NK_TEXT_EDIT_MODE_VIEW;
28029 if (flags & NK_EDIT_READ_ONLY)
28030 edit->mode = NK_TEXT_EDIT_MODE_VIEW;
28031 else if (flags & NK_EDIT_ALWAYS_INSERT_MODE)
28032 edit->mode = NK_TEXT_EDIT_MODE_INSERT;
28035 if (prev_state != edit->active)
28039 if (edit->active && in)
28041 int shift_mod = in->keyboard.keys[NK_KEY_SHIFT].down;
28042 const float mouse_x = (in->mouse.pos.x - area.x) + edit->scrollbar.x;
28043 const float mouse_y = (in->mouse.pos.y - area.y) + edit->scrollbar.y;
28046 is_hovered = (char)nk_input_is_mouse_hovering_rect(in, area);
28048 nk_textedit_select_all(edit);
28049 }
else if (is_hovered && in->mouse.buttons[NK_BUTTON_LEFT].down &&
28050 in->mouse.buttons[NK_BUTTON_LEFT].clicked) {
28051 nk_textedit_click(edit, mouse_x, mouse_y, font, row_height);
28052 }
else if (is_hovered && in->mouse.buttons[NK_BUTTON_LEFT].down &&
28053 (in->mouse.delta.x != 0.0f || in->mouse.delta.y != 0.0f)) {
28054 nk_textedit_drag(edit, mouse_x, mouse_y, font, row_height);
28055 cursor_follow = nk_true;
28056 }
else if (is_hovered && in->mouse.buttons[NK_BUTTON_RIGHT].clicked &&
28057 in->mouse.buttons[NK_BUTTON_RIGHT].down) {
28058 nk_textedit_key(edit, NK_KEY_TEXT_WORD_LEFT, nk_false, font, row_height);
28059 nk_textedit_key(edit, NK_KEY_TEXT_WORD_RIGHT, nk_true, font, row_height);
28060 cursor_follow = nk_true;
28064 int old_mode = edit->mode;
28065 for (i = 0; i < NK_KEY_MAX; ++i) {
28066 if (i == NK_KEY_ENTER || i == NK_KEY_TAB)
continue;
28067 if (nk_input_is_key_pressed(in, (
enum nk_keys)i)) {
28068 nk_textedit_key(edit, (
enum nk_keys)i, shift_mod, font, row_height);
28069 cursor_follow = nk_true;
28072 if (old_mode != edit->mode) {
28073 in->keyboard.text_len = 0;
28077 edit->filter = filter;
28078 if (in->keyboard.text_len) {
28079 nk_textedit_text(edit, in->keyboard.text, in->keyboard.text_len);
28080 cursor_follow = nk_true;
28081 in->keyboard.text_len = 0;
28085 if (nk_input_is_key_pressed(in, NK_KEY_ENTER)) {
28086 cursor_follow = nk_true;
28087 if (flags & NK_EDIT_CTRL_ENTER_NEWLINE && shift_mod)
28088 nk_textedit_text(edit,
"\n", 1);
28089 else if (flags & NK_EDIT_SIG_ENTER)
28091 else nk_textedit_text(edit,
"\n", 1);
28095 {
int copy= nk_input_is_key_pressed(in, NK_KEY_COPY);
28096 int cut = nk_input_is_key_pressed(in, NK_KEY_CUT);
28097 if ((copy || cut) && (flags & NK_EDIT_CLIPBOARD))
28102 int b = edit->select_start;
28103 int e = edit->select_end;
28105 int begin = NK_MIN(b, e);
28106 int end = NK_MAX(b, e);
28107 text = nk_str_at_const(&edit->string, begin, &unicode, &glyph_len);
28108 if (edit->clip.copy)
28109 edit->clip.copy(edit->clip.userdata, text, end - begin);
28110 if (cut && !(flags & NK_EDIT_READ_ONLY)){
28111 nk_textedit_cut(edit);
28112 cursor_follow = nk_true;
28117 {
int paste = nk_input_is_key_pressed(in, NK_KEY_PASTE);
28118 if (paste && (flags & NK_EDIT_CLIPBOARD) && edit->clip.paste) {
28119 edit->clip.paste(edit->clip.userdata, edit);
28120 cursor_follow = nk_true;
28124 {
int tab = nk_input_is_key_pressed(in, NK_KEY_TAB);
28125 if (tab && (flags & NK_EDIT_ALLOW_TAB)) {
28126 nk_textedit_text(edit,
" ", 4);
28127 cursor_follow = nk_true;
28134 else nk_widget_state_reset(state);
28140 {
const char *text = nk_str_get_const(&edit->string);
28141 int len = nk_str_len_char(&edit->string);
28146 background = &style->active;
28148 background = &style->hover;
28149 else background = &style->normal;
28152 switch(background->type) {
28153 case NK_STYLE_ITEM_IMAGE:
28154 nk_draw_image(out, bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
28156 case NK_STYLE_ITEM_NINE_SLICE:
28157 nk_draw_nine_slice(out, bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor));
28159 case NK_STYLE_ITEM_COLOR:
28160 nk_fill_rect(out, bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor));
28161 nk_stroke_rect(out, bounds, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor));
28166 area.w = NK_MAX(0, area.w - style->cursor_size);
28169 int total_lines = 1;
28173 const char *cursor_ptr = 0;
28174 const char *select_begin_ptr = 0;
28175 const char *select_end_ptr = 0;
28182 int selection_begin = NK_MIN(edit->select_start, edit->select_end);
28183 int selection_end = NK_MAX(edit->select_start, edit->select_end);
28186 float line_width = 0.0f;
28192 nk_rune unicode = 0;
28197 glyph_len = nk_utf_decode(text, &unicode, len);
28198 glyph_width = font->
width(font->userdata, font->
height, text, glyph_len);
28202 while ((text_len < len) && glyph_len)
28205 if (!cursor_ptr && glyphs == edit->cursor)
28210 const char *remaining;
28213 cursor_pos.y = (float)(total_lines-1) * row_height;
28214 row_size = nk_text_calculate_text_bounds(font, text+row_begin,
28215 text_len-row_begin, row_height, &remaining,
28216 &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
28217 cursor_pos.x = row_size.x;
28218 cursor_ptr = text + text_len;
28222 if (!select_begin_ptr && edit->select_start != edit->select_end &&
28223 glyphs == selection_begin)
28228 const char *remaining;
28231 selection_offset_start.y = (float)(NK_MAX(total_lines-1,0)) * row_height;
28232 row_size = nk_text_calculate_text_bounds(font, text+row_begin,
28233 text_len-row_begin, row_height, &remaining,
28234 &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
28235 selection_offset_start.x = row_size.x;
28236 select_begin_ptr = text + text_len;
28240 if (!select_end_ptr && edit->select_start != edit->select_end &&
28241 glyphs == selection_end)
28246 const char *remaining;
28249 selection_offset_end.y = (float)(total_lines-1) * row_height;
28250 row_size = nk_text_calculate_text_bounds(font, text+row_begin,
28251 text_len-row_begin, row_height, &remaining,
28252 &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
28253 selection_offset_end.x = row_size.x;
28254 select_end_ptr = text + text_len;
28256 if (unicode ==
'\n') {
28257 text_size.x = NK_MAX(text_size.x, line_width);
28262 row_begin = text_len;
28263 glyph_len = nk_utf_decode(text + text_len, &unicode, len-text_len);
28264 glyph_width = font->
width(font->userdata, font->
height, text+text_len, glyph_len);
28269 text_len += glyph_len;
28270 line_width += (float)glyph_width;
28272 glyph_len = nk_utf_decode(text + text_len, &unicode, len-text_len);
28273 glyph_width = font->
width(font->userdata, font->
height,
28274 text+text_len, glyph_len);
28277 text_size.y = (float)total_lines * row_height;
28280 if (!cursor_ptr && edit->cursor == edit->string.len) {
28281 cursor_pos.x = line_width;
28282 cursor_pos.y = text_size.y - row_height;
28290 if (!(flags & NK_EDIT_NO_HORIZONTAL_SCROLL)) {
28292 const float scroll_increment = area.w * 0.25f;
28293 if (cursor_pos.x < edit->scrollbar.x)
28294 edit->scrollbar.x = (float)(
int)NK_MAX(0.0f, cursor_pos.x - scroll_increment);
28295 if (cursor_pos.x >= edit->scrollbar.x + area.w)
28296 edit->scrollbar.x = (float)(
int)NK_MAX(0.0f, cursor_pos.x - area.w + scroll_increment);
28297 }
else edit->scrollbar.x = 0;
28299 if (flags & NK_EDIT_MULTILINE) {
28303 if (cursor_pos.y < edit->scrollbar.y)
28304 edit->scrollbar.y = NK_MAX(0.0f, cursor_pos.y);
28305 if (cursor_pos.y > edit->scrollbar.y + area.h - row_height)
28306 edit->scrollbar.y = edit->scrollbar.y + row_height;
28307 }
else edit->scrollbar.y = 0;
28311 if (flags & NK_EDIT_MULTILINE)
28315 float scroll_target;
28316 float scroll_offset;
28321 scroll.x = (bounds.x + bounds.w - style->border) - style->scrollbar_size.x;
28322 scroll.w = style->scrollbar_size.x;
28324 scroll_offset = edit->scrollbar.y;
28325 scroll_step = scroll.h * 0.10f;
28326 scroll_inc = scroll.h * 0.01f;
28327 scroll_target = text_size.y;
28328 edit->scrollbar.y = nk_do_scrollbarv(&ws, out, scroll, is_hovered,
28329 scroll_offset, scroll_target, scroll_step, scroll_inc,
28330 &style->scrollbar, in, font);
28332 if (is_hovered && in->mouse.scroll_delta.y) {
28333 in->mouse.scroll_delta.y = 0;
28339 {
struct nk_color background_color;
28341 struct nk_color sel_background_color;
28344 struct nk_color cursor_text_color;
28346 nk_push_scissor(out, clip);
28350 background = &style->active;
28351 text_color = style->text_active;
28352 sel_text_color = style->selected_text_hover;
28353 sel_background_color = style->selected_hover;
28354 cursor_color = style->cursor_hover;
28355 cursor_text_color = style->cursor_text_hover;
28357 background = &style->hover;
28358 text_color = style->text_hover;
28359 sel_text_color = style->selected_text_hover;
28360 sel_background_color = style->selected_hover;
28361 cursor_text_color = style->cursor_text_hover;
28362 cursor_color = style->cursor_hover;
28364 background = &style->normal;
28365 text_color = style->text_normal;
28366 sel_text_color = style->selected_text_normal;
28367 sel_background_color = style->selected_normal;
28368 cursor_color = style->cursor_normal;
28369 cursor_text_color = style->cursor_text_normal;
28371 if (background->type == NK_STYLE_ITEM_IMAGE)
28372 background_color = nk_rgba(0,0,0,0);
28374 background_color = background->data.color;
28376 cursor_color = nk_rgb_factor(cursor_color, style->color_factor);
28377 cursor_text_color = nk_rgb_factor(cursor_text_color, style->color_factor);
28379 if (edit->select_start == edit->select_end) {
28381 const char *begin = nk_str_get_const(&edit->string);
28382 int l = nk_str_len_char(&edit->string);
28383 nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
28384 area.y - edit->scrollbar.y, 0, begin, l, row_height, font,
28385 background_color, text_color, nk_false);
28388 if (edit->select_start != edit->select_end && selection_begin > 0){
28390 const char *begin = nk_str_get_const(&edit->string);
28391 NK_ASSERT(select_begin_ptr);
28392 nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
28393 area.y - edit->scrollbar.y, 0, begin, (
int)(select_begin_ptr - begin),
28394 row_height, font, background_color, text_color, nk_false);
28396 if (edit->select_start != edit->select_end) {
28398 NK_ASSERT(select_begin_ptr);
28399 if (!select_end_ptr) {
28400 const char *begin = nk_str_get_const(&edit->string);
28401 select_end_ptr = begin + nk_str_len_char(&edit->string);
28403 nk_edit_draw_text(out, style,
28404 area.x - edit->scrollbar.x,
28405 area.y + selection_offset_start.y - edit->scrollbar.y,
28406 selection_offset_start.x,
28407 select_begin_ptr, (
int)(select_end_ptr - select_begin_ptr),
28408 row_height, font, sel_background_color, sel_text_color, nk_true);
28410 if ((edit->select_start != edit->select_end &&
28411 selection_end < edit->
string.len))
28414 const char *begin = select_end_ptr;
28415 const char *end = nk_str_get_const(&edit->string) +
28416 nk_str_len_char(&edit->string);
28417 NK_ASSERT(select_end_ptr);
28418 nk_edit_draw_text(out, style,
28419 area.x - edit->scrollbar.x,
28420 area.y + selection_offset_end.y - edit->scrollbar.y,
28421 selection_offset_end.x,
28422 begin, (
int)(end - begin), row_height, font,
28423 background_color, text_color, nk_true);
28428 if (edit->select_start == edit->select_end)
28430 if (edit->cursor >= nk_str_len(&edit->string) ||
28431 (cursor_ptr && *cursor_ptr ==
'\n')) {
28434 cursor.w = style->cursor_size;
28435 cursor.h = font->
height;
28436 cursor.x = area.x + cursor_pos.x - edit->scrollbar.x;
28437 cursor.y = area.y + cursor_pos.y + row_height/2.0f - cursor.h/2.0f;
28438 cursor.y -= edit->scrollbar.y;
28444 struct nk_text txt;
28447 NK_ASSERT(cursor_ptr);
28448 glyph_len = nk_utf_decode(cursor_ptr, &unicode, 4);
28450 label.x = area.x + cursor_pos.x - edit->scrollbar.x;
28451 label.y = area.y + cursor_pos.y - edit->scrollbar.y;
28452 label.w = font->
width(font->userdata, font->
height, cursor_ptr, glyph_len);
28453 label.h = row_height;
28456 txt.background = cursor_color;;
28457 txt.text = cursor_text_color;
28459 nk_widget_text(out, label, cursor_ptr, glyph_len, &txt, NK_TEXT_LEFT, font);
28464 int l = nk_str_len_char(&edit->string);
28465 const char *begin = nk_str_get_const(&edit->string);
28470 nk_push_scissor(out, clip);
28472 background = &style->active;
28473 text_color = style->text_active;
28475 background = &style->hover;
28476 text_color = style->text_hover;
28478 background = &style->normal;
28479 text_color = style->text_normal;
28481 if (background->type == NK_STYLE_ITEM_IMAGE)
28482 background_color = nk_rgba(0,0,0,0);
28484 background_color = background->data.color;
28486 background_color = nk_rgb_factor(background_color, style->color_factor);
28487 text_color = nk_rgb_factor(text_color, style->color_factor);
28489 nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
28490 area.y - edit->scrollbar.y, 0, begin, l, row_height, font,
28491 background_color, text_color, nk_false);
28493 nk_push_scissor(out, old_clip);}
28497nk_edit_focus(
struct nk_context *ctx, nk_flags flags)
28503 NK_ASSERT(ctx->current);
28504 if (!ctx || !ctx->current)
return;
28506 win = ctx->current;
28507 hash = win->edit.seq;
28508 win->edit.active = nk_true;
28509 win->edit.name = hash;
28510 if (flags & NK_EDIT_ALWAYS_INSERT_MODE)
28511 win->edit.mode = NK_TEXT_EDIT_MODE_INSERT;
28518 NK_ASSERT(ctx->current);
28519 if (!ctx || !ctx->current)
return;
28521 win = ctx->current;
28522 win->edit.active = nk_false;
28523 win->edit.name = 0;
28526nk_edit_string(
struct nk_context *ctx, nk_flags flags,
28527 char *memory,
int *len,
int max, nk_plugin_filter filter)
28537 if (!ctx || !memory || !len)
28541 win = ctx->current;
28542 hash = win->edit.seq;
28544 nk_textedit_clear_state(&ctx->
text_edit, (flags & NK_EDIT_MULTILINE)?
28545 NK_TEXT_EDIT_MULTI_LINE: NK_TEXT_EDIT_SINGLE_LINE, filter);
28547 if (win->edit.active && hash == win->edit.name) {
28548 if (flags & NK_EDIT_NO_CURSOR)
28549 edit->cursor = nk_utf_len(memory, *len);
28550 else edit->cursor = win->edit.cursor;
28551 if (!(flags & NK_EDIT_SELECTABLE)) {
28552 edit->select_start = win->edit.cursor;
28553 edit->select_end = win->edit.cursor;
28555 edit->select_start = win->edit.sel_start;
28556 edit->select_end = win->edit.sel_end;
28558 edit->mode = win->edit.mode;
28559 edit->scrollbar.x = (float)win->edit.scrollbar.x;
28560 edit->scrollbar.y = (float)win->edit.scrollbar.y;
28561 edit->active = nk_true;
28562 }
else edit->active = nk_false;
28564 max = NK_MAX(1, max);
28565 *len = NK_MIN(*len, max-1);
28566 nk_str_init_fixed(&edit->string, memory, (nk_size)max);
28567 edit->string.buffer.
allocated = (nk_size)*len;
28568 edit->string.len = nk_utf_len(memory, *len);
28569 state = nk_edit_buffer(ctx, flags, edit, filter);
28570 *len = (int)edit->string.buffer.
allocated;
28572 if (edit->active) {
28573 win->edit.cursor = edit->cursor;
28574 win->edit.sel_start = edit->select_start;
28575 win->edit.sel_end = edit->select_end;
28576 win->edit.mode = edit->mode;
28577 win->edit.scrollbar.x = (nk_uint)edit->scrollbar.x;
28578 win->edit.scrollbar.y = (nk_uint)edit->scrollbar.y;
28582nk_edit_buffer(
struct nk_context *ctx, nk_flags flags,
28592 nk_flags ret_flags = 0;
28593 unsigned char prev_state;
28599 NK_ASSERT(ctx->current);
28600 NK_ASSERT(ctx->current->layout);
28601 if (!ctx || !ctx->current || !ctx->current->layout)
28604 win = ctx->current;
28605 style = &ctx->style;
28606 state = nk_widget(&bounds, ctx);
28607 if (!state)
return state;
28609 flags |= NK_EDIT_READ_ONLY;
28610 in = (win->layout->flags &
NK_WINDOW_ROM) ? 0 : &ctx->input;
28613 hash = win->edit.seq++;
28614 if (win->edit.active && hash == win->edit.name) {
28615 if (flags & NK_EDIT_NO_CURSOR)
28616 edit->cursor = edit->string.len;
28617 if (!(flags & NK_EDIT_SELECTABLE)) {
28618 edit->select_start = edit->cursor;
28619 edit->select_end = edit->cursor;
28621 if (flags & NK_EDIT_CLIPBOARD)
28622 edit->clip = ctx->clip;
28623 edit->active = (
unsigned char)win->edit.active;
28624 }
else edit->active = nk_false;
28625 edit->mode = win->edit.mode;
28628 prev_state = (
unsigned char)edit->active;
28629 in = (flags & NK_EDIT_READ_ONLY) ? 0: in;
28630 ret_flags = nk_do_edit(&ctx->last_widget_state, &win->buffer, bounds, flags,
28631 filter, edit, &style->edit, in, style->font);
28634 ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_TEXT];
28635 if (edit->active && prev_state != edit->active) {
28637 win->edit.active = nk_true;
28638 win->edit.name = hash;
28639 }
else if (prev_state && !edit->active) {
28641 win->edit.active = nk_false;
28642 }
return ret_flags;
28645nk_edit_string_zero_terminated(
struct nk_context *ctx, nk_flags flags,
28646 char *buffer,
int max, nk_plugin_filter filter)
28649 int len = nk_strlen(buffer);
28650 result = nk_edit_string(ctx, flags, buffer, &len, max, filter);
28651 buffer[NK_MIN(NK_MAX(max-1,0), len)] =
'\0';
28665nk_drag_behavior(nk_flags *state,
const struct nk_input *in,
28666 struct nk_rect drag,
struct nk_property_variant *variant,
28667 float inc_per_pixel)
28669 int left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
28670 int left_mouse_click_in_cursor = in &&
28671 nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, drag, nk_true);
28673 nk_widget_state_reset(state);
28674 if (nk_input_is_mouse_hovering_rect(in, drag))
28677 if (left_mouse_down && left_mouse_click_in_cursor) {
28678 float delta, pixels;
28679 pixels = in->mouse.delta.x;
28680 delta = pixels * inc_per_pixel;
28681 switch (variant->kind) {
28683 case NK_PROPERTY_INT:
28684 variant->value.i = variant->value.i + (int)delta;
28685 variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
28687 case NK_PROPERTY_FLOAT:
28688 variant->value.f = variant->value.f + (float)delta;
28689 variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
28691 case NK_PROPERTY_DOUBLE:
28692 variant->value.d = variant->value.d + (double)delta;
28693 variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
28700 else if (nk_input_is_mouse_prev_hovering_rect(in, drag))
28704nk_property_behavior(nk_flags *ws,
const struct nk_input *in,
28706 struct nk_rect empty,
int *state,
struct nk_property_variant *variant,
28707 float inc_per_pixel)
28709 nk_widget_state_reset(ws);
28710 if (in && *state == NK_PROPERTY_DEFAULT) {
28711 if (nk_button_behavior(ws, edit, in, NK_BUTTON_DEFAULT))
28712 *state = NK_PROPERTY_EDIT;
28713 else if (nk_input_is_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, label, nk_true))
28714 *state = NK_PROPERTY_DRAG;
28715 else if (nk_input_is_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, empty, nk_true))
28716 *state = NK_PROPERTY_DRAG;
28718 if (*state == NK_PROPERTY_DRAG) {
28719 nk_drag_behavior(ws, in, property, variant, inc_per_pixel);
28725 const struct nk_rect *bounds,
const struct nk_rect *label, nk_flags state,
28726 const char *name,
int len,
const struct nk_user_font *font)
28728 struct nk_text text;
28733 background = &style->active;
28734 text.text = style->label_active;
28736 background = &style->hover;
28737 text.text = style->label_hover;
28739 background = &style->normal;
28740 text.text = style->label_normal;
28743 text.text = nk_rgb_factor(text.text, style->color_factor);
28746 switch(background->type) {
28747 case NK_STYLE_ITEM_IMAGE:
28748 text.background = nk_rgba(0, 0, 0, 0);
28749 nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
28751 case NK_STYLE_ITEM_NINE_SLICE:
28752 text.background = nk_rgba(0, 0, 0, 0);
28753 nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor));
28755 case NK_STYLE_ITEM_COLOR:
28756 text.background = background->data.color;
28757 nk_fill_rect(out, *bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor));
28758 nk_stroke_rect(out, *bounds, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor));
28764 if (name && name[0] !=
'#') {
28765 nk_widget_text(out, *label, name, len, &text, NK_TEXT_CENTERED, font);
28769nk_do_property(nk_flags *ws,
28771 const char *name,
struct nk_property_variant *variant,
28772 float inc_per_pixel,
char *buffer,
int *len,
28773 int *state,
int *cursor,
int *select_begin,
int *select_end,
28775 enum nk_property_filter filter,
struct nk_input *in,
28777 enum nk_button_behavior behavior)
28779 const nk_plugin_filter filters[] = {
28783 nk_bool active, old;
28784 int num_len = 0, name_len = 0;
28785 char string[NK_MAX_NUMBER_BUFFER];
28798 left.h = font->
height/2;
28800 left.x =
property.x + style->border + style->padding.x;
28801 left.y =
property.y + style->border +
property.h/2.0f - left.h/2;
28804 if (name && name[0] !=
'#') {
28805 name_len = nk_strlen(name);
28807 size = font->
width(font->userdata, font->
height, name, name_len);
28808 label.x = left.x + left.w + style->padding.x;
28809 label.w = (float)size + 2 * style->padding.x;
28810 label.y =
property.y + style->border + style->padding.y;
28811 label.h =
property.h - (2 * style->border + 2 * style->padding.y);
28817 right.x =
property.x +
property.w - (right.w + style->padding.x);
28820 if (*state == NK_PROPERTY_EDIT) {
28821 size = font->
width(font->userdata, font->
height, buffer, *len);
28822 size += style->edit.cursor_size;
28826 switch (variant->kind) {
28828 case NK_PROPERTY_INT:
28829 nk_itoa(
string, variant->value.i);
28830 num_len = nk_strlen(
string);
28832 case NK_PROPERTY_FLOAT:
28833 NK_DTOA(
string, (
double)variant->value.f);
28834 num_len = nk_string_float_limit(
string, NK_MAX_FLOAT_PRECISION);
28836 case NK_PROPERTY_DOUBLE:
28837 NK_DTOA(
string, variant->value.d);
28838 num_len = nk_string_float_limit(
string, NK_MAX_FLOAT_PRECISION);
28841 size = font->
width(font->userdata, font->
height,
string, num_len);
28846 edit.w = (float)size + 2 * style->padding.x;
28847 edit.w = NK_MIN(edit.w, right.x - (label.x + label.w));
28848 edit.x = right.x - (edit.w + style->padding.x);
28849 edit.y =
property.y + style->border;
28850 edit.h =
property.h - (2 * style->border);
28853 empty.w = edit.x - (label.x + label.w);
28854 empty.x = label.x + label.w;
28855 empty.y =
property.y;
28856 empty.h =
property.h;
28859 old = (*state == NK_PROPERTY_EDIT);
28860 nk_property_behavior(ws, in, property, label, edit, empty, state, variant, inc_per_pixel);
28863 if (style->draw_begin) style->draw_begin(out, style->userdata);
28864 nk_draw_property(out, style, &property, &label, *ws, name, name_len, font);
28865 if (style->draw_end) style->draw_end(out, style->userdata);
28868 if (nk_do_button_symbol(ws, out, left, style->sym_left, behavior, &style->dec_button, in, font)) {
28869 switch (variant->kind) {
28871 case NK_PROPERTY_INT:
28872 variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i - variant->step.i, variant->max_value.i);
break;
28873 case NK_PROPERTY_FLOAT:
28874 variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f - variant->step.f, variant->max_value.f);
break;
28875 case NK_PROPERTY_DOUBLE:
28876 variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d - variant->step.d, variant->max_value.d);
break;
28880 if (nk_do_button_symbol(ws, out, right, style->sym_right, behavior, &style->inc_button, in, font)) {
28881 switch (variant->kind) {
28883 case NK_PROPERTY_INT:
28884 variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i + variant->step.i, variant->max_value.i);
break;
28885 case NK_PROPERTY_FLOAT:
28886 variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f + variant->step.f, variant->max_value.f);
break;
28887 case NK_PROPERTY_DOUBLE:
28888 variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d + variant->step.d, variant->max_value.d);
break;
28891 if (old != NK_PROPERTY_EDIT && (*state == NK_PROPERTY_EDIT)) {
28893 NK_MEMCPY(buffer, dst, (nk_size)*length);
28894 *cursor = nk_utf_len(buffer, *length);
28899 }
else active = (*state == NK_PROPERTY_EDIT);
28902 nk_textedit_clear_state(text_edit, NK_TEXT_EDIT_SINGLE_LINE, filters[filter]);
28903 text_edit->active = (
unsigned char)active;
28904 text_edit->string.len = *length;
28905 text_edit->cursor = NK_CLAMP(0, *cursor, *length);
28906 text_edit->select_start = NK_CLAMP(0,*select_begin, *length);
28907 text_edit->select_end = NK_CLAMP(0,*select_end, *length);
28908 text_edit->string.buffer.
allocated = (nk_size)*length;
28909 text_edit->string.buffer.
memory.size = NK_MAX_NUMBER_BUFFER;
28910 text_edit->string.buffer.
memory.ptr = dst;
28911 text_edit->string.buffer.
size = NK_MAX_NUMBER_BUFFER;
28912 text_edit->mode = NK_TEXT_EDIT_MODE_INSERT;
28913 nk_do_edit(ws, out, edit, (
int)NK_EDIT_FIELD|(
int)NK_EDIT_AUTO_SELECT,
28914 filters[filter], text_edit, &style->edit, (*state == NK_PROPERTY_EDIT) ? in: 0, font);
28916 *length = text_edit->string.len;
28917 *cursor = text_edit->cursor;
28918 *select_begin = text_edit->select_start;
28919 *select_end = text_edit->select_end;
28920 if (text_edit->active && nk_input_is_key_pressed(in, NK_KEY_ENTER))
28921 text_edit->active = nk_false;
28923 if (active && !text_edit->active) {
28925 *state = NK_PROPERTY_DEFAULT;
28926 buffer[*len] =
'\0';
28927 switch (variant->kind) {
28929 case NK_PROPERTY_INT:
28930 variant->value.i = nk_strtoi(buffer, 0);
28931 variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
28933 case NK_PROPERTY_FLOAT:
28934 nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
28935 variant->value.f = nk_strtof(buffer, 0);
28936 variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
28938 case NK_PROPERTY_DOUBLE:
28939 nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
28940 variant->value.d = nk_strtod(buffer, 0);
28941 variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
28946NK_LIB
struct nk_property_variant
28947nk_property_variant_int(int value, int min_value, int max_value, int step)
28949 struct nk_property_variant result;
28950 result.kind = NK_PROPERTY_INT;
28951 result.value.i = value;
28952 result.min_value.i = min_value;
28953 result.max_value.i = max_value;
28954 result.step.i = step;
28957NK_LIB
struct nk_property_variant
28958nk_property_variant_float(float value, float min_value, float max_value, float step)
28960 struct nk_property_variant result;
28961 result.kind = NK_PROPERTY_FLOAT;
28962 result.value.f = value;
28963 result.min_value.f = min_value;
28964 result.max_value.f = max_value;
28965 result.step.f = step;
28968NK_LIB
struct nk_property_variant
28969nk_property_variant_double(double value, double min_value, double max_value,
28972 struct nk_property_variant result;
28973 result.kind = NK_PROPERTY_DOUBLE;
28974 result.value.d = value;
28975 result.min_value.d = min_value;
28976 result.max_value.d = max_value;
28977 result.step.d = step;
28981nk_property(
struct nk_context *ctx,
const char *name,
struct nk_property_variant *variant,
28982 float inc_per_pixel,
const enum nk_property_filter filter)
28997 int *select_begin = 0;
28998 int *select_end = 0;
29001 char dummy_buffer[NK_MAX_NUMBER_BUFFER];
29002 int dummy_state = NK_PROPERTY_DEFAULT;
29003 int dummy_length = 0;
29004 int dummy_cursor = 0;
29005 int dummy_select_begin = 0;
29006 int dummy_select_end = 0;
29009 NK_ASSERT(ctx->current);
29010 NK_ASSERT(ctx->current->layout);
29011 if (!ctx || !ctx->current || !ctx->current->layout)
29014 win = ctx->current;
29015 layout = win->layout;
29016 style = &ctx->style;
29017 s = nk_widget(&bounds, ctx);
29021 if (name[0] ==
'#') {
29022 hash = nk_murmur_hash(name, (
int)nk_strlen(name), win->property.seq++);
29024 }
else hash = nk_murmur_hash(name, (
int)nk_strlen(name), 42);
29027 if (win->property.active && hash == win->property.name) {
29028 buffer = win->property.buffer;
29029 len = &win->property.length;
29030 cursor = &win->property.cursor;
29031 state = &win->property.state;
29032 select_begin = &win->property.select_start;
29033 select_end = &win->property.select_end;
29035 buffer = dummy_buffer;
29036 len = &dummy_length;
29037 cursor = &dummy_cursor;
29038 state = &dummy_state;
29039 select_begin = &dummy_select_begin;
29040 select_end = &dummy_select_end;
29044 old_state = *state;
29048 nk_do_property(&ctx->last_widget_state, &win->buffer, bounds, name,
29049 variant, inc_per_pixel, buffer, len, state, cursor, select_begin,
29050 select_end, &style->property, filter, in, style->font, &ctx->
text_edit,
29051 ctx->button_behavior);
29053 if (in && *state != NK_PROPERTY_DEFAULT && !win->property.active) {
29055 win->property.active = 1;
29056 NK_MEMCPY(win->property.buffer, buffer, (nk_size)*len);
29057 win->property.length = *len;
29058 win->property.cursor = *cursor;
29059 win->property.state = *state;
29060 win->property.name = hash;
29061 win->property.select_start = *select_begin;
29062 win->property.select_end = *select_end;
29063 if (*state == NK_PROPERTY_DRAG) {
29064 ctx->input.mouse.grab = nk_true;
29065 ctx->input.mouse.grabbed = nk_true;
29069 if (*state == NK_PROPERTY_DEFAULT && old_state != NK_PROPERTY_DEFAULT) {
29070 if (old_state == NK_PROPERTY_DRAG) {
29071 ctx->input.mouse.grab = nk_false;
29072 ctx->input.mouse.grabbed = nk_false;
29073 ctx->input.mouse.ungrab = nk_true;
29075 win->property.select_start = 0;
29076 win->property.select_end = 0;
29077 win->property.active = 0;
29081nk_property_int(
struct nk_context *ctx,
const char *name,
29082 int min,
int *val,
int max,
int step,
float inc_per_pixel)
29084 struct nk_property_variant variant;
29089 if (!ctx || !ctx->current || !name || !val)
return;
29090 variant = nk_property_variant_int(*val, min, max, step);
29091 nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_INT);
29092 *val = variant.value.i;
29096 float min,
float *val,
float max,
float step,
float inc_per_pixel)
29098 struct nk_property_variant variant;
29103 if (!ctx || !ctx->current || !name || !val)
return;
29104 variant = nk_property_variant_float(*val, min, max, step);
29105 nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
29106 *val = variant.value.f;
29110 double min,
double *val,
double max,
double step,
float inc_per_pixel)
29112 struct nk_property_variant variant;
29117 if (!ctx || !ctx->current || !name || !val)
return;
29118 variant = nk_property_variant_double(*val, min, max, step);
29119 nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
29120 *val = variant.value.d;
29124 int max,
int step,
float inc_per_pixel)
29126 struct nk_property_variant variant;
29130 if (!ctx || !ctx->current || !name)
return val;
29131 variant = nk_property_variant_int(val, min, max, step);
29132 nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_INT);
29133 val = variant.value.i;
29138 float val,
float max,
float step,
float inc_per_pixel)
29140 struct nk_property_variant variant;
29144 if (!ctx || !ctx->current || !name)
return val;
29145 variant = nk_property_variant_float(val, min, max, step);
29146 nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
29147 val = variant.value.f;
29152 double val,
double max,
double step,
float inc_per_pixel)
29154 struct nk_property_variant variant;
29158 if (!ctx || !ctx->current || !name)
return val;
29159 variant = nk_property_variant_double(val, min, max, step);
29160 nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
29161 val = variant.value.d;
29175nk_chart_begin_colored(
struct nk_context *ctx,
enum nk_chart_type type,
29177 int count,
float min_value,
float max_value)
29185 struct nk_rect bounds = {0, 0, 0, 0};
29188 NK_ASSERT(ctx->current);
29189 NK_ASSERT(ctx->current->layout);
29191 if (!ctx || !ctx->current || !ctx->current->layout)
return 0;
29192 if (!nk_widget(&bounds, ctx)) {
29193 chart = &ctx->current->layout->chart;
29194 nk_zero(chart,
sizeof(*chart));
29198 win = ctx->current;
29199 config = &ctx->style;
29200 chart = &win->layout->chart;
29201 style = &config->chart;
29204 nk_zero(chart,
sizeof(*chart));
29205 chart->x = bounds.x + style->padding.x;
29206 chart->y = bounds.y + style->padding.y;
29207 chart->w = bounds.w - 2 * style->padding.x;
29208 chart->h = bounds.h - 2 * style->padding.y;
29209 chart->w = NK_MAX(chart->w, 2 * style->padding.x);
29210 chart->h = NK_MAX(chart->h, 2 * style->padding.y);
29213 {
struct nk_chart_slot *slot = &chart->slots[chart->slot++];
29215 slot->count = count;
29216 slot->color = nk_rgb_factor(color, style->color_factor);
29217 slot->highlight = highlight;
29218 slot->min = NK_MIN(min_value, max_value);
29219 slot->max = NK_MAX(min_value, max_value);
29220 slot->range = slot->max - slot->min;
29221 slot->show_markers = style->show_markers;}
29224 background = &style->background;
29226 switch(background->type) {
29227 case NK_STYLE_ITEM_IMAGE:
29228 nk_draw_image(&win->buffer, bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
29230 case NK_STYLE_ITEM_NINE_SLICE:
29231 nk_draw_nine_slice(&win->buffer, bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor));
29233 case NK_STYLE_ITEM_COLOR:
29234 nk_fill_rect(&win->buffer, bounds, style->rounding, nk_rgb_factor(style->border_color, style->color_factor));
29235 nk_fill_rect(&win->buffer, nk_shrink_rect(bounds, style->border),
29236 style->rounding, nk_rgb_factor(style->background.data.color, style->color_factor));
29242nk_chart_begin(
struct nk_context *ctx,
const enum nk_chart_type type,
29243 int count,
float min_value,
float max_value)
29245 return nk_chart_begin_colored(ctx, type, ctx->style.chart.color,
29246 ctx->style.chart.selected_color, count, min_value, max_value);
29249nk_chart_add_slot_colored(
struct nk_context *ctx,
const enum nk_chart_type type,
29251 int count,
float min_value,
float max_value)
29256 NK_ASSERT(ctx->current);
29257 NK_ASSERT(ctx->current->layout);
29258 NK_ASSERT(ctx->current->layout->chart.slot < NK_CHART_MAX_SLOT);
29259 if (!ctx || !ctx->current || !ctx->current->layout)
return;
29260 if (ctx->current->layout->chart.slot >= NK_CHART_MAX_SLOT)
return;
29262 style = &ctx->style.chart;
29265 {
struct nk_chart *chart = &ctx->current->layout->chart;
29268 slot->count = count;
29269 slot->color = nk_rgb_factor(color, style->color_factor);
29270 slot->highlight = highlight;
29271 slot->min = NK_MIN(min_value, max_value);
29272 slot->max = NK_MAX(min_value, max_value);
29273 slot->range = slot->max - slot->min;
29274 slot->show_markers = style->show_markers;}
29277nk_chart_add_slot(
struct nk_context *ctx,
const enum nk_chart_type type,
29278 int count,
float min_value,
float max_value)
29280 nk_chart_add_slot_colored(ctx, type, ctx->style.chart.color,
29281 ctx->style.chart.selected_color, count, min_value, max_value);
29285 struct nk_chart *g,
float value,
int slot)
29287 struct nk_panel *layout = win->layout;
29288 const struct nk_input *i = ctx->current->widgets_disabled ? 0 : &ctx->input;
29299 NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT);
29300 step = g->w / (float)g->slots[slot].count;
29301 range = g->slots[slot].max - g->slots[slot].min;
29302 ratio = (value - g->slots[slot].min) / range;
29304 if (g->slots[slot].index == 0) {
29306 g->slots[slot].last.x = g->x;
29307 g->slots[slot].last.y = (g->y + g->h) - ratio * (
float)g->h;
29309 bounds.x = g->slots[slot].last.x - 2;
29310 bounds.y = g->slots[slot].last.y - 2;
29311 bounds.w = bounds.h = 4;
29313 color = g->slots[slot].color;
29315 NK_INBOX(i->mouse.pos.x,i->mouse.pos.y, g->slots[slot].last.x-3, g->slots[slot].last.y-3, 6, 6)){
29316 ret = nk_input_is_mouse_hovering_rect(i, bounds) ? NK_CHART_HOVERING : 0;
29317 ret |= (i->mouse.buttons[NK_BUTTON_LEFT].down &&
29318 i->mouse.buttons[NK_BUTTON_LEFT].clicked) ? NK_CHART_CLICKED: 0;
29319 color = g->slots[slot].highlight;
29321 if (g->slots[slot].show_markers) {
29324 g->slots[slot].index += 1;
29329 color = g->slots[slot].color;
29330 cur.x = g->x + (float)(step * (
float)g->slots[slot].index);
29331 cur.y = (g->y + g->h) - (ratio * (
float)g->h);
29332 nk_stroke_line(out, g->slots[slot].last.x, g->slots[slot].last.y, cur.x, cur.y, 1.0f, color);
29334 bounds.x = cur.x - 3;
29335 bounds.y = cur.y - 3;
29336 bounds.w = bounds.h = 6;
29340 if (nk_input_is_mouse_hovering_rect(i, bounds)) {
29341 ret = NK_CHART_HOVERING;
29342 ret |= (!i->mouse.buttons[NK_BUTTON_LEFT].down &&
29343 i->mouse.buttons[NK_BUTTON_LEFT].clicked) ? NK_CHART_CLICKED: 0;
29344 color = g->slots[slot].highlight;
29347 if (g->slots[slot].show_markers) {
29352 g->slots[slot].last.x = cur.x;
29353 g->slots[slot].last.y = cur.y;
29354 g->slots[slot].index += 1;
29359 struct nk_chart *chart,
float value,
int slot)
29362 const struct nk_input *in = ctx->current->widgets_disabled ? 0 : &ctx->input;
29363 struct nk_panel *layout = win->layout;
29368 struct nk_rect item = {0,0,0,0};
29370 NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT);
29371 if (chart->slots[slot].index >= chart->slots[slot].count)
29373 if (chart->slots[slot].count) {
29374 float padding = (float)(chart->slots[slot].count-1);
29375 item.w = (chart->w - padding) / (
float)(chart->slots[slot].count);
29379 color = chart->slots[slot].color;;
29380 item.h = chart->h * NK_ABS((value/chart->slots[slot].range));
29382 ratio = (value + NK_ABS(chart->slots[slot].min)) / NK_ABS(chart->slots[slot].range);
29383 item.y = (chart->y + chart->h) - chart->h * ratio;
29385 ratio = (value - chart->slots[slot].max) / chart->slots[slot].range;
29386 item.y = chart->y + (chart->h * NK_ABS(ratio)) - item.h;
29388 item.x = chart->x + ((float)chart->slots[slot].index * item.w);
29389 item.x = item.x + ((float)chart->slots[slot].index);
29393 NK_INBOX(in->mouse.pos.x,in->mouse.pos.y,item.x,item.y,item.w,item.h)) {
29394 ret = NK_CHART_HOVERING;
29395 ret |= (!in->mouse.buttons[NK_BUTTON_LEFT].down &&
29396 in->mouse.buttons[NK_BUTTON_LEFT].clicked) ? NK_CHART_CLICKED: 0;
29397 color = chart->slots[slot].highlight;
29400 chart->slots[slot].index += 1;
29404nk_chart_push_slot(
struct nk_context *ctx,
float value,
int slot)
29410 NK_ASSERT(ctx->current);
29411 NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT);
29412 NK_ASSERT(slot < ctx->current->layout->chart.slot);
29413 if (!ctx || !ctx->current || slot >= NK_CHART_MAX_SLOT)
return nk_false;
29414 if (slot >= ctx->current->layout->chart.slot)
return nk_false;
29416 win = ctx->current;
29417 if (win->layout->chart.slot < slot)
return nk_false;
29418 switch (win->layout->chart.slots[slot].type) {
29419 case NK_CHART_LINES:
29420 flags = nk_chart_push_line(ctx, win, &win->layout->chart, value, slot);
break;
29421 case NK_CHART_COLUMN:
29422 flags = nk_chart_push_column(ctx, win, &win->layout->chart, value, slot);
break;
29430nk_chart_push(
struct nk_context *ctx,
float value)
29432 return nk_chart_push_slot(ctx, value, 0);
29441 NK_ASSERT(ctx->current);
29442 if (!ctx || !ctx->current)
29445 win = ctx->current;
29446 chart = &win->layout->chart;
29447 NK_MEMSET(chart, 0,
sizeof(*chart));
29451nk_plot(
struct nk_context *ctx,
enum nk_chart_type type,
const float *values,
29452 int count,
int offset)
29460 if (!ctx || !values || !count)
return;
29462 min_value = values[offset];
29463 max_value = values[offset];
29464 for (i = 0; i < count; ++i) {
29465 min_value = NK_MIN(values[i + offset], min_value);
29466 max_value = NK_MAX(values[i + offset], max_value);
29469 if (nk_chart_begin(ctx, type, count, min_value, max_value)) {
29470 for (i = 0; i < count; ++i)
29471 nk_chart_push(ctx, values[i + offset]);
29476nk_plot_function(
struct nk_context *ctx,
enum nk_chart_type type,
void *userdata,
29477 float(*value_getter)(
void* user,
int index),
int count,
int offset)
29484 NK_ASSERT(value_getter);
29485 if (!ctx || !value_getter || !count)
return;
29487 max_value = min_value = value_getter(userdata, offset);
29488 for (i = 0; i < count; ++i) {
29489 float value = value_getter(userdata, i + offset);
29490 min_value = NK_MIN(value, min_value);
29491 max_value = NK_MAX(value, max_value);
29494 if (nk_chart_begin(ctx, type, count, min_value, max_value)) {
29495 for (i = 0; i < count; ++i)
29496 nk_chart_push(ctx, value_getter(userdata, i + offset));
29511nk_color_picker_behavior(nk_flags *state,
29517 nk_bool value_changed = 0;
29518 nk_bool hsv_changed = 0;
29522 NK_ASSERT(hue_bar);
29526 nk_colorf_hsva_fv(hsva, *color);
29527 if (nk_button_behavior(state, *matrix, in, NK_BUTTON_REPEATER)) {
29528 hsva[1] = NK_SATURATE((in->mouse.pos.x - matrix->x) / (matrix->w-1));
29529 hsva[2] = 1.0f - NK_SATURATE((in->mouse.pos.y - matrix->y) / (matrix->h-1));
29530 value_changed = hsv_changed = 1;
29533 if (nk_button_behavior(state, *hue_bar, in, NK_BUTTON_REPEATER)) {
29534 hsva[0] = NK_SATURATE((in->mouse.pos.y - hue_bar->y) / (hue_bar->h-1));
29535 value_changed = hsv_changed = 1;
29539 if (nk_button_behavior(state, *alpha_bar, in, NK_BUTTON_REPEATER)) {
29540 hsva[3] = 1.0f - NK_SATURATE((in->mouse.pos.y - alpha_bar->y) / (alpha_bar->h-1));
29544 nk_widget_state_reset(state);
29546 *color = nk_hsva_colorfv(hsva);
29549 if (value_changed) {
29550 color->a = hsva[3];
29554 if (nk_input_is_mouse_hovering_rect(in, *bounds))
29558 else if (nk_input_is_mouse_prev_hovering_rect(in, *bounds))
29560 return value_changed;
29567 NK_STORAGE
const struct nk_color black = {0,0,0,255};
29568 NK_STORAGE
const struct nk_color white = {255, 255, 255, 255};
29569 NK_STORAGE
const struct nk_color black_trans = {0,0,0,0};
29571 const float crosshair_size = 7.0f;
29579 NK_ASSERT(hue_bar);
29582 nk_colorf_hsva_fv(hsva, col);
29583 for (i = 0; i < 6; ++i) {
29584 NK_GLOBAL
const struct nk_color hue_colors[] = {
29585 {255, 0, 0, 255}, {255,255,0,255}, {0,255,0,255}, {0, 255,255,255},
29586 {0,0,255,255}, {255, 0, 255, 255}, {255, 0, 0, 255}
29588 nk_fill_rect_multi_color(o,
29589 nk_rect(hue_bar->x, hue_bar->y + (
float)i * (hue_bar->h/6.0f) + 0.5f,
29590 hue_bar->w, (hue_bar->h/6.0f) + 0.5f), hue_colors[i], hue_colors[i],
29591 hue_colors[i+1], hue_colors[i+1]);
29593 line_y = (float)(
int)(hue_bar->y + hsva[0] * matrix->h + 0.5f);
29594 nk_stroke_line(o, hue_bar->x-1, line_y, hue_bar->x + hue_bar->w + 2,
29595 line_y, 1, nk_rgb(255,255,255));
29599 float alpha = NK_SATURATE(col.a);
29600 line_y = (float)(
int)(alpha_bar->y + (1.0f - alpha) * matrix->h + 0.5f);
29602 nk_fill_rect_multi_color(o, *alpha_bar, white, white, black, black);
29603 nk_stroke_line(o, alpha_bar->x-1, line_y, alpha_bar->x + alpha_bar->w + 2,
29604 line_y, 1, nk_rgb(255,255,255));
29608 temp = nk_hsv_f(hsva[0], 1.0f, 1.0f);
29609 nk_fill_rect_multi_color(o, *matrix, white, temp, temp, white);
29610 nk_fill_rect_multi_color(o, *matrix, black_trans, black_trans, black, black);
29613 {
struct nk_vec2 p;
float S = hsva[1];
float V = hsva[2];
29614 p.x = (float)(
int)(matrix->x + S * matrix->w);
29615 p.y = (float)(
int)(matrix->y + (1.0f - V) * matrix->h);
29616 nk_stroke_line(o, p.x - crosshair_size, p.y, p.x-2, p.y, 1.0f, white);
29617 nk_stroke_line(o, p.x + crosshair_size + 1, p.y, p.x+3, p.y, 1.0f, white);
29618 nk_stroke_line(o, p.x, p.y + crosshair_size + 1, p.x, p.y+3, 1.0f, white);
29619 nk_stroke_line(o, p.x, p.y - crosshair_size, p.x, p.y-2, 1.0f, white);}
29622nk_do_color_picker(nk_flags *state,
29624 enum nk_color_format fmt,
struct nk_rect bounds,
29638 if (!out || !col || !state || !font)
29642 bounds.x += padding.x;
29643 bounds.y += padding.x;
29644 bounds.w -= 2 * padding.x;
29645 bounds.h -= 2 * padding.y;
29647 matrix.x = bounds.x;
29648 matrix.y = bounds.y;
29649 matrix.h = bounds.h;
29650 matrix.w = bounds.w - (3 * padding.x + 2 * bar_w);
29653 hue_bar.y = bounds.y;
29654 hue_bar.h = matrix.h;
29655 hue_bar.x = matrix.x + matrix.w + padding.x;
29657 alpha_bar.x = hue_bar.x + hue_bar.w + padding.x;
29658 alpha_bar.y = bounds.y;
29659 alpha_bar.w = bar_w;
29660 alpha_bar.h = matrix.h;
29662 ret = nk_color_picker_behavior(state, &bounds, &matrix, &hue_bar,
29663 (fmt == NK_RGBA) ? &alpha_bar:0, col, in);
29664 nk_draw_color_picker(out, &matrix, &hue_bar, (fmt == NK_RGBA) ? &alpha_bar:0, *col);
29669 enum nk_color_format fmt)
29681 NK_ASSERT(ctx->current);
29682 NK_ASSERT(ctx->current->layout);
29683 if (!ctx || !ctx->current || !ctx->current->layout || !color)
29686 win = ctx->current;
29687 config = &ctx->style;
29688 layout = win->layout;
29689 state = nk_widget(&bounds, ctx);
29690 if (!state)
return 0;
29692 return nk_do_color_picker(&ctx->last_widget_state, &win->buffer, color, fmt, bounds,
29693 nk_vec2(0,0), in, config->font);
29697 enum nk_color_format fmt)
29699 nk_color_pick(ctx, &color, fmt);
29723 NK_ASSERT(ctx->current);
29724 NK_ASSERT(ctx->current->layout);
29725 if (!ctx || !ctx->current || !ctx->current->layout)
29728 popup = win->popup.win;
29731 body.y = header.y + header.h-ctx->style.window.combo_border;
29734 hash = win->popup.combo_count++;
29735 is_open = (popup) ? nk_true:nk_false;
29736 is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_COMBO);
29737 if ((is_clicked && is_open && !is_active) || (is_open && !is_active) ||
29738 (!is_open && !is_active && !is_clicked))
return 0;
29739 if (!nk_nonblock_begin(ctx, 0, body,
29740 (is_clicked && is_open)?
nk_rect(0,0,0,0):header, NK_PANEL_COMBO)) return 0;
29742 win->popup.type = NK_PANEL_COMBO;
29743 win->popup.name = hash;
29747nk_combo_begin_text(
struct nk_context *ctx,
const char *selected,
int len,
29755 int is_clicked = nk_false;
29758 struct nk_text text;
29761 NK_ASSERT(selected);
29762 NK_ASSERT(ctx->current);
29763 NK_ASSERT(ctx->current->layout);
29764 if (!ctx || !ctx->current || !ctx->current->layout || !selected)
29767 win = ctx->current;
29768 style = &ctx->style;
29769 s = nk_widget(&header, ctx);
29774 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
29775 is_clicked = nk_true;
29779 background = &style->combo.active;
29780 text.text = style->combo.label_active;
29782 background = &style->combo.hover;
29783 text.text = style->combo.label_hover;
29785 background = &style->combo.normal;
29786 text.text = style->combo.label_normal;
29789 text.text = nk_rgb_factor(text.text, style->combo.color_factor);
29791 switch(background->type) {
29792 case NK_STYLE_ITEM_IMAGE:
29793 text.background = nk_rgba(0, 0, 0, 0);
29794 nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor));
29796 case NK_STYLE_ITEM_NINE_SLICE:
29797 text.background = nk_rgba(0, 0, 0, 0);
29798 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor));
29800 case NK_STYLE_ITEM_COLOR:
29801 text.background = background->data.color;
29802 nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor));
29803 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor));
29811 int draw_button_symbol;
29813 enum nk_symbol_type sym;
29815 sym = style->combo.sym_hover;
29816 else if (is_clicked)
29817 sym = style->combo.sym_active;
29819 sym = style->combo.sym_normal;
29822 draw_button_symbol = sym != NK_SYMBOL_NONE;
29825 button.w = header.h - 2 * style->combo.button_padding.y;
29826 button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
29827 button.y = header.y + style->combo.button_padding.y;
29828 button.h = button.w;
29830 content.x = button.x + style->combo.button.padding.x;
29831 content.y = button.y + style->combo.button.padding.y;
29832 content.w = button.w - 2 * style->combo.button.padding.x;
29833 content.h = button.h - 2 * style->combo.button.padding.y;
29837 label.x = header.x + style->combo.content_padding.x;
29838 label.y = header.y + style->combo.content_padding.y;
29839 label.h = header.h - 2 * style->combo.content_padding.y;
29840 if (draw_button_symbol)
29841 label.w = button.x - (style->combo.content_padding.x + style->combo.spacing.x) - label.x;
29843 label.w = header.w - 2 * style->combo.content_padding.x;
29844 nk_widget_text(&win->buffer, label, selected, len, &text,
29845 NK_TEXT_LEFT, ctx->style.font);
29848 if (draw_button_symbol)
29849 nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
29850 &ctx->style.combo.button, sym, style->font);
29852 return nk_combo_begin(ctx, win, size, is_clicked, header);
29855nk_combo_begin_label(
struct nk_context *ctx,
const char *selected,
struct nk_vec2 size)
29857 return nk_combo_begin_text(ctx, selected, nk_strlen(selected), size);
29867 int is_clicked = nk_false;
29872 NK_ASSERT(ctx->current);
29873 NK_ASSERT(ctx->current->layout);
29874 if (!ctx || !ctx->current || !ctx->current->layout)
29877 win = ctx->current;
29878 style = &ctx->style;
29879 s = nk_widget(&header, ctx);
29884 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
29885 is_clicked = nk_true;
29889 background = &style->combo.active;
29891 background = &style->combo.hover;
29892 else background = &style->combo.normal;
29894 switch(background->type) {
29895 case NK_STYLE_ITEM_IMAGE:
29896 nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor));
29898 case NK_STYLE_ITEM_NINE_SLICE:
29899 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor));
29901 case NK_STYLE_ITEM_COLOR:
29902 nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor));
29903 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor));
29910 int draw_button_symbol;
29912 enum nk_symbol_type sym;
29914 sym = style->combo.sym_hover;
29915 else if (is_clicked)
29916 sym = style->combo.sym_active;
29917 else sym = style->combo.sym_normal;
29920 draw_button_symbol = sym != NK_SYMBOL_NONE;
29923 button.w = header.h - 2 * style->combo.button_padding.y;
29924 button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
29925 button.y = header.y + style->combo.button_padding.y;
29926 button.h = button.w;
29928 content.x = button.x + style->combo.button.padding.x;
29929 content.y = button.y + style->combo.button.padding.y;
29930 content.w = button.w - 2 * style->combo.button.padding.x;
29931 content.h = button.h - 2 * style->combo.button.padding.y;
29934 bounds.h = header.h - 4 * style->combo.content_padding.y;
29935 bounds.y = header.y + 2 * style->combo.content_padding.y;
29936 bounds.x = header.x + 2 * style->combo.content_padding.x;
29937 if (draw_button_symbol)
29938 bounds.w = (button.x - (style->combo.content_padding.x + style->combo.spacing.x)) - bounds.x;
29940 bounds.w = header.w - 4 * style->combo.content_padding.x;
29941 nk_fill_rect(&win->buffer, bounds, 0, nk_rgb_factor(color, style->combo.color_factor));
29944 if (draw_button_symbol)
29945 nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
29946 &ctx->style.combo.button, sym, style->font);
29948 return nk_combo_begin(ctx, win, size, is_clicked, header);
29951nk_combo_begin_symbol(
struct nk_context *ctx,
enum nk_symbol_type symbol,
struct nk_vec2 size)
29958 int is_clicked = nk_false;
29965 NK_ASSERT(ctx->current);
29966 NK_ASSERT(ctx->current->layout);
29967 if (!ctx || !ctx->current || !ctx->current->layout)
29970 win = ctx->current;
29971 style = &ctx->style;
29972 s = nk_widget(&header, ctx);
29977 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
29978 is_clicked = nk_true;
29982 background = &style->combo.active;
29983 symbol_color = style->combo.symbol_active;
29985 background = &style->combo.hover;
29986 symbol_color = style->combo.symbol_hover;
29988 background = &style->combo.normal;
29989 symbol_color = style->combo.symbol_hover;
29992 symbol_color = nk_rgb_factor(symbol_color, style->combo.color_factor);
29994 switch(background->type) {
29995 case NK_STYLE_ITEM_IMAGE:
29996 sym_background = nk_rgba(0, 0, 0, 0);
29997 nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor));
29999 case NK_STYLE_ITEM_NINE_SLICE:
30000 sym_background = nk_rgba(0, 0, 0, 0);
30001 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor));
30003 case NK_STYLE_ITEM_COLOR:
30004 sym_background = background->data.color;
30005 nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor));
30006 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor));
30010 struct nk_rect bounds = {0,0,0,0};
30014 enum nk_symbol_type sym;
30016 sym = style->combo.sym_hover;
30017 else if (is_clicked)
30018 sym = style->combo.sym_active;
30019 else sym = style->combo.sym_normal;
30022 button.w = header.h - 2 * style->combo.button_padding.y;
30023 button.x = (header.x + header.w - header.h) - style->combo.button_padding.y;
30024 button.y = header.y + style->combo.button_padding.y;
30025 button.h = button.w;
30027 content.x = button.x + style->combo.button.padding.x;
30028 content.y = button.y + style->combo.button.padding.y;
30029 content.w = button.w - 2 * style->combo.button.padding.x;
30030 content.h = button.h - 2 * style->combo.button.padding.y;
30033 bounds.h = header.h - 2 * style->combo.content_padding.y;
30034 bounds.y = header.y + style->combo.content_padding.y;
30035 bounds.x = header.x + style->combo.content_padding.x;
30036 bounds.w = (button.x - style->combo.content_padding.y) - bounds.x;
30037 nk_draw_symbol(&win->buffer, symbol, bounds, sym_background, symbol_color,
30038 1.0f, style->font);
30041 nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state,
30042 &ctx->style.combo.button, sym, style->font);
30044 return nk_combo_begin(ctx, win, size, is_clicked, header);
30047nk_combo_begin_symbol_text(
struct nk_context *ctx,
const char *selected,
int len,
30048 enum nk_symbol_type symbol,
struct nk_vec2 size)
30055 int is_clicked = nk_false;
30059 struct nk_text text;
30062 NK_ASSERT(ctx->current);
30063 NK_ASSERT(ctx->current->layout);
30064 if (!ctx || !ctx->current || !ctx->current->layout)
30067 win = ctx->current;
30068 style = &ctx->style;
30069 s = nk_widget(&header, ctx);
30073 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
30074 is_clicked = nk_true;
30078 background = &style->combo.active;
30079 symbol_color = style->combo.symbol_active;
30080 text.text = style->combo.label_active;
30082 background = &style->combo.hover;
30083 symbol_color = style->combo.symbol_hover;
30084 text.text = style->combo.label_hover;
30086 background = &style->combo.normal;
30087 symbol_color = style->combo.symbol_normal;
30088 text.text = style->combo.label_normal;
30091 text.text = nk_rgb_factor(text.text, style->combo.color_factor);
30092 symbol_color = nk_rgb_factor(symbol_color, style->combo.color_factor);
30094 switch(background->type) {
30095 case NK_STYLE_ITEM_IMAGE:
30096 text.background = nk_rgba(0, 0, 0, 0);
30097 nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor));
30099 case NK_STYLE_ITEM_NINE_SLICE:
30100 text.background = nk_rgba(0, 0, 0, 0);
30101 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor));
30103 case NK_STYLE_ITEM_COLOR:
30104 text.background = background->data.color;
30105 nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor));
30106 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor));
30115 enum nk_symbol_type sym;
30117 sym = style->combo.sym_hover;
30118 else if (is_clicked)
30119 sym = style->combo.sym_active;
30120 else sym = style->combo.sym_normal;
30123 button.w = header.h - 2 * style->combo.button_padding.y;
30124 button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
30125 button.y = header.y + style->combo.button_padding.y;
30126 button.h = button.w;
30128 content.x = button.x + style->combo.button.padding.x;
30129 content.y = button.y + style->combo.button.padding.y;
30130 content.w = button.w - 2 * style->combo.button.padding.x;
30131 content.h = button.h - 2 * style->combo.button.padding.y;
30132 nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
30133 &ctx->style.combo.button, sym, style->font);
30136 image.x = header.x + style->combo.content_padding.x;
30137 image.y = header.y + style->combo.content_padding.y;
30138 image.h = header.h - 2 * style->combo.content_padding.y;
30140 nk_draw_symbol(&win->buffer, symbol, image, text.background, symbol_color,
30141 1.0f, style->font);
30145 label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x;
30146 label.y = header.y + style->combo.content_padding.y;
30147 label.w = (button.x - style->combo.content_padding.x) - label.x;
30148 label.h = header.h - 2 * style->combo.content_padding.y;
30149 nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font);
30151 return nk_combo_begin(ctx, win, size, is_clicked, header);
30161 int is_clicked = nk_false;
30166 NK_ASSERT(ctx->current);
30167 NK_ASSERT(ctx->current->layout);
30168 if (!ctx || !ctx->current || !ctx->current->layout)
30171 win = ctx->current;
30172 style = &ctx->style;
30173 s = nk_widget(&header, ctx);
30178 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
30179 is_clicked = nk_true;
30183 background = &style->combo.active;
30185 background = &style->combo.hover;
30186 else background = &style->combo.normal;
30188 switch (background->type) {
30189 case NK_STYLE_ITEM_IMAGE:
30190 nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor));
30192 case NK_STYLE_ITEM_NINE_SLICE:
30193 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor));
30195 case NK_STYLE_ITEM_COLOR:
30196 nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor));
30197 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor));
30201 struct nk_rect bounds = {0,0,0,0};
30204 int draw_button_symbol;
30206 enum nk_symbol_type sym;
30208 sym = style->combo.sym_hover;
30209 else if (is_clicked)
30210 sym = style->combo.sym_active;
30211 else sym = style->combo.sym_normal;
30214 draw_button_symbol = sym != NK_SYMBOL_NONE;
30217 button.w = header.h - 2 * style->combo.button_padding.y;
30218 button.x = (header.x + header.w - header.h) - style->combo.button_padding.y;
30219 button.y = header.y + style->combo.button_padding.y;
30220 button.h = button.w;
30222 content.x = button.x + style->combo.button.padding.x;
30223 content.y = button.y + style->combo.button.padding.y;
30224 content.w = button.w - 2 * style->combo.button.padding.x;
30225 content.h = button.h - 2 * style->combo.button.padding.y;
30228 bounds.h = header.h - 2 * style->combo.content_padding.y;
30229 bounds.y = header.y + style->combo.content_padding.y;
30230 bounds.x = header.x + style->combo.content_padding.x;
30231 if (draw_button_symbol)
30232 bounds.w = (button.x - style->combo.content_padding.y) - bounds.x;
30234 bounds.w = header.w - 2 * style->combo.content_padding.x;
30235 nk_draw_image(&win->buffer, bounds, &img, nk_rgb_factor(nk_white, style->combo.color_factor));
30238 if (draw_button_symbol)
30239 nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state,
30240 &ctx->style.combo.button, sym, style->font);
30242 return nk_combo_begin(ctx, win, size, is_clicked, header);
30245nk_combo_begin_image_text(
struct nk_context *ctx,
const char *selected,
int len,
30253 int is_clicked = nk_false;
30256 struct nk_text text;
30259 NK_ASSERT(ctx->current);
30260 NK_ASSERT(ctx->current->layout);
30261 if (!ctx || !ctx->current || !ctx->current->layout)
30264 win = ctx->current;
30265 style = &ctx->style;
30266 s = nk_widget(&header, ctx);
30270 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
30271 is_clicked = nk_true;
30275 background = &style->combo.active;
30276 text.text = style->combo.label_active;
30278 background = &style->combo.hover;
30279 text.text = style->combo.label_hover;
30281 background = &style->combo.normal;
30282 text.text = style->combo.label_normal;
30285 text.text = nk_rgb_factor(text.text, style->combo.color_factor);
30287 switch(background->type) {
30288 case NK_STYLE_ITEM_IMAGE:
30289 text.background = nk_rgba(0, 0, 0, 0);
30290 nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor));
30292 case NK_STYLE_ITEM_NINE_SLICE:
30293 text.background = nk_rgba(0, 0, 0, 0);
30294 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor));
30296 case NK_STYLE_ITEM_COLOR:
30297 text.background = background->data.color;
30298 nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor));
30299 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor));
30307 int draw_button_symbol;
30309 enum nk_symbol_type sym;
30311 sym = style->combo.sym_hover;
30312 else if (is_clicked)
30313 sym = style->combo.sym_active;
30314 else sym = style->combo.sym_normal;
30317 draw_button_symbol = sym != NK_SYMBOL_NONE;
30320 button.w = header.h - 2 * style->combo.button_padding.y;
30321 button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
30322 button.y = header.y + style->combo.button_padding.y;
30323 button.h = button.w;
30325 content.x = button.x + style->combo.button.padding.x;
30326 content.y = button.y + style->combo.button.padding.y;
30327 content.w = button.w - 2 * style->combo.button.padding.x;
30328 content.h = button.h - 2 * style->combo.button.padding.y;
30329 if (draw_button_symbol)
30330 nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
30331 &ctx->style.combo.button, sym, style->font);
30334 image.x = header.x + style->combo.content_padding.x;
30335 image.y = header.y + style->combo.content_padding.y;
30336 image.h = header.h - 2 * style->combo.content_padding.y;
30338 nk_draw_image(&win->buffer, image, &img, nk_rgb_factor(nk_white, style->combo.color_factor));
30342 label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x;
30343 label.y = header.y + style->combo.content_padding.y;
30344 label.h = header.h - 2 * style->combo.content_padding.y;
30345 if (draw_button_symbol)
30346 label.w = (button.x - style->combo.content_padding.x) - label.x;
30348 label.w = (header.x + header.w - style->combo.content_padding.x) - label.x;
30349 nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font);
30351 return nk_combo_begin(ctx, win, size, is_clicked, header);
30354nk_combo_begin_symbol_label(
struct nk_context *ctx,
30355 const char *selected,
enum nk_symbol_type type,
struct nk_vec2 size)
30357 return nk_combo_begin_symbol_text(ctx, selected, nk_strlen(selected), type, size);
30360nk_combo_begin_image_label(
struct nk_context *ctx,
30363 return nk_combo_begin_image_text(ctx, selected, nk_strlen(selected), img, size);
30366nk_combo_item_text(
struct nk_context *ctx,
const char *text,
int len,nk_flags align)
30368 return nk_contextual_item_text(ctx, text, len, align);
30371nk_combo_item_label(
struct nk_context *ctx,
const char *label, nk_flags align)
30373 return nk_contextual_item_label(ctx, label, align);
30376nk_combo_item_image_text(
struct nk_context *ctx,
struct nk_image img,
const char *text,
30377 int len, nk_flags alignment)
30379 return nk_contextual_item_image_text(ctx, img, text, len, alignment);
30383 const char *text, nk_flags alignment)
30385 return nk_contextual_item_image_label(ctx, img, text, alignment);
30388nk_combo_item_symbol_text(
struct nk_context *ctx,
enum nk_symbol_type sym,
30389 const char *text,
int len, nk_flags alignment)
30391 return nk_contextual_item_symbol_text(ctx, sym, text, len, alignment);
30394nk_combo_item_symbol_label(
struct nk_context *ctx,
enum nk_symbol_type sym,
30395 const char *label, nk_flags alignment)
30397 return nk_contextual_item_symbol_label(ctx, sym, label, alignment);
30399NK_API
void nk_combo_end(
struct nk_context *ctx)
30401 nk_contextual_end(ctx);
30403NK_API
void nk_combo_close(
struct nk_context *ctx)
30405 nk_contextual_close(ctx);
30408nk_combo(
struct nk_context *ctx,
const char *
const *items,
int count,
30409 int selected,
int item_height,
struct nk_vec2 size)
30414 struct nk_vec2 window_padding;
30418 NK_ASSERT(ctx->current);
30419 if (!ctx || !items ||!count)
30422 item_spacing = ctx->style.window.spacing;
30423 window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
30424 max_height = count * item_height + count * (int)item_spacing.y;
30425 max_height += (int)item_spacing.y * 2 + (
int)window_padding.y * 2;
30426 size.y = NK_MIN(size.y, (
float)max_height);
30427 if (nk_combo_begin_label(ctx, items[selected], size)) {
30429 for (i = 0; i < count; ++i) {
30430 if (nk_combo_item_label(ctx, items[i], NK_TEXT_LEFT))
30438nk_combo_separator(
struct nk_context *ctx,
const char *items_separated_by_separator,
30439 int separator,
int selected,
int count,
int item_height,
struct nk_vec2 size)
30444 struct nk_vec2 window_padding;
30445 const char *current_item;
30450 NK_ASSERT(items_separated_by_separator);
30451 if (!ctx || !items_separated_by_separator)
30455 item_spacing = ctx->style.window.spacing;
30456 window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
30457 max_height = count * item_height + count * (int)item_spacing.y;
30458 max_height += (int)item_spacing.y * 2 + (
int)window_padding.y * 2;
30459 size.y = NK_MIN(size.y, (
float)max_height);
30462 current_item = items_separated_by_separator;
30463 for (i = 0; i < count; ++i) {
30464 iter = current_item;
30465 while (*iter && *iter != separator) iter++;
30466 length = (int)(iter - current_item);
30467 if (i == selected)
break;
30468 current_item = iter + 1;
30471 if (nk_combo_begin_text(ctx, current_item, length, size)) {
30472 current_item = items_separated_by_separator;
30474 for (i = 0; i < count; ++i) {
30475 iter = current_item;
30476 while (*iter && *iter != separator) iter++;
30477 length = (int)(iter - current_item);
30478 if (nk_combo_item_text(ctx, current_item, length, NK_TEXT_LEFT))
30480 current_item = current_item + length + 1;
30487nk_combo_string(
struct nk_context *ctx,
const char *items_separated_by_zeros,
30488 int selected,
int count,
int item_height,
struct nk_vec2 size)
30490 return nk_combo_separator(ctx, items_separated_by_zeros,
'\0', selected, count, item_height, size);
30493nk_combo_callback(
struct nk_context *ctx,
void(*item_getter)(
void*,
int,
const char**),
30494 void *userdata,
int selected,
int count,
int item_height,
struct nk_vec2 size)
30499 struct nk_vec2 window_padding;
30503 NK_ASSERT(item_getter);
30504 if (!ctx || !item_getter)
30508 item_spacing = ctx->style.window.spacing;
30509 window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
30510 max_height = count * item_height + count * (int)item_spacing.y;
30511 max_height += (int)item_spacing.y * 2 + (
int)window_padding.y * 2;
30512 size.y = NK_MIN(size.y, (
float)max_height);
30514 item_getter(userdata, selected, &item);
30515 if (nk_combo_begin_label(ctx, item, size)) {
30517 for (i = 0; i < count; ++i) {
30518 item_getter(userdata, i, &item);
30519 if (nk_combo_item_label(ctx, item, NK_TEXT_LEFT))
30526nk_combobox(
struct nk_context *ctx,
const char *
const *items,
int count,
30527 int *selected,
int item_height,
struct nk_vec2 size)
30529 *selected = nk_combo(ctx, items, count, *selected, item_height, size);
30532nk_combobox_string(
struct nk_context *ctx,
const char *items_separated_by_zeros,
30533 int *selected,
int count,
int item_height,
struct nk_vec2 size)
30535 *selected = nk_combo_string(ctx, items_separated_by_zeros, *selected, count, item_height, size);
30538nk_combobox_separator(
struct nk_context *ctx,
const char *items_separated_by_separator,
30539 int separator,
int *selected,
int count,
int item_height,
struct nk_vec2 size)
30541 *selected = nk_combo_separator(ctx, items_separated_by_separator, separator,
30542 *selected, count, item_height, size);
30546 void(*item_getter)(
void* data,
int id,
const char **out_text),
30547 void *userdata,
int *selected,
int count,
int item_height,
struct nk_vec2 size)
30549 *selected = nk_combo_callback(ctx, item_getter, userdata, *selected, count, item_height, size);
30561nk_tooltip_begin(
struct nk_context *ctx,
float width)
30570 NK_ASSERT(ctx->current);
30571 NK_ASSERT(ctx->current->layout);
30572 if (!ctx || !ctx->current || !ctx->current->layout)
30576 win = ctx->current;
30578 if (win->popup.win && ((
int)win->popup.type & (
int)NK_PANEL_SET_NONBLOCK))
30581 w = nk_iceilf(width);
30582 h = nk_iceilf(nk_null_rect.h);
30583 x = nk_ifloorf(in->mouse.pos.x + 1) - (int)win->layout->clip.x;
30584 y = nk_ifloorf(in->mouse.pos.y + 1) - (int)win->layout->clip.y;
30586 bounds.x = (float)x;
30587 bounds.y = (float)y;
30588 bounds.w = (float)w;
30589 bounds.h = (float)h;
30591 ret = nk_popup_begin(ctx, NK_POPUP_DYNAMIC,
30592 "__##Tooltip##__", NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER, bounds);
30594 win->popup.type = NK_PANEL_TOOLTIP;
30595 ctx->current->layout->type = NK_PANEL_TOOLTIP;
30603 NK_ASSERT(ctx->current);
30604 if (!ctx || !ctx->current)
return;
30605 ctx->current->seq--;
30606 nk_popup_close(ctx);
30610nk_tooltip(
struct nk_context *ctx,
const char *text)
30620 NK_ASSERT(ctx->current);
30621 NK_ASSERT(ctx->current->layout);
30623 if (!ctx || !ctx->current || !ctx->current->layout || !text)
30627 style = &ctx->style;
30628 padding = style->window.padding;
30631 text_len = nk_strlen(text);
30632 text_width = style->font->
width(style->font->userdata,
30633 style->font->
height, text, text_len);
30634 text_width += (4 * padding.x);
30635 text_height = (style->font->
height + 2 * padding.y);
30638 if (nk_tooltip_begin(ctx, (
float)text_width)) {
30640 nk_text(ctx, text, text_len, NK_TEXT_LEFT);
30641 nk_tooltip_end(ctx);
30644#ifdef NK_INCLUDE_STANDARD_VARARGS
30646nk_tooltipf(
struct nk_context *ctx,
const char *fmt, ...)
30649 va_start(args, fmt);
30650 nk_tooltipfv(ctx, fmt, args);
30654nk_tooltipfv(
struct nk_context *ctx,
const char *fmt, va_list args)
30657 nk_strfmt(buf, NK_LEN(buf), fmt, args);
30658 nk_tooltip(ctx, buf);
float vec2[2]
2D vector of floats
Definition Structs.h:190
NK_API void nk_tree_pop(struct nk_context *)
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. Requires a previous layouting function to specify a pos/size.
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)
NK_API void nk_spacer(struct nk_context *ctx)
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)
NK_API void nk_rule_horizontal(struct nk_context *ctx, struct nk_color color, nk_bool rounding)
NK_API void nk_layout_space_end(struct nk_context *)
NK_API nk_bool nk_init_fixed(struct nk_context *, void *memory, nk_size size, const struct nk_user_font *)
NK_API void nk_property_float(struct nk_context *, const char *name, float min, float *val, float max, float step, float inc_per_pixel)
nk_window_flags
Definition nuklear.h:5712
@ NK_WINDOW_CLOSED
Definition nuklear.h:5718
@ NK_WINDOW_MINIMIZED
Definition nuklear.h:5719
@ NK_WINDOW_HIDDEN
Definition nuklear.h:5717
@ NK_WINDOW_ROM
Definition nuklear.h:5715
@ NK_WINDOW_NOT_INTERACTIVE
Definition nuklear.h:5716
@ NK_WINDOW_DYNAMIC
Definition nuklear.h:5714
@ NK_WINDOW_REMOVE_ROM
Definition nuklear.h:5720
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)
NK_API nk_bool nk_window_is_hovered(const struct nk_context *ctx)
NK_API void nk_window_collapse_if(struct nk_context *ctx, const char *name, enum nk_collapse_states state, int cond)
NK_API struct nk_vec2 nk_layout_space_to_screen(const struct nk_context *ctx, struct nk_vec2 vec)
#define NK_UTF_INVALID
Definition nuklear.h:244
#define NK_BOOL
Definition nuklear.h:415
NK_API struct nk_command_buffer * nk_window_get_canvas(const struct nk_context *ctx)
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)
NK_API void nk_window_set_scroll(struct nk_context *ctx, nk_uint offset_x, nk_uint offset_y)
NK_API void nk_group_scrolled_end(struct nk_context *)
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 *)
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 nk_bool nk_window_is_active(const struct nk_context *ctx, const char *name)
NK_API void nk_group_get_scroll(struct nk_context *, const char *id, nk_uint *x_offset, nk_uint *y_offset)
NK_API struct nk_vec2 nk_layout_space_to_local(const struct nk_context *ctx, struct nk_vec2 vec)
NK_API void nk_window_set_focus(struct nk_context *ctx, const char *name)
NK_API nk_bool nk_item_is_any_active(const struct nk_context *ctx)
#define NK_UTF_SIZE
Definition nuklear.h:245
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)
NK_API void nk_property_double(struct nk_context *, const char *name, double min, double *val, double max, double step, float inc_per_pixel)
NK_API void nk_fill_rect(struct nk_command_buffer *, struct nk_rect, float rounding, struct nk_color)
NK_API void nk_layout_row_template_push_static(struct nk_context *, float width)
NK_API struct nk_vec2 nk_window_get_content_region_size(const struct nk_context *ctx)
NK_API struct nk_panel * nk_window_get_panel(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)
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)
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)
NK_API void nk_window_set_position(struct nk_context *ctx, const char *name, struct nk_vec2 pos)
NK_API void nk_window_show(struct nk_context *ctx, const char *name, enum nk_show_states state)
NK_API nk_bool nk_window_is_collapsed(const struct nk_context *ctx, const char *name)
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 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_window_collapse(struct nk_context *ctx, const char *name, enum nk_collapse_states state)
NK_API nk_bool nk_filter_default(const struct nk_text_edit *, nk_rune unicode)
NK_API void nk_layout_row_template_end(struct nk_context *)
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 *)
nk_widget_states
Definition nuklear.h:3310
@ NK_WIDGET_STATE_LEFT
Definition nuklear.h:3316
@ NK_WIDGET_STATE_ACTIVED
Definition nuklear.h:3315
@ NK_WIDGET_STATE_ENTERED
Definition nuklear.h:3313
@ NK_WIDGET_STATE_HOVER
Definition nuklear.h:3314
@ NK_WIDGET_STATE_ACTIVE
Definition nuklear.h:3318
@ NK_WIDGET_STATE_HOVERED
Definition nuklear.h:3317
NK_API struct nk_window * nk_window_find(const struct nk_context *ctx, const char *name)
NK_API struct nk_rect nk_layout_space_rect_to_local(const struct nk_context *ctx, struct nk_rect bounds)
NK_API void nk_window_set_bounds(struct nk_context *ctx, const char *name, struct nk_rect bounds)
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)
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)
NK_API void nk_layout_set_min_row_height(struct nk_context *, float height)
NK_API void nk_window_show_if(struct nk_context *ctx, const char *name, enum nk_show_states state, int cond)
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. Requires a previous layouting function to specify a pos/size.
NK_API nk_bool nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, struct nk_rect bounds, nk_flags flags)
#define nk_foreach(c, ctx)
Iterates over each draw command inside the context draw command list.
Definition nuklear.h:1254
NK_API void nk_layout_space_push(struct nk_context *, struct nk_rect bounds)
NK_API nk_bool nk_begin(struct nk_context *ctx, const char *title, struct nk_rect bounds, nk_flags flags)
NK_API void nk_window_set_size(struct nk_context *ctx, const char *name, struct nk_vec2 size)
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)
NK_API void nk_layout_row_template_begin(struct nk_context *, float row_height)
NK_API nk_bool nk_init(struct nk_context *, const struct nk_allocator *, const struct nk_user_font *)
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 *)
NK_API void nk_layout_row_push(struct nk_context *, float value)
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)
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_layout_states
Definition nuklear.h:3304
@ NK_WIDGET_DISABLED
Definition nuklear.h:3308
@ NK_WIDGET_ROM
Definition nuklear.h:3307
@ NK_WIDGET_VALID
Definition nuklear.h:3306
@ NK_WIDGET_INVALID
Definition nuklear.h:3305
NK_API double nk_propertyd(struct nk_context *, const char *name, double min, double val, double max, double step, float inc_per_pixel)
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)
NK_API struct nk_rect nk_layout_space_bounds(const struct nk_context *ctx)
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 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)
NK_API void nk_group_end(struct nk_context *)
NK_API void nk_layout_row_template_push_variable(struct nk_context *, float min_width)
NK_API struct nk_vec2 nk_window_get_position(const struct nk_context *ctx)
nk_edit_events
Definition nuklear.h:3724
@ NK_EDIT_INACTIVE
Definition nuklear.h:3726
@ NK_EDIT_DEACTIVATED
Definition nuklear.h:3728
@ NK_EDIT_COMMITED
Definition nuklear.h:3729
@ NK_EDIT_ACTIVATED
Definition nuklear.h:3727
NK_API int nk_propertyi(struct nk_context *, const char *name, int min, int val, int max, int step, float inc_per_pixel)
NK_API nk_bool nk_group_scrolled_begin(struct nk_context *, struct nk_scroll *off, const char *title, nk_flags)
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)
Definition nuklear.h:4406
Definition nuklear.h:4412
struct nk_allocator pool
Definition nuklear.h:4414
struct nk_memory memory
Definition nuklear.h:4416
enum nk_allocation_type type
Definition nuklear.h:4415
nk_size needed
Definition nuklear.h:4419
nk_size size
Definition nuklear.h:4421
nk_size allocated
Definition nuklear.h:4418
float grow_factor
Definition nuklear.h:4417
nk_size calls
Definition nuklear.h:4420
Definition nuklear.h:5627
Definition nuklear.h:5638
Definition nuklear.h:4535
Definition nuklear.h:4789
Definition nuklear.h:4780
Definition nuklear.h:4855
Definition nuklear.h:4773
Definition nuklear.h:4765
Definition nuklear.h:4712
Definition nuklear.h:4830
Definition nuklear.h:4820
Definition nuklear.h:4704
Definition nuklear.h:4805
Definition nuklear.h:4797
Definition nuklear.h:4812
Definition nuklear.h:4730
Definition nuklear.h:4738
Definition nuklear.h:4721
Definition nuklear.h:4698
Definition nuklear.h:4838
Definition nuklear.h:4757
Definition nuklear.h:4748
Definition nuklear.h:4690
Definition nuklear.h:5874
Definition nuklear.h:5927
int build
Definition nuklear.h:5956
struct nk_text_edit text_edit
Definition nuklear.h:5951
struct nk_command_buffer overlay
Definition nuklear.h:5953
Definition nuklear.h:1201
enum nk_anti_aliasing shape_AA
Definition nuklear.h:1204
enum nk_anti_aliasing line_AA
Definition nuklear.h:1203
nk_size vertex_alignment
Definition nuklear.h:1211
nk_size vertex_size
Definition nuklear.h:1210
const struct nk_draw_vertex_layout_element * vertex_layout
Definition nuklear.h:1209
unsigned arc_segment_count
Definition nuklear.h:1206
unsigned circle_segment_count
Definition nuklear.h:1205
unsigned curve_segment_count
Definition nuklear.h:1207
struct nk_draw_null_texture tex_null
Definition nuklear.h:1208
Definition nuklear.h:1197
struct nk_vec2 uv
Definition nuklear.h:1199
Definition nuklear.h:5735
Definition nuklear.h:4912
Definition nuklear.h:4916
Definition nuklear.h:3288
Definition nuklear.h:4386
Definition nuklear.h:4411
Definition nuklear.h:4898
Definition nuklear.h:5904
Definition nuklear.h:5910
Definition nuklear.h:5685
Definition nuklear.h:5916
Definition nuklear.h:5748
Definition nuklear.h:5656
Definition nuklear.h:4449
Definition nuklear.h:5430
Definition nuklear.h:5446
Definition nuklear.h:5361
Definition nuklear.h:5113
Definition nuklear.h:5265
Definition nuklear.h:5298
Definition nuklear.h:5397
Definition nuklear.h:5187
Definition nuklear.h:5224
Definition nuklear.h:5479
Definition nuklear.h:5118
Definition nuklear.h:5155
Definition nuklear.h:5532
Definition nuklear.h:5569
Definition nuklear.h:5890
Definition nuklear.h:4568
Definition nuklear.h:4541
Definition nuklear.h:4548
Definition nuklear.h:4229
nk_text_width_f width
Definition nuklear.h:4232
float height
Definition nuklear.h:4231
Definition nuklear.h:5761
Definition nuklear.h:5898
Definition nuklear.h:5107