diff options
Diffstat (limited to 'swaybar/render.c')
-rw-r--r-- | swaybar/render.c | 353 |
1 files changed, 209 insertions, 144 deletions
diff --git a/swaybar/render.c b/swaybar/render.c index df066622..92b73f4c 100644 --- a/swaybar/render.c +++ b/swaybar/render.c | |||
@@ -5,7 +5,7 @@ | |||
5 | #include <stdlib.h> | 5 | #include <stdlib.h> |
6 | #include <stdint.h> | 6 | #include <stdint.h> |
7 | #include <string.h> | 7 | #include <string.h> |
8 | #include "cairo.h" | 8 | #include "cairo_util.h" |
9 | #include "pango.h" | 9 | #include "pango.h" |
10 | #include "pool-buffer.h" | 10 | #include "pool-buffer.h" |
11 | #include "swaybar/bar.h" | 11 | #include "swaybar/bar.h" |
@@ -14,6 +14,7 @@ | |||
14 | #include "swaybar/ipc.h" | 14 | #include "swaybar/ipc.h" |
15 | #include "swaybar/render.h" | 15 | #include "swaybar/render.h" |
16 | #include "swaybar/status_line.h" | 16 | #include "swaybar/status_line.h" |
17 | #include "log.h" | ||
17 | #if HAVE_TRAY | 18 | #if HAVE_TRAY |
18 | #include "swaybar/tray/tray.h" | 19 | #include "swaybar/tray/tray.h" |
19 | #endif | 20 | #endif |
@@ -23,28 +24,51 @@ static const int WS_HORIZONTAL_PADDING = 5; | |||
23 | static const double WS_VERTICAL_PADDING = 1.5; | 24 | static const double WS_VERTICAL_PADDING = 1.5; |
24 | static const double BORDER_WIDTH = 1; | 25 | static const double BORDER_WIDTH = 1; |
25 | 26 | ||
26 | static uint32_t render_status_line_error(cairo_t *cairo, | 27 | struct render_context { |
27 | struct swaybar_output *output, double *x) { | 28 | cairo_t *cairo; |
29 | struct swaybar_output *output; | ||
30 | cairo_font_options_t *textaa_sharp; | ||
31 | cairo_font_options_t *textaa_safe; | ||
32 | uint32_t background_color; | ||
33 | }; | ||
34 | |||
35 | static void choose_text_aa_mode(struct render_context *ctx, uint32_t fontcolor) { | ||
36 | uint32_t salpha = fontcolor & 0xFF; | ||
37 | uint32_t balpha = ctx->background_color & 0xFF; | ||
38 | |||
39 | // Subpixel antialiasing requires blend be done in cairo, not compositor | ||
40 | cairo_font_options_t *fo = salpha == balpha ? | ||
41 | ctx->textaa_sharp : ctx->textaa_safe; | ||
42 | cairo_set_font_options(ctx->cairo, fo); | ||
43 | |||
44 | // Color emojis, being semitransparent bitmaps, are leaky with 'SOURCE' | ||
45 | cairo_operator_t op = salpha == 0xFF ? | ||
46 | CAIRO_OPERATOR_OVER : CAIRO_OPERATOR_SOURCE; | ||
47 | cairo_set_operator(ctx->cairo, op); | ||
48 | } | ||
49 | |||
50 | static uint32_t render_status_line_error(struct render_context *ctx, double *x) { | ||
51 | struct swaybar_output *output = ctx->output; | ||
28 | const char *error = output->bar->status->text; | 52 | const char *error = output->bar->status->text; |
29 | if (!error) { | 53 | if (!error) { |
30 | return 0; | 54 | return 0; |
31 | } | 55 | } |
32 | 56 | ||
33 | uint32_t height = output->height * output->scale; | 57 | uint32_t height = output->height; |
34 | 58 | ||
59 | cairo_t *cairo = ctx->cairo; | ||
35 | cairo_set_source_u32(cairo, 0xFF0000FF); | 60 | cairo_set_source_u32(cairo, 0xFF0000FF); |
36 | 61 | ||
37 | int margin = 3 * output->scale; | 62 | int margin = 3; |
38 | double ws_vertical_padding = | 63 | double ws_vertical_padding = output->bar->config->status_padding; |
39 | output->bar->config->status_padding * output->scale; | ||
40 | 64 | ||
41 | char *font = output->bar->config->font; | 65 | char *font = output->bar->config->font; |
42 | int text_width, text_height; | 66 | int text_width, text_height; |
43 | get_text_size(cairo, font, &text_width, &text_height, NULL, | 67 | get_text_size(cairo, font, &text_width, &text_height, NULL, |
44 | output->scale, false, "%s", error); | 68 | 1, false, "%s", error); |
45 | 69 | ||
46 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; | 70 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; |
47 | uint32_t ideal_surface_height = ideal_height / output->scale; | 71 | uint32_t ideal_surface_height = ideal_height; |
48 | if (!output->bar->config->height && | 72 | if (!output->bar->config->height && |
49 | output->height < ideal_surface_height) { | 73 | output->height < ideal_surface_height) { |
50 | return ideal_surface_height; | 74 | return ideal_surface_height; |
@@ -53,42 +77,45 @@ static uint32_t render_status_line_error(cairo_t *cairo, | |||
53 | 77 | ||
54 | double text_y = height / 2.0 - text_height / 2.0; | 78 | double text_y = height / 2.0 - text_height / 2.0; |
55 | cairo_move_to(cairo, *x, (int)floor(text_y)); | 79 | cairo_move_to(cairo, *x, (int)floor(text_y)); |
56 | pango_printf(cairo, font, output->scale, false, "%s", error); | 80 | choose_text_aa_mode(ctx, 0xFF0000FF); |
81 | render_text(cairo, font, 1, false, "%s", error); | ||
57 | *x -= margin; | 82 | *x -= margin; |
58 | return output->height; | 83 | return output->height; |
59 | } | 84 | } |
60 | 85 | ||
61 | static uint32_t render_status_line_text(cairo_t *cairo, | 86 | static uint32_t render_status_line_text(struct render_context *ctx, double *x) { |
62 | struct swaybar_output *output, double *x) { | 87 | struct swaybar_output *output = ctx->output; |
63 | const char *text = output->bar->status->text; | 88 | const char *text = output->bar->status->text; |
64 | if (!text) { | 89 | if (!text) { |
65 | return 0; | 90 | return 0; |
66 | } | 91 | } |
67 | 92 | ||
93 | cairo_t *cairo = ctx->cairo; | ||
68 | struct swaybar_config *config = output->bar->config; | 94 | struct swaybar_config *config = output->bar->config; |
69 | cairo_set_source_u32(cairo, output->focused ? | 95 | uint32_t fontcolor = output->focused ? |
70 | config->colors.focused_statusline : config->colors.statusline); | 96 | config->colors.focused_statusline : config->colors.statusline; |
97 | cairo_set_source_u32(cairo, fontcolor); | ||
71 | 98 | ||
72 | int text_width, text_height; | 99 | int text_width, text_height; |
73 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, | 100 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, |
74 | output->scale, config->pango_markup, "%s", text); | 101 | 1, config->pango_markup, "%s", text); |
75 | 102 | ||
76 | double ws_vertical_padding = config->status_padding * output->scale; | 103 | double ws_vertical_padding = config->status_padding; |
77 | int margin = 3 * output->scale; | 104 | int margin = 3; |
78 | 105 | ||
79 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; | 106 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; |
80 | uint32_t ideal_surface_height = ideal_height / output->scale; | 107 | uint32_t ideal_surface_height = ideal_height; |
81 | if (!output->bar->config->height && | 108 | if (!output->bar->config->height && |
82 | output->height < ideal_surface_height) { | 109 | output->height < ideal_surface_height) { |
83 | return ideal_surface_height; | 110 | return ideal_surface_height; |
84 | } | 111 | } |
85 | 112 | ||
86 | *x -= text_width + margin; | 113 | *x -= text_width + margin; |
87 | uint32_t height = output->height * output->scale; | 114 | uint32_t height = output->height; |
88 | double text_y = height / 2.0 - text_height / 2.0; | 115 | double text_y = height / 2.0 - text_height / 2.0; |
89 | cairo_move_to(cairo, *x, (int)floor(text_y)); | 116 | cairo_move_to(cairo, *x, (int)floor(text_y)); |
90 | pango_printf(cairo, config->font, output->scale, | 117 | choose_text_aa_mode(ctx, fontcolor); |
91 | config->pango_markup, "%s", text); | 118 | render_text(cairo, config->font, 1, config->pango_markup, "%s", text); |
92 | *x -= margin; | 119 | *x -= margin; |
93 | return output->height; | 120 | return output->height; |
94 | } | 121 | } |
@@ -96,6 +123,7 @@ static uint32_t render_status_line_text(cairo_t *cairo, | |||
96 | static void render_sharp_rectangle(cairo_t *cairo, uint32_t color, | 123 | static void render_sharp_rectangle(cairo_t *cairo, uint32_t color, |
97 | double x, double y, double width, double height) { | 124 | double x, double y, double width, double height) { |
98 | cairo_save(cairo); | 125 | cairo_save(cairo); |
126 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); | ||
99 | cairo_set_source_u32(cairo, color); | 127 | cairo_set_source_u32(cairo, color); |
100 | cairo_set_antialias(cairo, CAIRO_ANTIALIAS_NONE); | 128 | cairo_set_antialias(cairo, CAIRO_ANTIALIAS_NONE); |
101 | cairo_rectangle(cairo, x, y, width, height); | 129 | cairo_rectangle(cairo, x, y, width, height); |
@@ -109,6 +137,7 @@ static void render_sharp_line(cairo_t *cairo, uint32_t color, | |||
109 | render_sharp_rectangle(cairo, color, x, y, width, height); | 137 | render_sharp_rectangle(cairo, color, x, y, width, height); |
110 | } else { | 138 | } else { |
111 | cairo_save(cairo); | 139 | cairo_save(cairo); |
140 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); | ||
112 | cairo_set_source_u32(cairo, color); | 141 | cairo_set_source_u32(cairo, color); |
113 | cairo_set_antialias(cairo, CAIRO_ANTIALIAS_NONE); | 142 | cairo_set_antialias(cairo, CAIRO_ANTIALIAS_NONE); |
114 | if (width == 1) { | 143 | if (width == 1) { |
@@ -135,10 +164,10 @@ static enum hotspot_event_handling block_hotspot_callback( | |||
135 | struct i3bar_block *block = data; | 164 | struct i3bar_block *block = data; |
136 | struct status_line *status = output->bar->status; | 165 | struct status_line *status = output->bar->status; |
137 | return i3bar_block_send_click(status, block, x, y, | 166 | return i3bar_block_send_click(status, block, x, y, |
138 | x - (double)hotspot->x / output->scale, | 167 | x - (double)hotspot->x, |
139 | y - (double)hotspot->y / output->scale, | 168 | y - (double)hotspot->y, |
140 | (double)hotspot->width / output->scale, | 169 | (double)hotspot->width, |
141 | (double)hotspot->height / output->scale, | 170 | (double)hotspot->height, |
142 | output->scale, button); | 171 | output->scale, button); |
143 | } | 172 | } |
144 | 173 | ||
@@ -146,9 +175,8 @@ static void i3bar_block_unref_callback(void *data) { | |||
146 | i3bar_block_unref(data); | 175 | i3bar_block_unref(data); |
147 | } | 176 | } |
148 | 177 | ||
149 | static uint32_t render_status_block(cairo_t *cairo, | 178 | static uint32_t render_status_block(struct render_context *ctx, |
150 | struct swaybar_output *output, struct i3bar_block *block, double *x, | 179 | struct i3bar_block *block, double *x, bool edge, bool use_short_text) { |
151 | bool edge, bool use_short_text) { | ||
152 | if (!block->full_text || !*block->full_text) { | 180 | if (!block->full_text || !*block->full_text) { |
153 | return 0; | 181 | return 0; |
154 | } | 182 | } |
@@ -158,20 +186,21 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
158 | text = block->short_text; | 186 | text = block->short_text; |
159 | } | 187 | } |
160 | 188 | ||
189 | cairo_t *cairo = ctx->cairo; | ||
190 | struct swaybar_output *output = ctx->output; | ||
161 | struct swaybar_config *config = output->bar->config; | 191 | struct swaybar_config *config = output->bar->config; |
162 | |||
163 | int text_width, text_height; | 192 | int text_width, text_height; |
164 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, | 193 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, 1, |
165 | output->scale, block->markup, "%s", text); | 194 | block->markup, "%s", text); |
166 | 195 | ||
167 | int margin = 3 * output->scale; | 196 | int margin = 3; |
168 | double ws_vertical_padding = config->status_padding * output->scale; | 197 | double ws_vertical_padding = config->status_padding; |
169 | 198 | ||
170 | int width = text_width; | 199 | int width = text_width; |
171 | if (block->min_width_str) { | 200 | if (block->min_width_str) { |
172 | int w; | 201 | int w; |
173 | get_text_size(cairo, config->font, &w, NULL, NULL, | 202 | get_text_size(cairo, config->font, &w, NULL, NULL, 1, block->markup, |
174 | output->scale, block->markup, "%s", block->min_width_str); | 203 | "%s", block->min_width_str); |
175 | block->min_width = w; | 204 | block->min_width = w; |
176 | } | 205 | } |
177 | if (width < block->min_width) { | 206 | if (width < block->min_width) { |
@@ -180,20 +209,20 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
180 | 209 | ||
181 | double block_width = width; | 210 | double block_width = width; |
182 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; | 211 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; |
183 | uint32_t ideal_surface_height = ideal_height / output->scale; | 212 | uint32_t ideal_surface_height = ideal_height; |
184 | if (!output->bar->config->height && | 213 | if (!output->bar->config->height && |
185 | output->height < ideal_surface_height) { | 214 | output->height < ideal_surface_height) { |
186 | return ideal_surface_height; | 215 | return ideal_surface_height; |
187 | } | 216 | } |
188 | 217 | ||
189 | *x -= width; | 218 | *x -= width; |
190 | if ((block->border || block->urgent) && block->border_left > 0) { | 219 | if ((block->border_set || block->urgent) && block->border_left > 0) { |
191 | *x -= (block->border_left * output->scale + margin); | 220 | *x -= (block->border_left + margin); |
192 | block_width += block->border_left * output->scale + margin; | 221 | block_width += block->border_left + margin; |
193 | } | 222 | } |
194 | if ((block->border || block->urgent) && block->border_right > 0) { | 223 | if ((block->border_set || block->urgent) && block->border_right > 0) { |
195 | *x -= (block->border_right * output->scale + margin); | 224 | *x -= (block->border_right + margin); |
196 | block_width += block->border_right * output->scale + margin; | 225 | block_width += block->border_right + margin; |
197 | } | 226 | } |
198 | 227 | ||
199 | int sep_width, sep_height; | 228 | int sep_width, sep_height; |
@@ -201,9 +230,9 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
201 | if (!edge) { | 230 | if (!edge) { |
202 | if (config->sep_symbol) { | 231 | if (config->sep_symbol) { |
203 | get_text_size(cairo, config->font, &sep_width, &sep_height, NULL, | 232 | get_text_size(cairo, config->font, &sep_width, &sep_height, NULL, |
204 | output->scale, false, "%s", config->sep_symbol); | 233 | 1, false, "%s", config->sep_symbol); |
205 | uint32_t _ideal_height = sep_height + ws_vertical_padding * 2; | 234 | uint32_t _ideal_height = sep_height + ws_vertical_padding * 2; |
206 | uint32_t _ideal_surface_height = _ideal_height / output->scale; | 235 | uint32_t _ideal_surface_height = _ideal_height; |
207 | if (!output->bar->config->height && | 236 | if (!output->bar->config->height && |
208 | output->height < _ideal_surface_height) { | 237 | output->height < _ideal_surface_height) { |
209 | return _ideal_surface_height; | 238 | return _ideal_surface_height; |
@@ -214,10 +243,10 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
214 | } | 243 | } |
215 | *x -= sep_block_width; | 244 | *x -= sep_block_width; |
216 | } else if (config->status_edge_padding) { | 245 | } else if (config->status_edge_padding) { |
217 | *x -= config->status_edge_padding * output->scale; | 246 | *x -= config->status_edge_padding; |
218 | } | 247 | } |
219 | 248 | ||
220 | uint32_t height = output->height * output->scale; | 249 | uint32_t height = output->height; |
221 | if (output->bar->status->click_events) { | 250 | if (output->bar->status->click_events) { |
222 | struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); | 251 | struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); |
223 | hotspot->x = *x; | 252 | hotspot->x = *x; |
@@ -240,23 +269,26 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
240 | if (bg_color) { | 269 | if (bg_color) { |
241 | render_sharp_rectangle(cairo, bg_color, x_pos, y_pos, | 270 | render_sharp_rectangle(cairo, bg_color, x_pos, y_pos, |
242 | block_width, render_height); | 271 | block_width, render_height); |
272 | ctx->background_color = bg_color; | ||
243 | } | 273 | } |
244 | 274 | ||
245 | uint32_t border_color = block->urgent | 275 | uint32_t border_color = block->urgent |
246 | ? config->colors.urgent_workspace.border : block->border; | 276 | ? config->colors.urgent_workspace.border : block->border; |
247 | if (border_color && block->border_top > 0) { | 277 | if (block->border_set || block->urgent) { |
248 | render_sharp_line(cairo, border_color, x_pos, y_pos, | 278 | if (block->border_top > 0) { |
249 | block_width, block->border_top * output->scale); | 279 | render_sharp_line(cairo, border_color, x_pos, y_pos, |
250 | } | 280 | block_width, block->border_top); |
251 | if (border_color && block->border_bottom > 0) { | 281 | } |
252 | render_sharp_line(cairo, border_color, x_pos, | 282 | if (block->border_bottom > 0) { |
253 | y_pos + render_height - block->border_bottom * output->scale, | 283 | render_sharp_line(cairo, border_color, x_pos, |
254 | block_width, block->border_bottom * output->scale); | 284 | y_pos + render_height - block->border_bottom, |
255 | } | 285 | block_width, block->border_bottom); |
256 | if (border_color && block->border_left > 0) { | 286 | } |
257 | render_sharp_line(cairo, border_color, x_pos, y_pos, | 287 | if (block->border_left > 0) { |
258 | block->border_left * output->scale, render_height); | 288 | render_sharp_line(cairo, border_color, x_pos, y_pos, |
259 | x_pos += block->border_left * output->scale + margin; | 289 | block->border_left, render_height); |
290 | } | ||
291 | x_pos += block->border_left + margin; | ||
260 | } | 292 | } |
261 | 293 | ||
262 | double offset = 0; | 294 | double offset = 0; |
@@ -274,30 +306,35 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
274 | color = block->color_set ? block->color : color; | 306 | color = block->color_set ? block->color : color; |
275 | color = block->urgent ? config->colors.urgent_workspace.text : color; | 307 | color = block->urgent ? config->colors.urgent_workspace.text : color; |
276 | cairo_set_source_u32(cairo, color); | 308 | cairo_set_source_u32(cairo, color); |
277 | pango_printf(cairo, config->font, output->scale, | 309 | choose_text_aa_mode(ctx, color); |
278 | block->markup, "%s", text); | 310 | render_text(cairo, config->font, 1, block->markup, "%s", text); |
279 | x_pos += width; | 311 | x_pos += width; |
280 | 312 | ||
281 | if (block->border && block->border_right > 0) { | 313 | if (block->border_set || block->urgent) { |
282 | x_pos += margin; | 314 | x_pos += margin; |
283 | render_sharp_line(cairo, border_color, x_pos, y_pos, | 315 | if (block->border_right > 0) { |
284 | block->border_right * output->scale, render_height); | 316 | render_sharp_line(cairo, border_color, x_pos, y_pos, |
285 | x_pos += block->border_right * output->scale; | 317 | block->border_right, render_height); |
318 | } | ||
319 | x_pos += block->border_right; | ||
286 | } | 320 | } |
287 | 321 | ||
288 | if (!edge && block->separator) { | 322 | if (!edge && block->separator) { |
289 | if (output->focused) { | 323 | if (output->focused) { |
290 | cairo_set_source_u32(cairo, config->colors.focused_separator); | 324 | color = config->colors.focused_separator; |
291 | } else { | 325 | } else { |
292 | cairo_set_source_u32(cairo, config->colors.separator); | 326 | color = config->colors.separator; |
293 | } | 327 | } |
328 | cairo_set_source_u32(cairo, color); | ||
294 | if (config->sep_symbol) { | 329 | if (config->sep_symbol) { |
295 | offset = x_pos + (sep_block_width - sep_width) / 2; | 330 | offset = x_pos + (sep_block_width - sep_width) / 2; |
296 | double sep_y = height / 2.0 - sep_height / 2.0; | 331 | double sep_y = height / 2.0 - sep_height / 2.0; |
297 | cairo_move_to(cairo, offset, (int)floor(sep_y)); | 332 | cairo_move_to(cairo, offset, (int)floor(sep_y)); |
298 | pango_printf(cairo, config->font, output->scale, false, | 333 | choose_text_aa_mode(ctx, color); |
334 | render_text(cairo, config->font, 1, false, | ||
299 | "%s", config->sep_symbol); | 335 | "%s", config->sep_symbol); |
300 | } else { | 336 | } else { |
337 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); | ||
301 | cairo_set_line_width(cairo, 1); | 338 | cairo_set_line_width(cairo, 1); |
302 | cairo_move_to(cairo, x_pos + sep_block_width / 2, margin); | 339 | cairo_move_to(cairo, x_pos + sep_block_width / 2, margin); |
303 | cairo_line_to(cairo, x_pos + sep_block_width / 2, height - margin); | 340 | cairo_line_to(cairo, x_pos + sep_block_width / 2, height - margin); |
@@ -317,18 +354,18 @@ static void predict_status_block_pos(cairo_t *cairo, | |||
317 | struct swaybar_config *config = output->bar->config; | 354 | struct swaybar_config *config = output->bar->config; |
318 | 355 | ||
319 | int text_width, text_height; | 356 | int text_width, text_height; |
320 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, | 357 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, 1, |
321 | output->scale, block->markup, "%s", block->full_text); | 358 | block->markup, "%s", block->full_text); |
322 | 359 | ||
323 | int margin = 3 * output->scale; | 360 | int margin = 3; |
324 | double ws_vertical_padding = config->status_padding * output->scale; | 361 | double ws_vertical_padding = config->status_padding; |
325 | 362 | ||
326 | int width = text_width; | 363 | int width = text_width; |
327 | 364 | ||
328 | if (block->min_width_str) { | 365 | if (block->min_width_str) { |
329 | int w; | 366 | int w; |
330 | get_text_size(cairo, config->font, &w, NULL, NULL, | 367 | get_text_size(cairo, config->font, &w, NULL, NULL, |
331 | output->scale, block->markup, "%s", block->min_width_str); | 368 | 1, block->markup, "%s", block->min_width_str); |
332 | block->min_width = w; | 369 | block->min_width = w; |
333 | } | 370 | } |
334 | if (width < block->min_width) { | 371 | if (width < block->min_width) { |
@@ -336,18 +373,18 @@ static void predict_status_block_pos(cairo_t *cairo, | |||
336 | } | 373 | } |
337 | 374 | ||
338 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; | 375 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; |
339 | uint32_t ideal_surface_height = ideal_height / output->scale; | 376 | uint32_t ideal_surface_height = ideal_height; |
340 | if (!output->bar->config->height && | 377 | if (!output->bar->config->height && |
341 | output->height < ideal_surface_height) { | 378 | output->height < ideal_surface_height) { |
342 | return; | 379 | return; |
343 | } | 380 | } |
344 | 381 | ||
345 | *x -= width; | 382 | *x -= width; |
346 | if ((block->border || block->urgent) && block->border_left > 0) { | 383 | if ((block->border_set || block->urgent) && block->border_left > 0) { |
347 | *x -= (block->border_left * output->scale + margin); | 384 | *x -= (block->border_left + margin); |
348 | } | 385 | } |
349 | if ((block->border || block->urgent) && block->border_right > 0) { | 386 | if ((block->border_set || block->urgent) && block->border_right > 0) { |
350 | *x -= (block->border_right * output->scale + margin); | 387 | *x -= (block->border_right + margin); |
351 | } | 388 | } |
352 | 389 | ||
353 | int sep_width, sep_height; | 390 | int sep_width, sep_height; |
@@ -355,9 +392,9 @@ static void predict_status_block_pos(cairo_t *cairo, | |||
355 | if (!edge) { | 392 | if (!edge) { |
356 | if (config->sep_symbol) { | 393 | if (config->sep_symbol) { |
357 | get_text_size(cairo, config->font, &sep_width, &sep_height, NULL, | 394 | get_text_size(cairo, config->font, &sep_width, &sep_height, NULL, |
358 | output->scale, false, "%s", config->sep_symbol); | 395 | 1, false, "%s", config->sep_symbol); |
359 | uint32_t _ideal_height = sep_height + ws_vertical_padding * 2; | 396 | uint32_t _ideal_height = sep_height + ws_vertical_padding * 2; |
360 | uint32_t _ideal_surface_height = _ideal_height / output->scale; | 397 | uint32_t _ideal_surface_height = _ideal_height; |
361 | if (!output->bar->config->height && | 398 | if (!output->bar->config->height && |
362 | output->height < _ideal_surface_height) { | 399 | output->height < _ideal_surface_height) { |
363 | return; | 400 | return; |
@@ -368,13 +405,13 @@ static void predict_status_block_pos(cairo_t *cairo, | |||
368 | } | 405 | } |
369 | *x -= sep_block_width; | 406 | *x -= sep_block_width; |
370 | } else if (config->status_edge_padding) { | 407 | } else if (config->status_edge_padding) { |
371 | *x -= config->status_edge_padding * output->scale; | 408 | *x -= config->status_edge_padding; |
372 | } | 409 | } |
373 | } | 410 | } |
374 | 411 | ||
375 | static double predict_status_line_pos(cairo_t *cairo, | 412 | static double predict_status_line_pos(cairo_t *cairo, |
376 | struct swaybar_output *output, double x) { | 413 | struct swaybar_output *output, double x) { |
377 | bool edge = x == output->width * output->scale; | 414 | bool edge = x == output->width; |
378 | struct i3bar_block *block; | 415 | struct i3bar_block *block; |
379 | wl_list_for_each(block, &output->bar->status->blocks, link) { | 416 | wl_list_for_each(block, &output->bar->status->blocks, link) { |
380 | predict_status_block_pos(cairo, output, block, &x, edge); | 417 | predict_status_block_pos(cairo, output, block, &x, edge); |
@@ -389,24 +426,24 @@ static uint32_t predict_workspace_button_length(cairo_t *cairo, | |||
389 | struct swaybar_config *config = output->bar->config; | 426 | struct swaybar_config *config = output->bar->config; |
390 | 427 | ||
391 | int text_width, text_height; | 428 | int text_width, text_height; |
392 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, | 429 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, 1, |
393 | output->scale, config->pango_markup, "%s", ws->label); | 430 | config->pango_markup, "%s", ws->label); |
394 | 431 | ||
395 | int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale; | 432 | int ws_vertical_padding = WS_VERTICAL_PADDING; |
396 | int ws_horizontal_padding = WS_HORIZONTAL_PADDING * output->scale; | 433 | int ws_horizontal_padding = WS_HORIZONTAL_PADDING; |
397 | int border_width = BORDER_WIDTH * output->scale; | 434 | int border_width = BORDER_WIDTH; |
398 | 435 | ||
399 | uint32_t ideal_height = ws_vertical_padding * 2 + text_height | 436 | uint32_t ideal_height = ws_vertical_padding * 2 + text_height |
400 | + border_width * 2; | 437 | + border_width * 2; |
401 | uint32_t ideal_surface_height = ideal_height / output->scale; | 438 | uint32_t ideal_surface_height = ideal_height; |
402 | if (!output->bar->config->height && | 439 | if (!output->bar->config->height && |
403 | output->height < ideal_surface_height) { | 440 | output->height < ideal_surface_height) { |
404 | return 0; | 441 | return 0; |
405 | } | 442 | } |
406 | 443 | ||
407 | uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; | 444 | uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; |
408 | if (width < config->workspace_min_width * output->scale) { | 445 | if (width < config->workspace_min_width) { |
409 | width = config->workspace_min_width * output->scale; | 446 | width = config->workspace_min_width; |
410 | } | 447 | } |
411 | return width; | 448 | return width; |
412 | } | 449 | } |
@@ -438,38 +475,39 @@ static uint32_t predict_binding_mode_indicator_length(cairo_t *cairo, | |||
438 | 475 | ||
439 | int text_width, text_height; | 476 | int text_width, text_height; |
440 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, | 477 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, |
441 | output->scale, output->bar->mode_pango_markup, | 478 | 1, output->bar->mode_pango_markup, |
442 | "%s", mode); | 479 | "%s", mode); |
443 | 480 | ||
444 | int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale; | 481 | int ws_vertical_padding = WS_VERTICAL_PADDING; |
445 | int ws_horizontal_padding = WS_HORIZONTAL_PADDING * output->scale; | 482 | int ws_horizontal_padding = WS_HORIZONTAL_PADDING; |
446 | int border_width = BORDER_WIDTH * output->scale; | 483 | int border_width = BORDER_WIDTH; |
447 | 484 | ||
448 | uint32_t ideal_height = text_height + ws_vertical_padding * 2 | 485 | uint32_t ideal_height = text_height + ws_vertical_padding * 2 |
449 | + border_width * 2; | 486 | + border_width * 2; |
450 | uint32_t ideal_surface_height = ideal_height / output->scale; | 487 | uint32_t ideal_surface_height = ideal_height; |
451 | if (!output->bar->config->height && | 488 | if (!output->bar->config->height && |
452 | output->height < ideal_surface_height) { | 489 | output->height < ideal_surface_height) { |
453 | return 0; | 490 | return 0; |
454 | } | 491 | } |
455 | uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; | 492 | uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; |
456 | if (width < config->workspace_min_width * output->scale) { | 493 | if (width < config->workspace_min_width) { |
457 | width = config->workspace_min_width * output->scale; | 494 | width = config->workspace_min_width; |
458 | } | 495 | } |
459 | return width; | 496 | return width; |
460 | } | 497 | } |
461 | 498 | ||
462 | static uint32_t render_status_line_i3bar(cairo_t *cairo, | 499 | static uint32_t render_status_line_i3bar(struct render_context *ctx, double *x) { |
463 | struct swaybar_output *output, double *x) { | 500 | struct swaybar_output *output = ctx->output; |
464 | uint32_t max_height = 0; | 501 | uint32_t max_height = 0; |
465 | bool edge = *x == output->width * output->scale; | 502 | bool edge = *x == output->width; |
466 | struct i3bar_block *block; | 503 | struct i3bar_block *block; |
467 | bool use_short_text = false; | 504 | bool use_short_text = false; |
468 | 505 | ||
506 | cairo_t *cairo = ctx->cairo; | ||
469 | double reserved_width = | 507 | double reserved_width = |
470 | predict_workspace_buttons_length(cairo, output) + | 508 | predict_workspace_buttons_length(cairo, output) + |
471 | predict_binding_mode_indicator_length(cairo, output) + | 509 | predict_binding_mode_indicator_length(cairo, output) + |
472 | 3 * output->scale; // require a bit of space for margin | 510 | 3; // require a bit of space for margin |
473 | 511 | ||
474 | double predicted_full_pos = | 512 | double predicted_full_pos = |
475 | predict_status_line_pos(cairo, output, *x); | 513 | predict_status_line_pos(cairo, output, *x); |
@@ -479,7 +517,7 @@ static uint32_t render_status_line_i3bar(cairo_t *cairo, | |||
479 | } | 517 | } |
480 | 518 | ||
481 | wl_list_for_each(block, &output->bar->status->blocks, link) { | 519 | wl_list_for_each(block, &output->bar->status->blocks, link) { |
482 | uint32_t h = render_status_block(cairo, output, block, x, edge, | 520 | uint32_t h = render_status_block(ctx, block, x, edge, |
483 | use_short_text); | 521 | use_short_text); |
484 | max_height = h > max_height ? h : max_height; | 522 | max_height = h > max_height ? h : max_height; |
485 | edge = false; | 523 | edge = false; |
@@ -487,53 +525,56 @@ static uint32_t render_status_line_i3bar(cairo_t *cairo, | |||
487 | return max_height; | 525 | return max_height; |
488 | } | 526 | } |
489 | 527 | ||
490 | static uint32_t render_status_line(cairo_t *cairo, | 528 | static uint32_t render_status_line(struct render_context *ctx, double *x) { |
491 | struct swaybar_output *output, double *x) { | 529 | struct status_line *status = ctx->output->bar->status; |
492 | struct status_line *status = output->bar->status; | ||
493 | switch (status->protocol) { | 530 | switch (status->protocol) { |
494 | case PROTOCOL_ERROR: | 531 | case PROTOCOL_ERROR: |
495 | return render_status_line_error(cairo, output, x); | 532 | return render_status_line_error(ctx, x); |
496 | case PROTOCOL_TEXT: | 533 | case PROTOCOL_TEXT: |
497 | return render_status_line_text(cairo, output, x); | 534 | return render_status_line_text(ctx, x); |
498 | case PROTOCOL_I3BAR: | 535 | case PROTOCOL_I3BAR: |
499 | return render_status_line_i3bar(cairo, output, x); | 536 | return render_status_line_i3bar(ctx, x); |
500 | case PROTOCOL_UNDEF: | 537 | case PROTOCOL_UNDEF: |
501 | return 0; | 538 | return 0; |
502 | } | 539 | } |
503 | return 0; | 540 | return 0; |
504 | } | 541 | } |
505 | 542 | ||
506 | static uint32_t render_binding_mode_indicator(cairo_t *cairo, | 543 | static uint32_t render_binding_mode_indicator(struct render_context *ctx, |
507 | struct swaybar_output *output, double x) { | 544 | double x) { |
545 | struct swaybar_output *output = ctx->output; | ||
508 | const char *mode = output->bar->mode; | 546 | const char *mode = output->bar->mode; |
509 | if (!mode) { | 547 | if (!mode) { |
510 | return 0; | 548 | return 0; |
511 | } | 549 | } |
512 | 550 | ||
551 | cairo_t *cairo = ctx->cairo; | ||
513 | struct swaybar_config *config = output->bar->config; | 552 | struct swaybar_config *config = output->bar->config; |
514 | int text_width, text_height; | 553 | int text_width, text_height; |
515 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, | 554 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, |
516 | output->scale, output->bar->mode_pango_markup, | 555 | 1, output->bar->mode_pango_markup, |
517 | "%s", mode); | 556 | "%s", mode); |
518 | 557 | ||
519 | int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale; | 558 | int ws_vertical_padding = WS_VERTICAL_PADDING; |
520 | int ws_horizontal_padding = WS_HORIZONTAL_PADDING * output->scale; | 559 | int ws_horizontal_padding = WS_HORIZONTAL_PADDING; |
521 | int border_width = BORDER_WIDTH * output->scale; | 560 | int border_width = BORDER_WIDTH; |
522 | 561 | ||
523 | uint32_t ideal_height = text_height + ws_vertical_padding * 2 | 562 | uint32_t ideal_height = text_height + ws_vertical_padding * 2 |
524 | + border_width * 2; | 563 | + border_width * 2; |
525 | uint32_t ideal_surface_height = ideal_height / output->scale; | 564 | uint32_t ideal_surface_height = ideal_height; |
526 | if (!output->bar->config->height && | 565 | if (!output->bar->config->height && |
527 | output->height < ideal_surface_height) { | 566 | output->height < ideal_surface_height) { |
528 | return ideal_surface_height; | 567 | return ideal_surface_height; |
529 | } | 568 | } |
530 | uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; | 569 | uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; |
531 | if (width < config->workspace_min_width * output->scale) { | 570 | if (width < config->workspace_min_width) { |
532 | width = config->workspace_min_width * output->scale; | 571 | width = config->workspace_min_width; |
533 | } | 572 | } |
534 | 573 | ||
535 | uint32_t height = output->height * output->scale; | 574 | uint32_t height = output->height; |
575 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); | ||
536 | cairo_set_source_u32(cairo, config->colors.binding_mode.background); | 576 | cairo_set_source_u32(cairo, config->colors.binding_mode.background); |
577 | ctx->background_color = config->colors.binding_mode.background; | ||
537 | cairo_rectangle(cairo, x, 0, width, height); | 578 | cairo_rectangle(cairo, x, 0, width, height); |
538 | cairo_fill(cairo); | 579 | cairo_fill(cairo); |
539 | 580 | ||
@@ -550,8 +591,9 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo, | |||
550 | double text_y = height / 2.0 - text_height / 2.0; | 591 | double text_y = height / 2.0 - text_height / 2.0; |
551 | cairo_set_source_u32(cairo, config->colors.binding_mode.text); | 592 | cairo_set_source_u32(cairo, config->colors.binding_mode.text); |
552 | cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y)); | 593 | cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y)); |
553 | pango_printf(cairo, config->font, output->scale, | 594 | choose_text_aa_mode(ctx, config->colors.binding_mode.text); |
554 | output->bar->mode_pango_markup, "%s", mode); | 595 | render_text(cairo, config->font, 1, output->bar->mode_pango_markup, |
596 | "%s", mode); | ||
555 | return output->height; | 597 | return output->height; |
556 | } | 598 | } |
557 | 599 | ||
@@ -565,9 +607,9 @@ static enum hotspot_event_handling workspace_hotspot_callback( | |||
565 | return HOTSPOT_IGNORE; | 607 | return HOTSPOT_IGNORE; |
566 | } | 608 | } |
567 | 609 | ||
568 | static uint32_t render_workspace_button(cairo_t *cairo, | 610 | static uint32_t render_workspace_button(struct render_context *ctx, |
569 | struct swaybar_output *output, | ||
570 | struct swaybar_workspace *ws, double *x) { | 611 | struct swaybar_workspace *ws, double *x) { |
612 | struct swaybar_output *output = ctx->output; | ||
571 | struct swaybar_config *config = output->bar->config; | 613 | struct swaybar_config *config = output->bar->config; |
572 | struct box_colors box_colors; | 614 | struct box_colors box_colors; |
573 | if (ws->urgent) { | 615 | if (ws->urgent) { |
@@ -580,30 +622,33 @@ static uint32_t render_workspace_button(cairo_t *cairo, | |||
580 | box_colors = config->colors.inactive_workspace; | 622 | box_colors = config->colors.inactive_workspace; |
581 | } | 623 | } |
582 | 624 | ||
583 | uint32_t height = output->height * output->scale; | 625 | uint32_t height = output->height; |
584 | 626 | ||
627 | cairo_t *cairo = ctx->cairo; | ||
585 | int text_width, text_height; | 628 | int text_width, text_height; |
586 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, | 629 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, |
587 | output->scale, config->pango_markup, "%s", ws->label); | 630 | 1, config->pango_markup, "%s", ws->label); |
588 | 631 | ||
589 | int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale; | 632 | int ws_vertical_padding = WS_VERTICAL_PADDING; |
590 | int ws_horizontal_padding = WS_HORIZONTAL_PADDING * output->scale; | 633 | int ws_horizontal_padding = WS_HORIZONTAL_PADDING; |
591 | int border_width = BORDER_WIDTH * output->scale; | 634 | int border_width = BORDER_WIDTH; |
592 | 635 | ||
593 | uint32_t ideal_height = ws_vertical_padding * 2 + text_height | 636 | uint32_t ideal_height = ws_vertical_padding * 2 + text_height |
594 | + border_width * 2; | 637 | + border_width * 2; |
595 | uint32_t ideal_surface_height = ideal_height / output->scale; | 638 | uint32_t ideal_surface_height = ideal_height; |
596 | if (!output->bar->config->height && | 639 | if (!output->bar->config->height && |
597 | output->height < ideal_surface_height) { | 640 | output->height < ideal_surface_height) { |
598 | return ideal_surface_height; | 641 | return ideal_surface_height; |
599 | } | 642 | } |
600 | 643 | ||
601 | uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; | 644 | uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; |
602 | if (width < config->workspace_min_width * output->scale) { | 645 | if (width < config->workspace_min_width) { |
603 | width = config->workspace_min_width * output->scale; | 646 | width = config->workspace_min_width; |
604 | } | 647 | } |
605 | 648 | ||
649 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); | ||
606 | cairo_set_source_u32(cairo, box_colors.background); | 650 | cairo_set_source_u32(cairo, box_colors.background); |
651 | ctx->background_color = box_colors.background; | ||
607 | cairo_rectangle(cairo, *x, 0, width, height); | 652 | cairo_rectangle(cairo, *x, 0, width, height); |
608 | cairo_fill(cairo); | 653 | cairo_fill(cairo); |
609 | 654 | ||
@@ -620,7 +665,8 @@ static uint32_t render_workspace_button(cairo_t *cairo, | |||
620 | double text_y = height / 2.0 - text_height / 2.0; | 665 | double text_y = height / 2.0 - text_height / 2.0; |
621 | cairo_set_source_u32(cairo, box_colors.text); | 666 | cairo_set_source_u32(cairo, box_colors.text); |
622 | cairo_move_to(cairo, *x + width / 2 - text_width / 2, (int)floor(text_y)); | 667 | cairo_move_to(cairo, *x + width / 2 - text_width / 2, (int)floor(text_y)); |
623 | pango_printf(cairo, config->font, output->scale, config->pango_markup, | 668 | choose_text_aa_mode(ctx, box_colors.text); |
669 | render_text(cairo, config->font, 1, config->pango_markup, | ||
624 | "%s", ws->label); | 670 | "%s", ws->label); |
625 | 671 | ||
626 | struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); | 672 | struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); |
@@ -637,20 +683,24 @@ static uint32_t render_workspace_button(cairo_t *cairo, | |||
637 | return output->height; | 683 | return output->height; |
638 | } | 684 | } |
639 | 685 | ||
640 | static uint32_t render_to_cairo(cairo_t *cairo, struct swaybar_output *output) { | 686 | static uint32_t render_to_cairo(struct render_context *ctx) { |
687 | cairo_t *cairo = ctx->cairo; | ||
688 | struct swaybar_output *output = ctx->output; | ||
641 | struct swaybar *bar = output->bar; | 689 | struct swaybar *bar = output->bar; |
642 | struct swaybar_config *config = bar->config; | 690 | struct swaybar_config *config = bar->config; |
643 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); | 691 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); |
644 | if (output->focused) { | 692 | if (output->focused) { |
645 | cairo_set_source_u32(cairo, config->colors.focused_background); | 693 | ctx->background_color = config->colors.focused_background; |
646 | } else { | 694 | } else { |
647 | cairo_set_source_u32(cairo, config->colors.background); | 695 | ctx->background_color = config->colors.background; |
648 | } | 696 | } |
697 | |||
698 | cairo_set_source_u32(cairo, ctx->background_color); | ||
649 | cairo_paint(cairo); | 699 | cairo_paint(cairo); |
650 | 700 | ||
651 | int th; | 701 | int th; |
652 | get_text_size(cairo, config->font, NULL, &th, NULL, output->scale, false, ""); | 702 | get_text_size(cairo, config->font, NULL, &th, NULL, 1, false, ""); |
653 | uint32_t max_height = (th + WS_VERTICAL_PADDING * 4) / output->scale; | 703 | uint32_t max_height = (th + WS_VERTICAL_PADDING * 4); |
654 | /* | 704 | /* |
655 | * Each render_* function takes the actual height of the bar, and returns | 705 | * Each render_* function takes the actual height of the bar, and returns |
656 | * the ideal height. If the actual height is too short, the render function | 706 | * the ideal height. If the actual height is too short, the render function |
@@ -658,7 +708,7 @@ static uint32_t render_to_cairo(cairo_t *cairo, struct swaybar_output *output) { | |||
658 | * height is too tall, the render function should adapt its drawing to | 708 | * height is too tall, the render function should adapt its drawing to |
659 | * utilize the available space. | 709 | * utilize the available space. |
660 | */ | 710 | */ |
661 | double x = output->width * output->scale; | 711 | double x = output->width; |
662 | #if HAVE_TRAY | 712 | #if HAVE_TRAY |
663 | if (bar->tray) { | 713 | if (bar->tray) { |
664 | uint32_t h = render_tray(cairo, output, &x); | 714 | uint32_t h = render_tray(cairo, output, &x); |
@@ -666,19 +716,19 @@ static uint32_t render_to_cairo(cairo_t *cairo, struct swaybar_output *output) { | |||
666 | } | 716 | } |
667 | #endif | 717 | #endif |
668 | if (bar->status) { | 718 | if (bar->status) { |
669 | uint32_t h = render_status_line(cairo, output, &x); | 719 | uint32_t h = render_status_line(ctx, &x); |
670 | max_height = h > max_height ? h : max_height; | 720 | max_height = h > max_height ? h : max_height; |
671 | } | 721 | } |
672 | x = 0; | 722 | x = 0; |
673 | if (config->workspace_buttons) { | 723 | if (config->workspace_buttons) { |
674 | struct swaybar_workspace *ws; | 724 | struct swaybar_workspace *ws; |
675 | wl_list_for_each(ws, &output->workspaces, link) { | 725 | wl_list_for_each(ws, &output->workspaces, link) { |
676 | uint32_t h = render_workspace_button(cairo, output, ws, &x); | 726 | uint32_t h = render_workspace_button(ctx, ws, &x); |
677 | max_height = h > max_height ? h : max_height; | 727 | max_height = h > max_height ? h : max_height; |
678 | } | 728 | } |
679 | } | 729 | } |
680 | if (config->binding_mode_indicator) { | 730 | if (config->binding_mode_indicator) { |
681 | uint32_t h = render_binding_mode_indicator(cairo, output, x); | 731 | uint32_t h = render_binding_mode_indicator(ctx, x); |
682 | max_height = h > max_height ? h : max_height; | 732 | max_height = h > max_height ? h : max_height; |
683 | } | 733 | } |
684 | 734 | ||
@@ -708,26 +758,36 @@ void render_frame(struct swaybar_output *output) { | |||
708 | 758 | ||
709 | free_hotspots(&output->hotspots); | 759 | free_hotspots(&output->hotspots); |
710 | 760 | ||
761 | struct render_context ctx = { 0 }; | ||
762 | ctx.output = output; | ||
763 | |||
711 | cairo_surface_t *recorder = cairo_recording_surface_create( | 764 | cairo_surface_t *recorder = cairo_recording_surface_create( |
712 | CAIRO_CONTENT_COLOR_ALPHA, NULL); | 765 | CAIRO_CONTENT_COLOR_ALPHA, NULL); |
713 | cairo_t *cairo = cairo_create(recorder); | 766 | cairo_t *cairo = cairo_create(recorder); |
767 | cairo_scale(cairo, output->scale, output->scale); | ||
714 | cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); | 768 | cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); |
769 | ctx.cairo = cairo; | ||
770 | |||
715 | cairo_font_options_t *fo = cairo_font_options_create(); | 771 | cairo_font_options_t *fo = cairo_font_options_create(); |
716 | cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL); | 772 | cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL); |
773 | cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_GRAY); | ||
774 | ctx.textaa_safe = fo; | ||
717 | if (output->subpixel == WL_OUTPUT_SUBPIXEL_NONE) { | 775 | if (output->subpixel == WL_OUTPUT_SUBPIXEL_NONE) { |
718 | cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_GRAY); | 776 | ctx.textaa_sharp = ctx.textaa_safe; |
719 | } else { | 777 | } else { |
778 | fo = cairo_font_options_create(); | ||
779 | cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL); | ||
720 | cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_SUBPIXEL); | 780 | cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_SUBPIXEL); |
721 | cairo_font_options_set_subpixel_order(fo, | 781 | cairo_font_options_set_subpixel_order(fo, |
722 | to_cairo_subpixel_order(output->subpixel)); | 782 | to_cairo_subpixel_order(output->subpixel)); |
783 | ctx.textaa_sharp = fo; | ||
723 | } | 784 | } |
724 | cairo_set_font_options(cairo, fo); | 785 | |
725 | cairo_font_options_destroy(fo); | ||
726 | cairo_save(cairo); | 786 | cairo_save(cairo); |
727 | cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR); | 787 | cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR); |
728 | cairo_paint(cairo); | 788 | cairo_paint(cairo); |
729 | cairo_restore(cairo); | 789 | cairo_restore(cairo); |
730 | uint32_t height = render_to_cairo(cairo, output); | 790 | uint32_t height = render_to_cairo(&ctx); |
731 | int config_height = output->bar->config->height; | 791 | int config_height = output->bar->config->height; |
732 | if (config_height > 0) { | 792 | if (config_height > 0) { |
733 | height = config_height; | 793 | height = config_height; |
@@ -779,6 +839,11 @@ void render_frame(struct swaybar_output *output) { | |||
779 | 839 | ||
780 | wl_surface_commit(output->surface); | 840 | wl_surface_commit(output->surface); |
781 | } | 841 | } |
842 | |||
843 | if (ctx.textaa_sharp != ctx.textaa_safe) { | ||
844 | cairo_font_options_destroy(ctx.textaa_sharp); | ||
845 | } | ||
846 | cairo_font_options_destroy(ctx.textaa_safe); | ||
782 | cairo_surface_destroy(recorder); | 847 | cairo_surface_destroy(recorder); |
783 | cairo_destroy(cairo); | 848 | cairo_destroy(cairo); |
784 | } | 849 | } |