From bf144ceca6285af5ce9f64f1176cb104f78b9637 Mon Sep 17 00:00:00 2001 From: Phil Jones Date: Mon, 21 Nov 2022 23:59:14 +0000 Subject: Add --clip-to-padding option. --- completions/tofi | 1 + doc/config | 13 +++++++++---- doc/tofi.5.md | 8 ++++++++ doc/tofi.5.scd | 7 +++++++ src/config.c | 2 ++ src/entry.c | 49 ++++++++++++++++++++++++++++++++++++------------- src/entry.h | 1 + src/main.c | 2 ++ 8 files changed, 66 insertions(+), 17 deletions(-) diff --git a/completions/tofi b/completions/tofi index 999e83d..328f7dc 100644 --- a/completions/tofi +++ b/completions/tofi @@ -65,6 +65,7 @@ _tofi() --padding-bottom --padding-left --padding-right + --clip-to-padding --horizontal --hide-cursor --history diff --git a/doc/config b/doc/config index a008fbd..017aeb1 100644 --- a/doc/config +++ b/doc/config @@ -161,10 +161,15 @@ corner-radius = 0 # Padding between borders and text. Can be pixels or a percentage. - padding-top = 0 - padding-bottom = 0 - padding-left = 0 - padding-right = 0 + padding-top = 8 + padding-bottom = 8 + padding-left = 8 + padding-right = 8 + + # Whether to clip text drawing to be within the specified padding. This + # is mostly important for allowing text to be inset from the border, + # while still allowing text backgrounds to reach right to the edge. + clip-to-padding = true # Whether to scale the window by the output's scale factor. scale = true diff --git a/doc/tofi.5.md b/doc/tofi.5.md index d87e232..e8f3c49 100644 --- a/doc/tofi.5.md +++ b/doc/tofi.5.md @@ -530,6 +530,14 @@ options. > > Default: 8 +**clip-to-padding**=*true\|false* + +> Whether to clip text drawing to be within the specified padding. This +> is mostly important for allowing text to be inset from the border, +> while still allowing text backgrounds to reach right to the edge. +> +> Default: true + **horizontal**=*true\|false* > List results horizontally. diff --git a/doc/tofi.5.scd b/doc/tofi.5.scd index 53bdc68..72be59e 100644 --- a/doc/tofi.5.scd +++ b/doc/tofi.5.scd @@ -451,6 +451,13 @@ options. Default: 8 +*clip-to-padding*=_true|false_ + Whether to clip text drawing to be within the specified padding. This + is mostly important for allowing text to be inset from the border, + while still allowing text backgrounds to reach right to the edge. + + Default: true + *horizontal*=_true|false_ List results horizontally. diff --git a/src/config.c b/src/config.c index 3f2873d..470b4ae 100644 --- a/src/config.c +++ b/src/config.c @@ -480,6 +480,8 @@ bool parse_option(struct tofi *tofi, const char *filename, size_t lineno, const percent = parse_uint32_percent(filename, lineno, value, &err); tofi->window.entry.padding_right = percent.value; tofi->window.entry.padding_right_is_percent = percent.percent; + } else if (strcasecmp(option, "clip-to-padding") == 0) { + tofi->window.entry.clip_to_padding = parse_bool(filename, lineno, value, &err); } else if (strcasecmp(option, "horizontal") == 0) { tofi->window.entry.horizontal = parse_bool(filename, lineno, value, &err); } else if (strcasecmp(option, "hide-cursor") == 0) { diff --git a/src/entry.c b/src/entry.c index 9e05f57..6af9969 100644 --- a/src/entry.c +++ b/src/entry.c @@ -132,11 +132,18 @@ void entry_init(struct entry *entry, uint8_t *restrict buffer, uint32_t width, u cairo_set_operator(cr, CAIRO_OPERATOR_OVER); - /* Move and clip following draws to be within this outline + padding */ + /* Move and clip following draws to be within this outline */ double dx = 2.0 * entry->outline_width + entry->border_width; - cairo_translate(cr, dx + entry->padding_left, dx + entry->padding_top); - width -= 2 * dx + entry->padding_left + entry->padding_right; - height -= 2 * dx + entry->padding_top + entry->padding_bottom; + cairo_translate(cr, dx, dx); + width -= 2 * dx; + height -= 2 * dx; + + /* If we're clipping to the padding, account for that as well here */ + if (entry->clip_to_padding) { + cairo_translate(cr, entry->padding_left, entry->padding_top); + width -= entry->padding_left + entry->padding_right; + height -= entry->padding_top + entry->padding_bottom; + } /* Account for rounded corners */ double inner_radius = (double)entry->corner_radius - dx; @@ -149,6 +156,22 @@ void entry_init(struct entry *entry, uint8_t *restrict buffer, uint32_t width, u cairo_rectangle(cr, 0, 0, width, height); cairo_clip(cr); + /* Store the clip rectangle width and height. */ + cairo_matrix_t mat; + cairo_get_matrix(cr, &mat); + entry->clip_x = mat.x0; + entry->clip_y = mat.y0; + entry->clip_width = width; + entry->clip_height = height; + + /* + * If we're not clipping to the padding, we didn't account for it + * before. + */ + if (!entry->clip_to_padding) { + cairo_translate(cr, entry->padding_left, entry->padding_top); + } + /* Setup the backend. */ if (access(entry->font_name, R_OK) != 0) { /* @@ -163,17 +186,9 @@ void entry_init(struct entry *entry, uint8_t *restrict buffer, uint32_t width, u entry_backend_harfbuzz_init(entry, &width, &height); } - /* Store the clip rectangle width and height. */ - cairo_matrix_t mat; - cairo_get_matrix(cr, &mat); - entry->clip_x = mat.x0; - entry->clip_y = mat.y0; - entry->clip_width = width; - entry->clip_height = height; - /* * Before we render any text, ensure all text themes are fully - * specified. + * specified. */ const struct text_theme default_theme = { .foreground_color = entry->foreground_color, @@ -227,6 +242,14 @@ void entry_init(struct entry *entry, uint8_t *restrict buffer, uint32_t width, u cairo_set_matrix(entry->cairo[1].cr, &mat); cairo_rectangle(entry->cairo[1].cr, 0, 0, width, height); cairo_clip(entry->cairo[1].cr); + + /* + * If we're not clipping to the padding, the transformation matrix + * didn't include it, so account for it here. + */ + if (!entry->clip_to_padding) { + cairo_translate(entry->cairo[1].cr, entry->padding_left, entry->padding_top); + } } void entry_destroy(struct entry *entry) diff --git a/src/entry.h b/src/entry.h index 05e73ab..f5b5f79 100644 --- a/src/entry.h +++ b/src/entry.h @@ -92,6 +92,7 @@ struct entry { bool padding_bottom_is_percent; bool padding_left_is_percent; bool padding_right_is_percent; + bool clip_to_padding; int32_t selection_background_padding; uint32_t input_width; uint32_t border_width; diff --git a/src/main.c b/src/main.c index f9291ee..689e824 100644 --- a/src/main.c +++ b/src/main.c @@ -832,6 +832,7 @@ const struct option long_options[] = { {"padding-bottom", required_argument, NULL, 0}, {"padding-left", required_argument, NULL, 0}, {"padding-right", required_argument, NULL, 0}, + {"clip-to-padding", required_argument, NULL, 0}, {"horizontal", required_argument, NULL, 0}, {"hide-cursor", required_argument, NULL, 0}, {"history", required_argument, NULL, 0}, @@ -1063,6 +1064,7 @@ int main(int argc, char *argv[]) .padding_bottom = 8, .padding_left = 8, .padding_right = 8, + .clip_to_padding = true, .border_width = 12, .outline_width = 4, .background_color = {0.106f, 0.114f, 0.118f, 1.0f}, -- cgit v1.2.3