Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions include/raylib-nuklear.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,15 @@ extern "C" {
#define RAYLIB_NUKLEAR_FONT_SPACING_RATIO 0.01f
#endif // RAYLIB_NUKLEAR_FONT_SPACING_RATIO

#ifndef RAYLIB_NUKLEAR_POLYGON_FILL_MAX_POINTS
/**
* The maximum amount of points allowed when drawing a filled polygon.
*
* @see NK_COMMAND_POLYGON_FILLED
*/
#define RAYLIB_NUKLEAR_POLYGON_FILL_MAX_POINTS 64
#endif // RAYLIB_NUKLEAR_POLYGON_FILL_MAX_POINTS

#ifndef RAYLIB_NUKLEAR_DEFAULT_ARC_SEGMENTS
/**
* The amount of segments used when drawing an arc.
Expand Down Expand Up @@ -563,9 +572,6 @@ NuklearImageToTexture(struct nk_image img)
*/
static void raylib_nuklear_draw_polygon_fill(float scale, const struct nk_vec2i *pnts, int count, Color col) {
int i = 0;
#ifndef RAYLIB_NUKLEAR_POLYGON_FILL_MAX_POINTS
#define RAYLIB_NUKLEAR_POLYGON_FILL_MAX_POINTS 64
#endif
int left = 10000, top = 10000, bottom = 0, right = 0;
int nodes, nodeX[RAYLIB_NUKLEAR_POLYGON_FILL_MAX_POINTS], pixelX, pixelY, j, swap ;

Expand Down Expand Up @@ -620,7 +626,7 @@ static void raylib_nuklear_draw_polygon_fill(float scale, const struct nk_vec2i
} else i++;
}
/* Fill the pixels between node pairs. */
for (i = 0; i < nodes; i += 2) {
for (i = 0; i + 1 < nodes; i += 2) {
if (nodeX[i+0] >= right) break;
if (nodeX[i+1] > left) {
if (nodeX[i+0] < left) nodeX[i+0] = left ;
Expand All @@ -632,7 +638,6 @@ static void raylib_nuklear_draw_polygon_fill(float scale, const struct nk_vec2i
}
}
}
#undef RAYLIB_NUKLEAR_POLYGON_FILL_MAX_POINTS
}

/**
Expand Down Expand Up @@ -829,9 +834,11 @@ DrawNuklear(struct nk_context * ctx)
Vector2 end = {(float)p->points[i + 1].x * scale, (float)p->points[i + 1].y * scale};
DrawLineEx(start, end, thickness, color);
}
Vector2 last = {(float)p->points[p->point_count - 1].x * scale, (float)p->points[p->point_count - 1].y * scale};
Vector2 first = {(float)p->points[0].x * scale, (float)p->points[0].y * scale};
DrawLineEx(last, first, thickness, color);
if (p->point_count >= 2) {
Vector2 last = {(float)p->points[p->point_count - 1].x * scale, (float)p->points[p->point_count - 1].y * scale};
Vector2 first = {(float)p->points[0].x * scale, (float)p->points[0].y * scale};
DrawLineEx(last, first, thickness, color);
}
} break;

case NK_COMMAND_POLYGON_FILLED: {
Expand Down
45 changes: 45 additions & 0 deletions test/raylib-nuklear-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,51 @@ int main(int argc, char *argv[]) {
UnloadNuklear(ctx);
}

// Degenerate polygons must not crash DrawNuklear().
// https://github.com/RobLoach/raylib-nuklear/issues/131
{
ctx = InitNuklear(10);
Assert(ctx);

UpdateNuklear(ctx);

if (nk_begin(ctx, "PolygonTest", nk_rect(0, 0, 100, 100),
NK_WINDOW_NO_SCROLLBAR)) {
struct nk_command_buffer* canvas = nk_window_get_canvas(ctx);
struct nk_color color = nk_rgb(230, 20, 20);

// No points.
nk_fill_polygon(canvas, NULL, 0, color);
nk_stroke_polygon(canvas, NULL, 0, 1.0f, color);

// A single point.
float single[] = {10.0f, 10.0f};
nk_fill_polygon(canvas, single, 1, color);
nk_stroke_polygon(canvas, single, 1, 1.0f, color);

// A self-touching polygon, where a repeated vertex touches the
// outline and can leave the scanline fill with an odd node count.
float touching[] = {
10.0f, 10.0f,
30.0f, 10.0f,
20.0f, 20.0f,
30.0f, 30.0f,
10.0f, 30.0f,
20.0f, 20.0f
};
nk_fill_polygon(canvas, touching, 6, color);
nk_stroke_polygon(canvas, touching, 6, 1.0f, color);
}
nk_end(ctx);

BeginDrawing();
ClearBackground(RAYWHITE);
DrawNuklear(ctx);
EndDrawing();

UnloadNuklear(ctx);
}

// A NULL context must not crash any of the public entry points.
{
UpdateNuklear(NULL);
Expand Down
Loading