diff options
Diffstat (limited to 'swaybar')
-rw-r--r-- | swaybar/render.c | 132 |
1 files changed, 97 insertions, 35 deletions
diff --git a/swaybar/render.c b/swaybar/render.c index df066622..ebe127a5 100644 --- a/swaybar/render.c +++ b/swaybar/render.c | |||
@@ -23,8 +23,31 @@ static const int WS_HORIZONTAL_PADDING = 5; | |||
23 | static const double WS_VERTICAL_PADDING = 1.5; | 23 | static const double WS_VERTICAL_PADDING = 1.5; |
24 | static const double BORDER_WIDTH = 1; | 24 | static const double BORDER_WIDTH = 1; |
25 | 25 | ||
26 | static uint32_t render_status_line_error(cairo_t *cairo, | 26 | struct render_context { |
27 | struct swaybar_output *output, double *x) { | 27 | cairo_t *cairo; |
28 | struct swaybar_output *output; | ||
29 | cairo_font_options_t *textaa_sharp; | ||
30 | cairo_font_options_t *textaa_safe; | ||
31 | uint32_t background_color; | ||
32 | }; | ||
33 | |||
34 | static void choose_text_aa_mode(struct render_context *ctx, uint32_t fontcolor) { | ||
35 | uint32_t salpha = fontcolor & 0xFF; | ||
36 | uint32_t balpha = ctx->background_color & 0xFF; | ||
37 | |||
38 | // Subpixel antialiasing requires blend be done in cairo, not compositor | ||
39 | cairo_font_options_t *fo = salpha == balpha ? | ||
40 | ctx->textaa_sharp : ctx->textaa_safe; | ||
41 | cairo_set_font_options(ctx->cairo, fo); | ||
42 | |||
43 | // Color emojis, being semitransparent bitmaps, are leaky with 'SOURCE' | ||
44 | cairo_operator_t op = salpha == 0xFF ? | ||
45 | CAIRO_OPERATOR_OVER : CAIRO_OPERATOR_SOURCE; | ||
46 | cairo_set_operator(ctx->cairo, op); | ||
47 | } | ||
48 | |||
49 | static uint32_t render_status_line_error(struct render_context *ctx, double *x) { | ||
50 | struct swaybar_output *output = ctx->output; | ||
28 | const char *error = output->bar->status->text; | 51 | const char *error = output->bar->status->text; |
29 | if (!error) { | 52 | if (!error) { |
30 | return 0; | 53 | return 0; |
@@ -32,6 +55,7 @@ static uint32_t render_status_line_error(cairo_t *cairo, | |||
32 | 55 | ||
33 | uint32_t height = output->height * output->scale; | 56 | uint32_t height = output->height * output->scale; |
34 | 57 | ||
58 | cairo_t *cairo = ctx->cairo; | ||
35 | cairo_set_source_u32(cairo, 0xFF0000FF); | 59 | cairo_set_source_u32(cairo, 0xFF0000FF); |
36 | 60 | ||
37 | int margin = 3 * output->scale; | 61 | int margin = 3 * output->scale; |
@@ -53,21 +77,24 @@ 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)); |
80 | choose_text_aa_mode(ctx, 0xFF0000FF); | ||
56 | pango_printf(cairo, font, output->scale, false, "%s", error); | 81 | pango_printf(cairo, font, output->scale, 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, |
@@ -87,6 +114,7 @@ static uint32_t render_status_line_text(cairo_t *cairo, | |||
87 | uint32_t height = output->height * output->scale; | 114 | uint32_t height = output->height * output->scale; |
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)); |
117 | choose_text_aa_mode(ctx, fontcolor); | ||
90 | pango_printf(cairo, config->font, output->scale, | 118 | pango_printf(cairo, config->font, output->scale, |
91 | config->pango_markup, "%s", text); | 119 | config->pango_markup, "%s", text); |
92 | *x -= margin; | 120 | *x -= margin; |
@@ -96,6 +124,7 @@ static uint32_t render_status_line_text(cairo_t *cairo, | |||
96 | static void render_sharp_rectangle(cairo_t *cairo, uint32_t color, | 124 | static void render_sharp_rectangle(cairo_t *cairo, uint32_t color, |
97 | double x, double y, double width, double height) { | 125 | double x, double y, double width, double height) { |
98 | cairo_save(cairo); | 126 | cairo_save(cairo); |
127 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); | ||
99 | cairo_set_source_u32(cairo, color); | 128 | cairo_set_source_u32(cairo, color); |
100 | cairo_set_antialias(cairo, CAIRO_ANTIALIAS_NONE); | 129 | cairo_set_antialias(cairo, CAIRO_ANTIALIAS_NONE); |
101 | cairo_rectangle(cairo, x, y, width, height); | 130 | cairo_rectangle(cairo, x, y, width, height); |
@@ -109,6 +138,7 @@ static void render_sharp_line(cairo_t *cairo, uint32_t color, | |||
109 | render_sharp_rectangle(cairo, color, x, y, width, height); | 138 | render_sharp_rectangle(cairo, color, x, y, width, height); |
110 | } else { | 139 | } else { |
111 | cairo_save(cairo); | 140 | cairo_save(cairo); |
141 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); | ||
112 | cairo_set_source_u32(cairo, color); | 142 | cairo_set_source_u32(cairo, color); |
113 | cairo_set_antialias(cairo, CAIRO_ANTIALIAS_NONE); | 143 | cairo_set_antialias(cairo, CAIRO_ANTIALIAS_NONE); |
114 | if (width == 1) { | 144 | if (width == 1) { |
@@ -146,9 +176,8 @@ static void i3bar_block_unref_callback(void *data) { | |||
146 | i3bar_block_unref(data); | 176 | i3bar_block_unref(data); |
147 | } | 177 | } |
148 | 178 | ||
149 | static uint32_t render_status_block(cairo_t *cairo, | 179 | static uint32_t render_status_block(struct render_context *ctx, |
150 | struct swaybar_output *output, struct i3bar_block *block, double *x, | 180 | 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) { | 181 | if (!block->full_text || !*block->full_text) { |
153 | return 0; | 182 | return 0; |
154 | } | 183 | } |
@@ -158,8 +187,9 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
158 | text = block->short_text; | 187 | text = block->short_text; |
159 | } | 188 | } |
160 | 189 | ||
190 | cairo_t *cairo = ctx->cairo; | ||
191 | struct swaybar_output *output = ctx->output; | ||
161 | struct swaybar_config *config = output->bar->config; | 192 | struct swaybar_config *config = output->bar->config; |
162 | |||
163 | int text_width, text_height; | 193 | int text_width, text_height; |
164 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, | 194 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, |
165 | output->scale, block->markup, "%s", text); | 195 | output->scale, block->markup, "%s", text); |
@@ -240,6 +270,7 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
240 | if (bg_color) { | 270 | if (bg_color) { |
241 | render_sharp_rectangle(cairo, bg_color, x_pos, y_pos, | 271 | render_sharp_rectangle(cairo, bg_color, x_pos, y_pos, |
242 | block_width, render_height); | 272 | block_width, render_height); |
273 | ctx->background_color = bg_color; | ||
243 | } | 274 | } |
244 | 275 | ||
245 | uint32_t border_color = block->urgent | 276 | uint32_t border_color = block->urgent |
@@ -274,6 +305,7 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
274 | color = block->color_set ? block->color : color; | 305 | color = block->color_set ? block->color : color; |
275 | color = block->urgent ? config->colors.urgent_workspace.text : color; | 306 | color = block->urgent ? config->colors.urgent_workspace.text : color; |
276 | cairo_set_source_u32(cairo, color); | 307 | cairo_set_source_u32(cairo, color); |
308 | choose_text_aa_mode(ctx, color); | ||
277 | pango_printf(cairo, config->font, output->scale, | 309 | pango_printf(cairo, config->font, output->scale, |
278 | block->markup, "%s", text); | 310 | block->markup, "%s", text); |
279 | x_pos += width; | 311 | x_pos += width; |
@@ -287,17 +319,20 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
287 | 319 | ||
288 | if (!edge && block->separator) { | 320 | if (!edge && block->separator) { |
289 | if (output->focused) { | 321 | if (output->focused) { |
290 | cairo_set_source_u32(cairo, config->colors.focused_separator); | 322 | color = config->colors.focused_separator; |
291 | } else { | 323 | } else { |
292 | cairo_set_source_u32(cairo, config->colors.separator); | 324 | color = config->colors.separator; |
293 | } | 325 | } |
326 | cairo_set_source_u32(cairo, color); | ||
294 | if (config->sep_symbol) { | 327 | if (config->sep_symbol) { |
295 | offset = x_pos + (sep_block_width - sep_width) / 2; | 328 | offset = x_pos + (sep_block_width - sep_width) / 2; |
296 | double sep_y = height / 2.0 - sep_height / 2.0; | 329 | double sep_y = height / 2.0 - sep_height / 2.0; |
297 | cairo_move_to(cairo, offset, (int)floor(sep_y)); | 330 | cairo_move_to(cairo, offset, (int)floor(sep_y)); |
331 | choose_text_aa_mode(ctx, color); | ||
298 | pango_printf(cairo, config->font, output->scale, false, | 332 | pango_printf(cairo, config->font, output->scale, false, |
299 | "%s", config->sep_symbol); | 333 | "%s", config->sep_symbol); |
300 | } else { | 334 | } else { |
335 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); | ||
301 | cairo_set_line_width(cairo, 1); | 336 | cairo_set_line_width(cairo, 1); |
302 | cairo_move_to(cairo, x_pos + sep_block_width / 2, margin); | 337 | cairo_move_to(cairo, x_pos + sep_block_width / 2, margin); |
303 | cairo_line_to(cairo, x_pos + sep_block_width / 2, height - margin); | 338 | cairo_line_to(cairo, x_pos + sep_block_width / 2, height - margin); |
@@ -459,13 +494,14 @@ static uint32_t predict_binding_mode_indicator_length(cairo_t *cairo, | |||
459 | return width; | 494 | return width; |
460 | } | 495 | } |
461 | 496 | ||
462 | static uint32_t render_status_line_i3bar(cairo_t *cairo, | 497 | static uint32_t render_status_line_i3bar(struct render_context *ctx, double *x) { |
463 | struct swaybar_output *output, double *x) { | 498 | struct swaybar_output *output = ctx->output; |
464 | uint32_t max_height = 0; | 499 | uint32_t max_height = 0; |
465 | bool edge = *x == output->width * output->scale; | 500 | bool edge = *x == output->width * output->scale; |
466 | struct i3bar_block *block; | 501 | struct i3bar_block *block; |
467 | bool use_short_text = false; | 502 | bool use_short_text = false; |
468 | 503 | ||
504 | cairo_t *cairo = ctx->cairo; | ||
469 | double reserved_width = | 505 | double reserved_width = |
470 | predict_workspace_buttons_length(cairo, output) + | 506 | predict_workspace_buttons_length(cairo, output) + |
471 | predict_binding_mode_indicator_length(cairo, output) + | 507 | predict_binding_mode_indicator_length(cairo, output) + |
@@ -479,7 +515,7 @@ static uint32_t render_status_line_i3bar(cairo_t *cairo, | |||
479 | } | 515 | } |
480 | 516 | ||
481 | wl_list_for_each(block, &output->bar->status->blocks, link) { | 517 | wl_list_for_each(block, &output->bar->status->blocks, link) { |
482 | uint32_t h = render_status_block(cairo, output, block, x, edge, | 518 | uint32_t h = render_status_block(ctx, block, x, edge, |
483 | use_short_text); | 519 | use_short_text); |
484 | max_height = h > max_height ? h : max_height; | 520 | max_height = h > max_height ? h : max_height; |
485 | edge = false; | 521 | edge = false; |
@@ -487,29 +523,30 @@ static uint32_t render_status_line_i3bar(cairo_t *cairo, | |||
487 | return max_height; | 523 | return max_height; |
488 | } | 524 | } |
489 | 525 | ||
490 | static uint32_t render_status_line(cairo_t *cairo, | 526 | static uint32_t render_status_line(struct render_context *ctx, double *x) { |
491 | struct swaybar_output *output, double *x) { | 527 | struct status_line *status = ctx->output->bar->status; |
492 | struct status_line *status = output->bar->status; | ||
493 | switch (status->protocol) { | 528 | switch (status->protocol) { |
494 | case PROTOCOL_ERROR: | 529 | case PROTOCOL_ERROR: |
495 | return render_status_line_error(cairo, output, x); | 530 | return render_status_line_error(ctx, x); |
496 | case PROTOCOL_TEXT: | 531 | case PROTOCOL_TEXT: |
497 | return render_status_line_text(cairo, output, x); | 532 | return render_status_line_text(ctx, x); |
498 | case PROTOCOL_I3BAR: | 533 | case PROTOCOL_I3BAR: |
499 | return render_status_line_i3bar(cairo, output, x); | 534 | return render_status_line_i3bar(ctx, x); |
500 | case PROTOCOL_UNDEF: | 535 | case PROTOCOL_UNDEF: |
501 | return 0; | 536 | return 0; |
502 | } | 537 | } |
503 | return 0; | 538 | return 0; |
504 | } | 539 | } |
505 | 540 | ||
506 | static uint32_t render_binding_mode_indicator(cairo_t *cairo, | 541 | static uint32_t render_binding_mode_indicator(struct render_context *ctx, |
507 | struct swaybar_output *output, double x) { | 542 | double x) { |
543 | struct swaybar_output *output = ctx->output; | ||
508 | const char *mode = output->bar->mode; | 544 | const char *mode = output->bar->mode; |
509 | if (!mode) { | 545 | if (!mode) { |
510 | return 0; | 546 | return 0; |
511 | } | 547 | } |
512 | 548 | ||
549 | cairo_t *cairo = ctx->cairo; | ||
513 | struct swaybar_config *config = output->bar->config; | 550 | struct swaybar_config *config = output->bar->config; |
514 | int text_width, text_height; | 551 | int text_width, text_height; |
515 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, | 552 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, |
@@ -533,7 +570,9 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo, | |||
533 | } | 570 | } |
534 | 571 | ||
535 | uint32_t height = output->height * output->scale; | 572 | uint32_t height = output->height * output->scale; |
573 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); | ||
536 | cairo_set_source_u32(cairo, config->colors.binding_mode.background); | 574 | cairo_set_source_u32(cairo, config->colors.binding_mode.background); |
575 | ctx->background_color = config->colors.binding_mode.background; | ||
537 | cairo_rectangle(cairo, x, 0, width, height); | 576 | cairo_rectangle(cairo, x, 0, width, height); |
538 | cairo_fill(cairo); | 577 | cairo_fill(cairo); |
539 | 578 | ||
@@ -550,6 +589,7 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo, | |||
550 | double text_y = height / 2.0 - text_height / 2.0; | 589 | double text_y = height / 2.0 - text_height / 2.0; |
551 | cairo_set_source_u32(cairo, config->colors.binding_mode.text); | 590 | 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)); | 591 | cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y)); |
592 | choose_text_aa_mode(ctx, config->colors.binding_mode.text); | ||
553 | pango_printf(cairo, config->font, output->scale, | 593 | pango_printf(cairo, config->font, output->scale, |
554 | output->bar->mode_pango_markup, "%s", mode); | 594 | output->bar->mode_pango_markup, "%s", mode); |
555 | return output->height; | 595 | return output->height; |
@@ -565,9 +605,9 @@ static enum hotspot_event_handling workspace_hotspot_callback( | |||
565 | return HOTSPOT_IGNORE; | 605 | return HOTSPOT_IGNORE; |
566 | } | 606 | } |
567 | 607 | ||
568 | static uint32_t render_workspace_button(cairo_t *cairo, | 608 | static uint32_t render_workspace_button(struct render_context *ctx, |
569 | struct swaybar_output *output, | ||
570 | struct swaybar_workspace *ws, double *x) { | 609 | struct swaybar_workspace *ws, double *x) { |
610 | struct swaybar_output *output = ctx->output; | ||
571 | struct swaybar_config *config = output->bar->config; | 611 | struct swaybar_config *config = output->bar->config; |
572 | struct box_colors box_colors; | 612 | struct box_colors box_colors; |
573 | if (ws->urgent) { | 613 | if (ws->urgent) { |
@@ -582,6 +622,7 @@ static uint32_t render_workspace_button(cairo_t *cairo, | |||
582 | 622 | ||
583 | uint32_t height = output->height * output->scale; | 623 | uint32_t height = output->height * output->scale; |
584 | 624 | ||
625 | cairo_t *cairo = ctx->cairo; | ||
585 | int text_width, text_height; | 626 | int text_width, text_height; |
586 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, | 627 | get_text_size(cairo, config->font, &text_width, &text_height, NULL, |
587 | output->scale, config->pango_markup, "%s", ws->label); | 628 | output->scale, config->pango_markup, "%s", ws->label); |
@@ -603,7 +644,9 @@ static uint32_t render_workspace_button(cairo_t *cairo, | |||
603 | width = config->workspace_min_width * output->scale; | 644 | width = config->workspace_min_width * output->scale; |
604 | } | 645 | } |
605 | 646 | ||
647 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); | ||
606 | cairo_set_source_u32(cairo, box_colors.background); | 648 | cairo_set_source_u32(cairo, box_colors.background); |
649 | ctx->background_color = box_colors.background; | ||
607 | cairo_rectangle(cairo, *x, 0, width, height); | 650 | cairo_rectangle(cairo, *x, 0, width, height); |
608 | cairo_fill(cairo); | 651 | cairo_fill(cairo); |
609 | 652 | ||
@@ -620,6 +663,7 @@ static uint32_t render_workspace_button(cairo_t *cairo, | |||
620 | double text_y = height / 2.0 - text_height / 2.0; | 663 | double text_y = height / 2.0 - text_height / 2.0; |
621 | cairo_set_source_u32(cairo, box_colors.text); | 664 | cairo_set_source_u32(cairo, box_colors.text); |
622 | cairo_move_to(cairo, *x + width / 2 - text_width / 2, (int)floor(text_y)); | 665 | cairo_move_to(cairo, *x + width / 2 - text_width / 2, (int)floor(text_y)); |
666 | choose_text_aa_mode(ctx, box_colors.text); | ||
623 | pango_printf(cairo, config->font, output->scale, config->pango_markup, | 667 | pango_printf(cairo, config->font, output->scale, config->pango_markup, |
624 | "%s", ws->label); | 668 | "%s", ws->label); |
625 | 669 | ||
@@ -637,15 +681,19 @@ static uint32_t render_workspace_button(cairo_t *cairo, | |||
637 | return output->height; | 681 | return output->height; |
638 | } | 682 | } |
639 | 683 | ||
640 | static uint32_t render_to_cairo(cairo_t *cairo, struct swaybar_output *output) { | 684 | static uint32_t render_to_cairo(struct render_context *ctx) { |
685 | cairo_t *cairo = ctx->cairo; | ||
686 | struct swaybar_output *output = ctx->output; | ||
641 | struct swaybar *bar = output->bar; | 687 | struct swaybar *bar = output->bar; |
642 | struct swaybar_config *config = bar->config; | 688 | struct swaybar_config *config = bar->config; |
643 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); | 689 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); |
644 | if (output->focused) { | 690 | if (output->focused) { |
645 | cairo_set_source_u32(cairo, config->colors.focused_background); | 691 | ctx->background_color = config->colors.focused_background; |
646 | } else { | 692 | } else { |
647 | cairo_set_source_u32(cairo, config->colors.background); | 693 | ctx->background_color = config->colors.background; |
648 | } | 694 | } |
695 | |||
696 | cairo_set_source_u32(cairo, ctx->background_color); | ||
649 | cairo_paint(cairo); | 697 | cairo_paint(cairo); |
650 | 698 | ||
651 | int th; | 699 | int th; |
@@ -666,19 +714,19 @@ static uint32_t render_to_cairo(cairo_t *cairo, struct swaybar_output *output) { | |||
666 | } | 714 | } |
667 | #endif | 715 | #endif |
668 | if (bar->status) { | 716 | if (bar->status) { |
669 | uint32_t h = render_status_line(cairo, output, &x); | 717 | uint32_t h = render_status_line(ctx, &x); |
670 | max_height = h > max_height ? h : max_height; | 718 | max_height = h > max_height ? h : max_height; |
671 | } | 719 | } |
672 | x = 0; | 720 | x = 0; |
673 | if (config->workspace_buttons) { | 721 | if (config->workspace_buttons) { |
674 | struct swaybar_workspace *ws; | 722 | struct swaybar_workspace *ws; |
675 | wl_list_for_each(ws, &output->workspaces, link) { | 723 | wl_list_for_each(ws, &output->workspaces, link) { |
676 | uint32_t h = render_workspace_button(cairo, output, ws, &x); | 724 | uint32_t h = render_workspace_button(ctx, ws, &x); |
677 | max_height = h > max_height ? h : max_height; | 725 | max_height = h > max_height ? h : max_height; |
678 | } | 726 | } |
679 | } | 727 | } |
680 | if (config->binding_mode_indicator) { | 728 | if (config->binding_mode_indicator) { |
681 | uint32_t h = render_binding_mode_indicator(cairo, output, x); | 729 | uint32_t h = render_binding_mode_indicator(ctx, x); |
682 | max_height = h > max_height ? h : max_height; | 730 | max_height = h > max_height ? h : max_height; |
683 | } | 731 | } |
684 | 732 | ||
@@ -708,26 +756,35 @@ void render_frame(struct swaybar_output *output) { | |||
708 | 756 | ||
709 | free_hotspots(&output->hotspots); | 757 | free_hotspots(&output->hotspots); |
710 | 758 | ||
759 | struct render_context ctx = { 0 }; | ||
760 | ctx.output = output; | ||
761 | |||
711 | cairo_surface_t *recorder = cairo_recording_surface_create( | 762 | cairo_surface_t *recorder = cairo_recording_surface_create( |
712 | CAIRO_CONTENT_COLOR_ALPHA, NULL); | 763 | CAIRO_CONTENT_COLOR_ALPHA, NULL); |
713 | cairo_t *cairo = cairo_create(recorder); | 764 | cairo_t *cairo = cairo_create(recorder); |
714 | cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); | 765 | cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); |
766 | ctx.cairo = cairo; | ||
767 | |||
715 | cairo_font_options_t *fo = cairo_font_options_create(); | 768 | cairo_font_options_t *fo = cairo_font_options_create(); |
716 | cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL); | 769 | cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL); |
770 | cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_GRAY); | ||
771 | ctx.textaa_safe = fo; | ||
717 | if (output->subpixel == WL_OUTPUT_SUBPIXEL_NONE) { | 772 | if (output->subpixel == WL_OUTPUT_SUBPIXEL_NONE) { |
718 | cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_GRAY); | 773 | ctx.textaa_sharp = ctx.textaa_safe; |
719 | } else { | 774 | } else { |
775 | fo = cairo_font_options_create(); | ||
776 | cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL); | ||
720 | cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_SUBPIXEL); | 777 | cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_SUBPIXEL); |
721 | cairo_font_options_set_subpixel_order(fo, | 778 | cairo_font_options_set_subpixel_order(fo, |
722 | to_cairo_subpixel_order(output->subpixel)); | 779 | to_cairo_subpixel_order(output->subpixel)); |
780 | ctx.textaa_sharp = fo; | ||
723 | } | 781 | } |
724 | cairo_set_font_options(cairo, fo); | 782 | |
725 | cairo_font_options_destroy(fo); | ||
726 | cairo_save(cairo); | 783 | cairo_save(cairo); |
727 | cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR); | 784 | cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR); |
728 | cairo_paint(cairo); | 785 | cairo_paint(cairo); |
729 | cairo_restore(cairo); | 786 | cairo_restore(cairo); |
730 | uint32_t height = render_to_cairo(cairo, output); | 787 | uint32_t height = render_to_cairo(&ctx); |
731 | int config_height = output->bar->config->height; | 788 | int config_height = output->bar->config->height; |
732 | if (config_height > 0) { | 789 | if (config_height > 0) { |
733 | height = config_height; | 790 | height = config_height; |
@@ -779,6 +836,11 @@ void render_frame(struct swaybar_output *output) { | |||
779 | 836 | ||
780 | wl_surface_commit(output->surface); | 837 | wl_surface_commit(output->surface); |
781 | } | 838 | } |
839 | |||
840 | if (ctx.textaa_sharp != ctx.textaa_safe) { | ||
841 | cairo_font_options_destroy(ctx.textaa_sharp); | ||
842 | } | ||
843 | cairo_font_options_destroy(ctx.textaa_safe); | ||
782 | cairo_surface_destroy(recorder); | 844 | cairo_surface_destroy(recorder); |
783 | cairo_destroy(cairo); | 845 | cairo_destroy(cairo); |
784 | } | 846 | } |