diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/blocks/slider.c | 9 | ||||
| -rw-r--r-- | src/layout.c | 4 | ||||
| -rw-r--r-- | src/util.c | 30 | ||||
| -rw-r--r-- | src/util.h | 4 |
4 files changed, 40 insertions, 7 deletions
diff --git a/src/blocks/slider.c b/src/blocks/slider.c index 3fe6e8c..8c89ddf 100644 --- a/src/blocks/slider.c +++ b/src/blocks/slider.c @@ -30,7 +30,7 @@ static void block_slider_render(layout_t *layout, cairo_t *cr) const int radius = slider->height / 2; int bar_y = layout->y + (layout->height - slider->height) / 2; - int bar_x = layout->x + layout->height / 2; + int bar_x = layout->x + (layout->width - slider->width) / 2; cairo_matrix_t matrix; cairo_matrix_init_scale(&matrix, 1.0 / slider->width, 1.0); @@ -38,7 +38,7 @@ static void block_slider_render(layout_t *layout, cairo_t *cr) cairo_pattern_t *pattern = slider->bg_color.pattern; if (pattern != NULL) { - render_capsule(cr, bar_x, bar_y, slider->width, radius, slider->line_width); + render_capsule_fast(cr, bar_x, bar_y, slider->width, radius, radius); cairo_pattern_set_matrix(pattern, &matrix); cairo_set_source(cr, pattern); @@ -48,7 +48,7 @@ static void block_slider_render(layout_t *layout, cairo_t *cr) pattern = slider->bar_color.pattern; if (pattern != NULL) { int current = slider->width * (slider->value / 100.0); - render_capsule(cr, bar_x, bar_y, current, radius, slider->line_width); + render_capsule(cr, bar_x, bar_y, current, radius, radius); cairo_pattern_set_matrix(pattern, &matrix); cairo_set_source(cr, pattern); @@ -57,7 +57,8 @@ static void block_slider_render(layout_t *layout, cairo_t *cr) pattern = slider->line_color.pattern; if (pattern != NULL) { - render_capsule(cr, bar_x, bar_y, slider->width, radius, slider->line_width); + int line_radius = radius - slider->line_width / 2; + render_capsule_fast(cr, bar_x, bar_y, slider->width, radius, line_radius); cairo_pattern_set_matrix(pattern, &matrix); cairo_set_source(cr, pattern); diff --git a/src/layout.c b/src/layout.c index 193ebbd..bfc25c0 100644 --- a/src/layout.c +++ b/src/layout.c @@ -107,7 +107,7 @@ void layout_render(layout_t *layout, cairo_t *cr) // Render background cairo_pattern_t *pattern = layout->block->bg_color.pattern; if (pattern != NULL) { - render_capsule(cr, block_x, block_y, layout->width - layout->x_padding, radius, radius); + render_capsule_fast(cr, block_x, block_y, layout->width - layout->x_padding, radius, radius); cairo_pattern_set_matrix(pattern, &matrix); cairo_set_source(cr, pattern); @@ -118,7 +118,7 @@ void layout_render(layout_t *layout, cairo_t *cr) pattern = layout->block->line_color.pattern; if (pattern != NULL) { int line_radius = radius - layout->line_width / 2; - render_capsule(cr, block_x, block_y, layout->width - layout->x_padding, radius, line_radius); + render_capsule_fast(cr, block_x, block_y, layout->width - layout->x_padding, radius, line_radius); cairo_pattern_set_matrix(pattern, &matrix); cairo_set_source(cr, pattern); @@ -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; @@ -85,6 +85,10 @@ void strfree(char **list); bool iszero(const void *ptr, size_t size); +// Render a capsule shape. Cannot handle w < 2*r1 +void render_capsule_fast(cairo_t *cr, int x, int y, int w, int r1, int r2); + +// Render a capsule shape void render_capsule(cairo_t *cr, int x, int y, int w, int r1, int r2); typedef enum { |
