From 42afe2dfc3c9c2f724abf2e92b6693cf6144efe6 Mon Sep 17 00:00:00 2001 From: Phil Jones Date: Fri, 24 Jun 2022 15:46:01 +0100 Subject: Correct clipping with rounded corners. Currently the clipping region is still a plain rectangle bounded by the outer rounded rectangle. A rounded rectangle clip would be nice, but unfortunately Cairo leaves antialiasing artifacts if we do this. --- src/entry.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/entry.c b/src/entry.c index 9050874..9298ce8 100644 --- a/src/entry.c +++ b/src/entry.c @@ -6,6 +6,9 @@ #include "log.h" #include "nelem.h" +#undef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + static void rounded_rectangle(cairo_t *cr, uint32_t width, uint32_t height, uint32_t r) { cairo_new_path(cr); @@ -98,19 +101,30 @@ void entry_init(struct entry *entry, uint8_t *restrict buffer, uint32_t width, u /* Move and clip following draws to be within this outline */ - cairo_translate( - cr, - 2 * entry->border.outline_width + entry->border.width, - 2 * entry->border.outline_width + entry->border.width); - width -= 4 * entry->border.outline_width + 2 * entry->border.width; - height -= 4 * entry->border.outline_width + 2 * entry->border.width; + double dx = 2.0 * entry->border.outline_width + entry->border.width + entry->padding; + cairo_translate(cr, dx, dx); + width -= 2 * dx; + height -= 2 * dx; + + /* Account for rounded corners */ + double inner_radius = (double)entry->corner_radius + - 2.0 * entry->border.outline_width + - entry->border.width + - entry->padding; + inner_radius = MAX(inner_radius, 0); + + dx = ceil(inner_radius * (1.0 - 1.0 / M_SQRT2)); + cairo_translate(cr, dx, dx); + width -= 2 * dx; + height -= 2 * dx; cairo_rectangle(cr, 0, 0, width, height); cairo_clip(cr); /* Move and clip following draws to be within the specified padding */ - cairo_translate(cr, entry->padding, entry->padding); - width -= 2 * entry->padding; - height -= 2 * entry->padding; + dx = entry->padding; + cairo_translate(cr, dx, dx); + width -= 2 * dx; + height -= 2 * dx; cairo_rectangle(cr, 0, 0, width, height); cairo_clip(cr); -- cgit v1.2.3