From 3504e2a5c552b682eb479cf53830499a7c525387 Mon Sep 17 00:00:00 2001 From: ryuukk Date: Wed, 25 Sep 2024 16:11:39 +0200 Subject: [PATCH 1/6] Make it so borders don't get clipped --- src/nuklear.h | 1 + src/nuklear_vertex.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/src/nuklear.h b/src/nuklear.h index 6a30b3947..2dbe5668b 100644 --- a/src/nuklear.h +++ b/src/nuklear.h @@ -5606,6 +5606,7 @@ struct nk_context { #define nk_ptr_add(t, p, i) ((t*)((void*)((nk_byte*)(p) + (i)))) #define nk_ptr_add_const(t, p, i) ((const t*)((const void*)((const nk_byte*)(p) + (i)))) #define nk_zero_struct(s) nk_zero(&s, sizeof(s)) +#define nk_div_round_closest(n, d) ((((n) < 0) == ((d) < 0)) ? (((n) + (d)/2)/(d)) : (((n) - (d)/2)/(d))) /* ============================================================== * ALIGNMENT diff --git a/src/nuklear_vertex.c b/src/nuklear_vertex.c index 10cff0456..03fe14c0f 100644 --- a/src/nuklear_vertex.c +++ b/src/nuklear_vertex.c @@ -973,6 +973,15 @@ nk_draw_list_stroke_rect(struct nk_draw_list *list, struct nk_rect rect, NK_ASSERT(list); if (!list || !col.a) return; if (list->line_AA == NK_ANTI_ALIASING_ON) { + /* borders will get cut off due to clipping + since widgets shrink the widget's area + the stroke needs to stay within its bounds + */ + float hl = nk_div_round_closest(thickness, 2.0); + rect.x += hl; + rect.w -= hl; + rect.y += hl; + rect.h -= hl; nk_draw_list_path_rect_to(list, nk_vec2(rect.x, rect.y), nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding); } else { From 156d85d7dc97777a805c0c74e4b9f015ac4b01da Mon Sep 17 00:00:00 2001 From: ryuukk Date: Wed, 25 Sep 2024 16:18:54 +0200 Subject: [PATCH 2/6] Shrink the w/h by the whole thickness --- src/nuklear_vertex.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nuklear_vertex.c b/src/nuklear_vertex.c index 03fe14c0f..c9799bff4 100644 --- a/src/nuklear_vertex.c +++ b/src/nuklear_vertex.c @@ -979,9 +979,9 @@ nk_draw_list_stroke_rect(struct nk_draw_list *list, struct nk_rect rect, */ float hl = nk_div_round_closest(thickness, 2.0); rect.x += hl; - rect.w -= hl; + rect.w -= thickness; rect.y += hl; - rect.h -= hl; + rect.h -= thickness; nk_draw_list_path_rect_to(list, nk_vec2(rect.x, rect.y), nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding); } else { From b8fb3bac87b92eb42a97bd887743ee16b5ebd0ac Mon Sep 17 00:00:00 2001 From: ryuukk Date: Wed, 25 Sep 2024 16:29:37 +0200 Subject: [PATCH 3/6] Substract the offset --- src/nuklear_vertex.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/nuklear_vertex.c b/src/nuklear_vertex.c index c9799bff4..74644422b 100644 --- a/src/nuklear_vertex.c +++ b/src/nuklear_vertex.c @@ -978,10 +978,13 @@ nk_draw_list_stroke_rect(struct nk_draw_list *list, struct nk_rect rect, the stroke needs to stay within its bounds */ float hl = nk_div_round_closest(thickness, 2.0); - rect.x += hl; - rect.w -= thickness; - rect.y += hl; - rect.h -= thickness; + if (hl > 0) + { + rect.x += hl - 0.5; + rect.w -= thickness; + rect.y += hl - 0.5; + rect.h -= thickness; + } nk_draw_list_path_rect_to(list, nk_vec2(rect.x, rect.y), nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding); } else { From 374778acaa1718cde5c1a44564e163ff2899a360 Mon Sep 17 00:00:00 2001 From: ryuukk Date: Wed, 25 Sep 2024 16:56:06 +0200 Subject: [PATCH 4/6] Added a way to specify what kind of stroke is needed, center/inner/outer --- src/nuklear.h | 3 +++ src/nuklear_button.c | 9 +++++---- src/nuklear_draw.c | 26 ++++++++++++++++++++++++++ src/nuklear_edit.c | 4 ++-- src/nuklear_vertex.c | 27 ++++++++++++++------------- 5 files changed, 50 insertions(+), 19 deletions(-) diff --git a/src/nuklear.h b/src/nuklear.h index 2dbe5668b..1c6ec39c9 100644 --- a/src/nuklear.h +++ b/src/nuklear.h @@ -4323,6 +4323,7 @@ struct nk_command_curve { struct nk_color color; }; +enum nk_stroke_type { NK_STROKE_CENTER, NK_STROKE_INNER, NK_STROKE_OUTER }; struct nk_command_rect { struct nk_command header; unsigned short rounding; @@ -4330,6 +4331,7 @@ struct nk_command_rect { short x, y; unsigned short w, h; struct nk_color color; + enum nk_stroke_type stroke_type; }; struct nk_command_rect_filled { @@ -4469,6 +4471,7 @@ struct nk_command_buffer { NK_API void nk_stroke_line(struct nk_command_buffer *b, float x0, float y0, float x1, float y1, float line_thickness, struct nk_color); NK_API void nk_stroke_curve(struct nk_command_buffer*, float, float, float, float, float, float, float, float, float line_thickness, struct nk_color); NK_API void nk_stroke_rect(struct nk_command_buffer*, struct nk_rect, float rounding, float line_thickness, struct nk_color); +NK_API void nk_stroke_rect_ex(struct nk_command_buffer*, struct nk_rect, float rounding, float line_thickness, struct nk_color, enum nk_stroke_type); NK_API void nk_stroke_circle(struct nk_command_buffer*, struct nk_rect, float line_thickness, struct nk_color); NK_API void nk_stroke_arc(struct nk_command_buffer*, float cx, float cy, float radius, float a_min, float a_max, float line_thickness, struct nk_color); NK_API void nk_stroke_triangle(struct nk_command_buffer*, float, float, float, float, float, float, float line_thichness, struct nk_color); diff --git a/src/nuklear_button.c b/src/nuklear_button.c index 6ef845997..b1360f2ee 100644 --- a/src/nuklear_button.c +++ b/src/nuklear_button.c @@ -111,16 +111,17 @@ nk_draw_button(struct nk_command_buffer *out, background = &style->active; else background = &style->normal; + struct nk_rect b = *bounds; switch (background->type) { case NK_STYLE_ITEM_IMAGE: - nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor_background)); + nk_draw_image(out, b, &background->data.image, nk_rgb_factor(nk_white, style->color_factor_background)); break; case NK_STYLE_ITEM_NINE_SLICE: - nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor_background)); + nk_draw_nine_slice(out, b, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor_background)); break; case NK_STYLE_ITEM_COLOR: - nk_fill_rect(out, *bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor_background)); - nk_stroke_rect(out, *bounds, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor_background)); + nk_fill_rect(out, style->border != 0 ? nk_shrink_rect(b, style->border * 0.5) : b, style->rounding, nk_rgb_factor(background->data.color, style->color_factor_background)); + nk_stroke_rect_ex(out, b, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor_background), NK_STROKE_INNER); break; } return background; diff --git a/src/nuklear_draw.c b/src/nuklear_draw.c index efdf9c59b..5b61f2927 100644 --- a/src/nuklear_draw.c +++ b/src/nuklear_draw.c @@ -132,6 +132,31 @@ nk_stroke_rect(struct nk_command_buffer *b, struct nk_rect rect, struct nk_command_rect *cmd; NK_ASSERT(b); if (!b || c.a == 0 || rect.w == 0 || rect.h == 0 || line_thickness <= 0) return; + + if (b->use_clipping) { + const struct nk_rect *clip = &b->clip; + if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h, + clip->x, clip->y, clip->w, clip->h)) return; + } + cmd = (struct nk_command_rect*) + nk_command_buffer_push(b, NK_COMMAND_RECT, sizeof(*cmd)); + if (!cmd) return; + cmd->rounding = (unsigned short)rounding; + cmd->line_thickness = (unsigned short)line_thickness; + cmd->x = (short)rect.x; + cmd->y = (short)rect.y; + cmd->w = (unsigned short)NK_MAX(0, rect.w); + cmd->h = (unsigned short)NK_MAX(0, rect.h); + cmd->color = c; +} +NK_API void +nk_stroke_rect_ex(struct nk_command_buffer *b, struct nk_rect rect, + float rounding, float line_thickness, struct nk_color c, enum nk_stroke_type stroke_type) +{ + struct nk_command_rect *cmd; + NK_ASSERT(b); + if (!b || c.a == 0 || rect.w == 0 || rect.h == 0 || line_thickness <= 0) return; + if (b->use_clipping) { const struct nk_rect *clip = &b->clip; if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h, @@ -147,6 +172,7 @@ nk_stroke_rect(struct nk_command_buffer *b, struct nk_rect rect, cmd->w = (unsigned short)NK_MAX(0, rect.w); cmd->h = (unsigned short)NK_MAX(0, rect.h); cmd->color = c; + cmd->stroke_type = stroke_type; } NK_API void nk_fill_rect(struct nk_command_buffer *b, struct nk_rect rect, diff --git a/src/nuklear_edit.c b/src/nuklear_edit.c index a7b2bfcf1..9e8a80d55 100644 --- a/src/nuklear_edit.c +++ b/src/nuklear_edit.c @@ -340,8 +340,8 @@ nk_do_edit(nk_flags *state, struct nk_command_buffer *out, nk_draw_nine_slice(out, bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor)); break; case NK_STYLE_ITEM_COLOR: - nk_fill_rect(out, bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor)); - nk_stroke_rect(out, bounds, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor)); + nk_fill_rect(out, style->border != 0 ? nk_shrink_rect(bounds, 0.5) : bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor)); + nk_stroke_rect_ex(out, bounds, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor), NK_STROKE_INNER); break; }} diff --git a/src/nuklear_vertex.c b/src/nuklear_vertex.c index 74644422b..7a9cb1130 100644 --- a/src/nuklear_vertex.c +++ b/src/nuklear_vertex.c @@ -973,18 +973,6 @@ nk_draw_list_stroke_rect(struct nk_draw_list *list, struct nk_rect rect, NK_ASSERT(list); if (!list || !col.a) return; if (list->line_AA == NK_ANTI_ALIASING_ON) { - /* borders will get cut off due to clipping - since widgets shrink the widget's area - the stroke needs to stay within its bounds - */ - float hl = nk_div_round_closest(thickness, 2.0); - if (hl > 0) - { - rect.x += hl - 0.5; - rect.w -= thickness; - rect.y += hl - 0.5; - rect.h -= thickness; - } nk_draw_list_path_rect_to(list, nk_vec2(rect.x, rect.y), nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding); } else { @@ -1232,7 +1220,20 @@ nk_convert(struct nk_context *ctx, struct nk_buffer *cmds, config->curve_segment_count, q->line_thickness); } break; case NK_COMMAND_RECT: { - const struct nk_command_rect *r = (const struct nk_command_rect*)cmd; + struct nk_command_rect *r = (struct nk_command_rect*)cmd; + + if (r->stroke_type == NK_STROKE_INNER) + { + float hl = nk_div_round_closest(r->line_thickness, 2.0); + if (hl > 0) + { + r->x += hl; + r->w -= r->line_thickness; + r->y += hl; + r->h -= r->line_thickness; + } + } + nk_draw_list_stroke_rect(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h), r->color, (float)r->rounding, r->line_thickness); } break; From 59f2c7091788b7b22a8a5b17c8fa59a1c379ea24 Mon Sep 17 00:00:00 2001 From: ryuukk Date: Wed, 25 Sep 2024 17:07:24 +0200 Subject: [PATCH 5/6] Only inner with AA for now, until i figure out the rest --- src/nuklear_vertex.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/nuklear_vertex.c b/src/nuklear_vertex.c index 7a9cb1130..d49a9fc85 100644 --- a/src/nuklear_vertex.c +++ b/src/nuklear_vertex.c @@ -1227,12 +1227,23 @@ nk_convert(struct nk_context *ctx, struct nk_buffer *cmds, float hl = nk_div_round_closest(r->line_thickness, 2.0); if (hl > 0) { - r->x += hl; - r->w -= r->line_thickness; - r->y += hl; - r->h -= r->line_thickness; + if (config->line_AA == NK_ANTI_ALIASING_OFF) + { + r->x += hl; + r->w -= r->line_thickness; + r->y += hl; + r->h -= r->line_thickness; + } + else + { + /* TODO: i don't know yet */ + } } } + else + { + /* TODO: implement the rest */ + } nk_draw_list_stroke_rect(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h), r->color, (float)r->rounding, r->line_thickness); From f4cd2b55fbb2c8cd9f6f6ec85de2e6f7437ae309 Mon Sep 17 00:00:00 2001 From: ryuukk <44361234+ryuukk@users.noreply.github.com> Date: Wed, 25 Sep 2024 19:23:41 +0200 Subject: [PATCH 6/6] Default to center stroke --- src/nuklear_draw.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nuklear_draw.c b/src/nuklear_draw.c index 5b61f2927..c617ca38c 100644 --- a/src/nuklear_draw.c +++ b/src/nuklear_draw.c @@ -148,6 +148,7 @@ nk_stroke_rect(struct nk_command_buffer *b, struct nk_rect rect, cmd->w = (unsigned short)NK_MAX(0, rect.w); cmd->h = (unsigned short)NK_MAX(0, rect.h); cmd->color = c; + cmd->stroke_type = NK_STROKE_CENTER; } NK_API void nk_stroke_rect_ex(struct nk_command_buffer *b, struct nk_rect rect,