From fcd52f6db3dc9092dbd7a502e3e561ad16bf0743 Mon Sep 17 00:00:00 2001 From: Federico Angelilli Date: Wed, 20 Nov 2024 23:11:10 +0100 Subject: Fix capsule edge case --- src/util.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'src/util.c') diff --git a/src/util.c b/src/util.c index f9e00f2..b06fbae 100644 --- a/src/util.c +++ b/src/util.c @@ -214,9 +214,10 @@ bool iszero(const void *ptr, size_t size) return true; } -void render_capsule(cairo_t *cr, int x, int y, int w, int r1, int r2) +void render_capsule_fast(cairo_t *cr, int x, int y, int w, int r1, int r2) { const double degree = M_PI / 180.0; + assert(w >= r1 * 2); cairo_new_sub_path(cr); cairo_arc(cr, x + r1, y + r1, r2, 90 * degree, 270 * degree); @@ -224,6 +225,33 @@ void render_capsule(cairo_t *cr, int x, int y, int w, int r1, int r2) cairo_close_path(cr); } +void render_capsule(cairo_t *cr, int x, int y, int w, int r1, int r2) +{ + // Fast path + if (w >= r1 * 2) { + render_capsule_fast(cr, x, y, w, r1, r2); + return; + } + + if (w == 0) return; + + const double degree = M_PI / 180.0; + int x_off = -(r1 - w); + + double angle1 = acos(1.0 - (w / 2.0) / (double)r1); + double angle2 = acos(1.0 - (w / 2.0) / (double)r1); + + double left1 = 180 * degree - angle2, + left2 = 180 * degree + angle1, + right1 = 360 * degree - angle2, + right2 = angle2; + + cairo_new_sub_path(cr); + cairo_arc(cr, x + r1, y + r1, r2, left1, left2); + cairo_arc(cr, x + x_off, y + r1, r2, right1, right2); + cairo_close_path(cr); +} + int snprintf_units(char *buffer, size_t max, uint64_t bytes, unit_t unit) { int base = unit & UNIT_SI ? 1000 : 1024; -- cgit v1.2.3